Skip to Content
Symmio Trading-SDK — the SDK surface for builders on HyperEVM
Session KeycreateSessionKeyManager

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

storageSessionKeyStoragerequired

Consumer-owned persistence adapter. The manager loads, saves, and removes records through it — see Security & storage.

defaultTtlMsnumberdefault SESSION_KEY_EXPIRY_MS

Lifetime applied to newly generated / imported keys, in ms. Defaults to one year.

now() => numberdefault Date.now

Injectable 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()SessionKeyState

Current runtime snapshot — see below.

isReady()boolean

Quick boolean for “a valid session key is loaded”.

getAddress()Address | null

Loaded session-key public address, or null.

getPrivateKey()Hex | null

Loaded 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)() => void

Subscribe to state changes. Returns an unsubscribe function.

getSnapshot()Address | null

Framework-integration snapshot — the loaded address, or null.

SessionKeyState

The shape getState() returns:

SessionKeyState
isReadyboolean

A valid key is currently in memory.

isExpiredboolean

The last loaded record was expired.

publicAddressAddress | null

Loaded session-key address, when initialized.

expiresAtnumber | null

Expiry 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.

Last updated on