Skip to main content

Accounts and sessions

Wallets and accounts

A Solana wallet owns one or more Nord accounts. Accounts hold balances, positions, and orders, and are addressed by a numeric accountId. A wallet's accounts are resolved from its public key:

  • REST: GET /user/{pubkey} returns the account IDs for a wallet.
  • SDK: await user.updateAccountId() populates user.accountIds.

Account-scoped state is then read with GET /account/{account_id} and the related endpoints, or with await user.fetchInfo(). Accounts owned by the same wallet are subaccounts — separate margin and positions under one wallet. Every action that can target an account takes an optional accountId, and the SDK defaults to the first account of the wallet.

Sessions

Signing every order with a wallet key would be slow and would keep the wallet key hot. Instead, a wallet authorizes a session key: an ephemeral keypair allowed to submit actions on its behalf until the session expires.

The flow:

  1. The wallet signs a session-creation request naming the session public key and an expiry.
  2. The session key signs subsequent actions — orders, cancels, withdrawals, transfers.
  3. Before expiry, the session is refreshed; otherwise it lapses and actions are rejected.

With the SDK:

const user = NordUser.fromPrivateKey(nord, process.env.PRIVATE_KEY!);
await user.updateAccountId();

await user.refreshSession(); // create or replace the session
await user.selfRefreshSession(); // extend the current session
await user.selfRevoke(); // end the current session
await user.revokeSession(sessionId); // revoke a session by id, from the wallet

refreshSession(expiryTimestamp?, refreshDeadline?) accepts an explicit expiry; without arguments it uses the SDK's default session lifetime. Order-entry calls throw if there is no valid session, so treat "refresh before expiry" as part of your run loop rather than something to retry after a failure.

NordUser.fromPrivateKey generates the session keypair for you. Browser integrations construct NordUser with signing callbacks from a wallet adapter, so the wallet only ever signs session creation, not each order.

Two signature framings are supported for session creation: hex message signing and Solana transaction framing, for wallets that will only sign transactions.

Nonces and action IDs

Actions are ordered per account and carry a nonce, and each accepted action returns an actionId. The SDK tracks nonces internally; direct integrations read them from the API:

PurposeEndpoint
Current exchange timestampGET /timestamp
Last acknowledged nonceGET /event/last-acked-nonce
Last executed action IDGET /action/last-executed-id

See Signed actions for how these are assembled into a submittable action.

Operational guidance

  • Keep the wallet key offline where possible; ship only the session key to the process that trades.
  • Give sessions the shortest lifetime that fits your refresh loop.
  • Revoke sessions when a process is retired — a revoked session cannot submit actions even if its key leaks.
  • Never commit keys or session material. Load them from your secret store.

These materials are provided for informational purposes only and do not constitute financial, investment, legal, or tax advice, or an offer or solicitation to buy or sell any asset. Trading digital assets and derivatives involves substantial risk, including the possible loss of some or all capital. Products may not be available in all jurisdictions. Users are responsible for evaluating suitability and complying with applicable laws.