createSessionKeyManager
The runtime that owns a session key: loads it, generates and rotates it, signs with it, and clears it. The private key lives in memory only — persistence, serialization, and encryption are delegated to the SessionKeyStorage adapter you pass in.
import { createSessionKeyManager, SESSION_KEY_EXPIRY_MS } from "@symmio/session-key";
const manager = createSessionKeyManager({
storage, // required — your persistence adapter
defaultTtlMs: SESSION_KEY_EXPIRY_MS, // default: one year
now: () => Date.now(), // default; override for tests
});
const state = await manager.initialize(owner);
const { signature } = await manager.sign("hello");Options
Consumer-owned persistence adapter. The manager loads, saves, and removes records through it — see Security & storage.
defaultTtlMsnumberdefault SESSION_KEY_EXPIRY_MSLifetime applied to newly generated / imported keys, in ms. Defaults to one year.
now() => numberdefault Date.nowInjectable clock. Override in tests to control expiry.
Methods
initialize(owner, options?)Promise<SessionKeyState>Load an existing non-expired key for owner, or generate and persist a new one. If the stored key is expired it is
removed and a fresh one is generated (auto-rotate); a load that throws is treated as “no key” and also rotated.
options.ttlMs overrides the default lifetime for a freshly generated key.
importPrivateKey(owner, key, options?)Promise<SessionKeyState>Persist an existing private key for owner and load it into memory, replacing any stored key. Used by
device-transfer flows.
rotate(owner, options?)Promise<SessionKeyState>Generate a new key, persist it (replacing any existing key for owner), and load it.
sign(message)Promise<SessionKeySignature>Sign a UTF-8 string as an EIP-191 personal message. Returns the signature, the signing address, and the client-side
durationMs. Throws if no key is loaded.
signTypedData(params)Promise<Hex>Sign EIP-712 typed data — the path the SDK’s trade actions use. Throws if no key is loaded.
destroy(owner?)Promise<void>Clear the in-memory key and reset state. When owner is passed, also remove its stored record.
getState()SessionKeyStateCurrent runtime snapshot — see below.
isReady()booleanQuick boolean for “a valid session key is loaded”.
getAddress()Address | nullLoaded session-key public address, or null.
getPrivateKey()Hex | nullLoaded raw private key — for explicit device-transfer / export only. Treat like a wallet mnemonic.
getMetadata(owner)Promise<SessionKeyMetadata | null>Stored public metadata via the adapter, without loading the key into memory.
subscribe(listener)() => voidSubscribe to state changes. Returns an unsubscribe function.
getSnapshot()Address | nullFramework-integration snapshot — the loaded address, or null.
SessionKeyState
The shape getState() returns:
SessionKeyStateisReadybooleanA valid key is currently in memory.
isExpiredbooleanThe last loaded record was expired.
publicAddressAddress | nullLoaded session-key address, when initialized.
expiresAtnumber | nullExpiry timestamp in ms since epoch, when initialized.
Reacting to state changes
subscribe plus getSnapshot is the integration surface for framework state (e.g. React’s useSyncExternalStore):
const unsubscribe = manager.subscribe(() => {
const { isReady, publicAddress, expiresAt } = manager.getState();
// re-render the "session active until …" indicator
});
// later
unsubscribe();Signing typed data
The SDK’s trade actions sign EIP-712 typed data. signTypedData takes the standard viem shape:
const signature = await manager.signTypedData({
domain,
types,
primaryType: "Quote",
message,
});See Provider integration for how this is reached automatically when an SDK write sets from to the session-key address.
Related
- Key material helpers — generate a raw keypair without a manager.
- Security & storage — the
SessionKeyStorageadapter the manager depends on. - Types & constants —
SessionKeyManager,CreateSessionKeyManagerOptions,SessionKeySignature,SessionKeyTypedDataParameters.