Skip to main content
Smart sessions let an application backend submit transactions from a user’s wallet without asking the owner to approve every transaction. The wallet owner approves an explicit set of EVM transfer grants and an expiry first. The wallet’s Sessions Module enforces those limits on-chain. The backend API is available through the TypeScript SDK’s RemoteAccessClient. The owner can approve or revoke the session with any OMS Wallet SDK. In this guide, client app means any web or mobile frontend that integrates an OMS Wallet SDK to add wallet functionality.
Smart sessions currently support EVM wallets. Keep the remote access credential (RAC) private key on the backend. Any operator or application client should call your authenticated backend API and must never receive or use that key.

Divide responsibilities

If your application uses approval links, request statuses, operator authentication, or local transaction history, those are application features. They are not OMS Wallet SDK APIs.

Understand the lifecycle

1

Register the backend credential

The backend creates or loads a persistent signer and registers it with WaaS. Registration returns a credentialId.
2

Ask the owner to approve

Your application sends the owner the credentialId and the requested network, grants, and expiry through its own approval flow.
3

Authorize in the client app

The owner inspects the credential metadata and calls authorizeRemoteAccess. The SDK returns the authoritative walletId and sessionId.
4

Associate the session with the backend

Associate the returned walletId and sessionId through your application workflow. The client can send them through an authenticated endpoint, or the backend can reconcile its current sessions with listSessions. In either case, verify the authoritative session with getSession and store an application association only if your workflow needs one.
5

Reconcile and operate

The backend reads the session from WaaS, checks its current grants and usage, and prepares and executes transactions within those limits.

Create a persistent backend signer

Load the RAC private key from backend-only secret storage and construct one RemoteAccessClient. This Node-style example reads environment variables; use your platform’s secret bindings in a Worker or other serverless runtime.
The signer supplies a strictly increasing nonce for every signed WaaS request. The built-in signer uses a time-based in-memory nonce and is suitable when one long-running process issues requests sequentially. A distributed or restart-sensitive deployment should implement the public CredentialSigner interface with a shared atomic nonce store. Requests for one RAC must still reach WaaS in increasing nonce order, so serialize their dispatch even when allocation is atomic.

Register the credential

Register the signer and persist the returned ID:
When first registering a newly generated signer, store its managed-key reference, credentialId, registration time, and requested lifetime. registerCredential returns only the credential ID. Registering the same active signer again is idempotent and does not extend its original lifetime, so do not treat a later call as a renewal. A session cannot expire after its RAC; persist the effective approved.expiresAt returned to the client app. The metadata is public consent-screen information returned to the client app by inspectRemoteCredential. Do not put secrets in it.

Collect owner approval

Your application decides how to transport the approval request to the client app. In the client app, inspect the credential before asking the owner to authorize it:
The public SDK supports nativeTransfer and erc20Transfer grants. To replace the grants or expiry of a specific existing session without changing its signer, call authorizeRemoteAccess again and pass that session’s sessionId. The example uses Polygon Amoy. Grant limits and transaction values are raw base-unit amounts. See the owner-side sessions guide for TypeScript, React Native, Swift, or Kotlin.

Persist application state separately

Treat any session identifiers received from a client as untrusted application input. Before accepting an association, call getSession with the RAC and verify that the returned session ID, chain, grants, and effective expiry are consistent with the intended authorization. Keep application workflow state separate from authoritative session state: If the client app also sends a wallet address, use it only for display or Indexer queries. Use the walletId returned by getSession when preparing a remote transaction.

Reconcile application state

listSessions follows all WaaS pages and returns the sessions currently available to this RAC. Read usage for the session’s network when showing remaining allowances:
Keep these RAC-signed reads sequential for a given credential. Your database can retain expired or revoked associations as application history, but do not present them as usable merely because a local record still exists.

Prepare and execute a transaction

Resolve the session immediately before preparing the transaction. This gives the backend its authoritative wallet ID and current grants:
Smart-session transactions must be sponsored by the relayer. WaaS rejects preparation when the transaction is not sponsored, so remote execution does not select or submit a fee option. Validate the requested operation against the current grants and usage before your backend accepts it for execution. This provides clear errors and defense in depth, but the on-chain Sessions Module remains the final authority. Persist txnId before execution so an uncertain response can be reconciled with getTransactionStatus instead of blindly preparing or executing another transaction.

Revoke or rotate access

The wallet owner revokes one specific session:
The backend can retire the RAC and every session authorized for it:
Credential rotation requires a new private key, a new RemoteAccessClient, and a new registration. Sessions authorized for the retired credential are not transferable to the replacement credential; owners must approve new sessions.

Production checklist

  • Encrypt the RAC private key at rest or keep it in a managed secret or signing service. Never expose it outside the secure backend.
  • Authenticate and authorize every caller of backend session-management endpoints. Add rate limits and abuse controls to any public approval endpoints.
  • If you use approval links, treat their tokens as bearer credentials. Store only hashes, or encrypt them and strictly limit access.
  • Use a shared atomic nonce allocator and serialize WaaS requests when more than one process can use the same RAC.
  • Schedule requested session expiries before the planned RAC rotation, persist each effective approval expiry, and rotate credentials before they expire.
  • Re-read the authoritative session and usage before presenting or executing an action.
  • Persist each prepared txnId before execution and reconcile its status before retrying.
  • Use the session’s authoritative walletId for remote transactions. A wallet address alone is not sufficient.

Smart session example

See a complete Worker, database, owner approval app, and admin dashboard that implement this lifecycle.