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

# Server Wallet SDK quickstart

> Install the Server Wallet SDK, restore the wallet for your application identity, and send a sponsored transfer.

This quickstart restores the wallet for your application identity and sends one sponsored transfer on Polygon.

It assumes your OIDC issuer is already registered with your OMS project. See [identity and credentials](/wallets/sdk/server/identity-and-credentials) for that setup.

## Install the SDK

```bash theme={null}
npm install @polygonlabs/oms-server-wallet-sdk@0.2.0
```

The package is ESM only and requires Web Crypto and Fetch. Use Node.js 24 or newer, or Cloudflare Workers with `nodejs_compat`.

## Configure the transport

Your publishable key is restricted to one origin, so server requests must send that origin explicitly. Requests without it are rejected by the gateway.

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

const applicationOrigin = 'https://wallet-api.example.com'

const omsFetch: typeof fetch = (input, init) => {
  const headers = new Headers(
    init?.headers ?? (input instanceof Request ? input.headers : undefined),
  )
  headers.set('Origin', new URL(applicationOrigin).origin)
  return fetch(input, { ...init, headers })
}

const transport = new WaasTransport('YOUR_PUBLISHABLE_KEY', ['YOUR_APPROVED_PCR0'], omsFetch)
```

`WaasTransport` verifies the enclave attestation on every response. The approved PCR0 measurements come from your OMS operator, and each one is 96 hexadecimal characters.

## Create the wallet client

```typescript theme={null}
import {
  ServerWallet,
  EncryptedStore,
  SerialExecutor,
  environmentFromKey,
  type StateStore,
} from '@polygonlabs/oms-server-wallet-sdk'

// Your durable storage, and the ES256 ID token issuer you host.
declare const persistence: StateStore
declare function issueIdToken(): Promise<{ token: string; expiresAt: number }>

const issuer = 'https://wallet-api.example.com'
const audience = 'YOUR_REGISTERED_AUDIENCE'
const subject = 'treasury-primary'

const environment = environmentFromKey('YOUR_PUBLISHABLE_KEY')
const namespace = JSON.stringify([
  environment.origin,
  environment.projectId,
  issuer,
  audience,
  subject,
])

const wallet = new ServerWallet({
  subject,
  issuer,
  audience,
  tokenProvider: issueIdToken,
  transport,
  store: new EncryptedStore(persistence, 'YOUR_ENCRYPTION_KEY', namespace),
  executor: new SerialExecutor(),
})
```

`SerialExecutor` is correct for a single Node process. A clustered backend needs a coordinator that holds exclusive ownership across processes, covered in [storage and concurrency](/wallets/sdk/server/storage-and-concurrency).

## Restore the wallet

```typescript theme={null}
const snapshot = await wallet.createOrRestore()

console.log('Wallet address:', snapshot.wallet?.address)
console.log('Credential expires:', snapshot.expiresAt)
```

`createOrRestore` authenticates when needed and returns the single wallet for your identity. Calling it again returns the same wallet rather than creating another.

## Send a sponsored transfer

Server Wallets run on mainnet networks only, so this example sends to the wallet's own address. The transfer moves no value and its gas is sponsored.

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

const operationId = crypto.randomUUID()

const prepared = await wallet.prepareTransfer(operationId, {
  chainId: 137,
  to: snapshot.wallet!.address,
  asset: 'native',
  amount: parseAmount('0.001', 18),
})

if (prepared.status === 'quoted') {
  await wallet.executeTransfer(operationId)
}

const operation = await wallet.getOperation(operationId)
console.log('Status:', operation?.status)
```

Persist `operationId` before you prepare, and reuse it on every retry for that transfer. It is the SDK's idempotency key: reusing it never prepares a second transfer.

Continue with [transfers](/wallets/sdk/server/transfers) for the full operation lifecycle and the status values you must handle. See [storage and concurrency](/wallets/sdk/server/storage-and-concurrency) before you deploy.
