> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript sessions and access

> Restore wallet sessions, switch wallets, issue backend tokens, manage access, and sign out.

An active session binds the local credential to one selected wallet. Authentication can return several wallets, but `omsWallet.wallet` exposes one active `walletAddress` at a time.

## Read and restore session state

Create `OMSWallet` with the same publishable key and storage configuration on each application load. The constructor synchronously restores unexpired session metadata. Protected wallet operations also verify the corresponding signer credential.

```typescript theme={null}
import { OMSWallet } from '@polygonlabs/oms-wallet'

const omsWallet = new OMSWallet({
  publishableKey: 'YOUR_PUBLISHABLE_KEY',
})

const { walletAddress, expiresAt, auth } = omsWallet.wallet.session

if (walletAddress) {
  console.log('Restored wallet:', walletAddress)
  console.log('Credential expires:', expiresAt)
  console.log('Authentication:', auth)
}
```

`wallet.session` is a read-only snapshot:

* `walletAddress` and `expiresAt` are defined only for an active session.
* Email auth metadata is `{ type: 'email', email }`.
* OIDC metadata is `{ type: 'oidc', flow, issuer, provider, providerLabel, email }`. Optional provider fields can be `undefined`.

The stored record is scoped to the publishable-key project and API environment. Restoration also requires the same local signer credential ID and signing algorithm.

## Understand storage defaults

Browser defaults use separate storage for completed sessions and pending redirects:

* Completed session metadata uses `localStorage`.
* The default non-extractable WebCrypto P-256 signer stores its credential in IndexedDB.
* Temporary OIDC verifier and state data use `sessionStorage`.

Outside a browser, completed session metadata defaults to in-memory storage, so it does not survive a process restart. Redirect storage has no non-browser default. Pass `redirectAuthStorage` before calling any redirect auth method, and make sure it remains available to the callback process.

For a non-browser runtime, provide application-owned implementations of the public `StorageManager` and `CredentialSigner` interfaces through the `storage`, `redirectAuthStorage`, and `credentialSigner` constructor options. See the [package API reference](/wallets/sdk/typescript/api-reference) for their exact contracts.

For the redirect convenience wrapper outside a browser, pass `currentUrl` and `assignUrl`. On completion, pass `callbackUrl`; either keep `cleanUrl: false` or provide `replaceUrl` when URL cleanup is required. An in-memory redirect store is suitable only when both stages run in the same process. See [authentication](/wallets/sdk/typescript/authentication#control-browser-routing-directly) for the lower-level browser flow.

## Respond to expiry

The SDK makes an expired session inactive before protected operations. Subscribe while your application needs to update its routing or UI.

```typescript theme={null}
const unsubscribe = omsWallet.wallet.onSessionExpired(({ session, expiredAt }) => {
  console.log('Expired wallet:', session.walletAddress)
  console.log('Expired at:', expiredAt)
})

// Call during application or component cleanup.
unsubscribe()
```

An expiry event includes the expired session snapshot even though `wallet.walletAddress` is now `undefined`. A newly constructed client can replay a stored expiry event to a listener. Starting authentication, completing a new session, or signing out clears that replay state.

## List and activate wallets

List every wallet available to the authenticated credential:

```typescript theme={null}
const wallets = await omsWallet.wallet.listWallets()

for (const wallet of wallets) {
  console.log(wallet.id, wallet.type, wallet.address, wallet.reference)
}
```

`listWallets` works with an active session and while manual auth selection is pending. After normal automatic auth, switch the active wallet with its server-side ID:

```typescript theme={null}
const wallet = wallets[0]

if (wallet) {
  const active = await omsWallet.wallet.useWallet({ walletId: wallet.id })
  console.log('Now active:', active.walletAddress)
}
```

`useWallet` requires an active session and preserves its credential expiry and auth metadata. If auth returned `PendingWalletSelection`, call `selection.selectWallet` instead.

## Create and activate another wallet

```typescript theme={null}
const active = await omsWallet.wallet.createWallet({
  reference: 'treasury',
})

console.log(active.wallet.id, active.walletAddress)
```

`createWallet` creates an Ethereum wallet by default and immediately makes it active. A pending manual selection must use `selection.createAndSelectWallet` instead.

## Issue an ID token for your backend

`getIdToken` asks OMS Wallet to issue an ID token that proves the active wallet session to your backend.

```typescript theme={null}
const idToken = await omsWallet.wallet.getIdToken({
  ttlSeconds: 300,
  customClaims: { purpose: 'checkout' },
})
```

This token is OMS Wallet output. It is distinct from the provider-issued ID token passed into `signInWithOidcIdToken` during authentication. Treat client-supplied custom claims as untrusted context unless your backend independently controls or validates them. See [backend wallet verification](/wallets/sdk/guides/backend-wallet-verification).

## Review and revoke access

`listAccess` follows all service pages and returns credentials with access to the active wallet. Use `listAccessPages` when you want page-at-a-time rendering.

```typescript theme={null}
const grants = await omsWallet.wallet.listAccess()

for (const grant of grants) {
  console.log(grant.credentialId, grant.expiresAt, grant.isCaller)
}

for await (const page of omsWallet.wallet.listAccessPages({ pageSize: 25 })) {
  console.log(page.grants)
}
```

Revoke only a credential that is not the caller for the current session:

```typescript theme={null}
const revocableGrant = grants.find((grant) => !grant.isCaller)

if (revocableGrant) {
  await omsWallet.wallet.revokeAccess({
    targetCredentialId: revocableGrant.credentialId,
  })
}
```

<Warning>
  Do not offer `revokeAccess` for a grant whose `isCaller` field is `true`. It represents the credential making the current request. Revocation is permanent for the target grant.
</Warning>

## Sign out locally

```typescript theme={null}
await omsWallet.wallet.signOut()
```

`signOut` clears the local session record, pending auth state, active wallet, and local credential signer where supported. It does not call the OMS service and does not revoke server-side access grants. Use `revokeAccess` separately for other grants before signing out when your account-management flow requires revocation.
