<!--
Sitemap:
- [Tempo Accounts SDK - Getting Started](/docs/): Set up the Tempo Accounts SDK to create, manage, and interact with accounts on Tempo.
- [Deploying to Production](/docs/production): Things to consider before deploying your application with the Tempo Accounts SDK to production.
- [FAQ](/docs/faq): Frequently asked questions about the Tempo Accounts SDK.
- [Connect Accounts](/docs/guides/connect-accounts): Connect a Tempo account in your application.
- [Authentication](/docs/guides/authentication): Authenticate connected accounts against your own server with a signed SIWE challenge.
- [Identity](/docs/guides/identity): Request and verify identity claims about a connected account, starting with a verified email.
- [Transfers](/docs/guides/transfers): Send stablecoin transfers from a connected Tempo account, initiated either by the user or by your server.
- [Spend Permissions](/docs/guides/spend-permissions): Authorize spend limits, call scopes, and expiries so repeat transfers can be signed without a confirmation prompt.
- [React Native](/docs/guides/react-native): Set up Tempo Accounts in a React Native app.
- [Subscriptions](/docs/guides/subscriptions): Charge recurring payments from a connected Tempo account.
- [Fee Sponsorship](/docs/guides/fee-sponsorship): Sponsor transaction fees from a server-controlled policy.
- [Deposits](/docs/guides/deposits): Open the Tempo deposit flow from a connected account and let the user choose deposit details.
- [Swaps](/docs/guides/swaps): Open the Tempo swap flow from a connected account with optional pre-filled intent fields.
- [Theming](/docs/guides/theming): Match embedded account surfaces to your product.
- [CLI](/docs/guides/cli): Authorize and use Tempo accounts from command-line tools.
- [Adapters](/docs/adapters/): Choose the signing adapter for your Tempo Accounts SDK integration.
- [Tempo Wallet Adapter](/docs/adapters/tempo-wallet): Use Tempo Wallet as the hosted universal wallet adapter.
- [WebAuthn Adapter](/docs/adapters/webauthn): Use domain-bound passkeys as the account signing adapter.
- [Turnkey Adapter](/docs/adapters/turnkey): Use Turnkey-managed wallet accounts as the account signing adapter.
- [Privy Adapter](/docs/adapters/privy): Use Privy embedded wallets as the account signing adapter.
- [Private Key Adapter](/docs/adapters/private-key): Sign in-process with a `secp256k1` private key.
- [Custom Adapter](/docs/adapters/custom): Author your own adapter with the `Adapter.define` API.
- [Adapters](/docs/api/adapters): Pluggable adapters for the Tempo Accounts SDK Provider.
- [dialog](/docs/api/dialog): Adapter for the Tempo Wallet dialog, an embedded iframe or popup for account management.
- [local](/docs/api/local): Key-agnostic adapter for defining arbitrary account types and signing mechanisms.
- [mobileWebAuth](/docs/api/mobileWebAuth): Mobile web auth adapter for browser-session wallet requests.
- [postMessage](/docs/api/postMessage): Connect to wallet from anywhere on the web
- [privy](/docs/api/privy): React adapter backed by Privy sessions and embedded Ethereum wallets.
- [secp256k1](/docs/api/secp256k1): Adapter that signs in-process with a `secp256k1` private key.
- [turnkey](/docs/api/turnkey): Adapter backed by Turnkey client sessions.
- [webAuthn](/docs/api/webAuthn): Adapter for passkey-based accounts using WebAuthn registration and authentication.
- [Dialog](/docs/api/dialogs): Dialog modes for embedding the Tempo Wallet.
- [Dialog.iframe](/docs/api/dialog.iframe): Embed the Tempo Wallet auth UI in an iframe dialog element.
- [Dialog.popup](/docs/api/dialog.popup): Open the Tempo Wallet auth UI in a popup window.
- [Expiry](/docs/api/expiry): Utility functions for computing access key expiry timestamps.
- [Provider](/docs/api/provider): Create an EIP-1193 provider for managing accounts on Tempo.
- [Rpc](/docs/api/rpc): Per-method Zod schemas and shared building blocks for the Accounts JSON-RPC surface.
- [Schema](/docs/api/schema): Zod-based JSON-RPC schema definitions for the Accounts provider.
- [TrustedHosts](/docs/api/trustedHosts): Trusted host mappings and matching helpers for dialog adapters.
- [WebAuthnCeremony](/docs/api/webauthnceremony): Pluggable strategy for WebAuthn registration and authentication ceremonies.
- [WebAuthnCeremony.from](/docs/api/webauthnceremony.from): Create a WebAuthnCeremony from a custom implementation.
- [WebAuthnCeremony.server](/docs/api/webauthnceremony.server): Server-backed WebAuthn ceremony that delegates to a remote handler.
- [CLI](/docs/cli/provider): Create a Provider for CLI environments.
- [eth_accounts](/docs/rpc/eth_accounts): Get the addresses of the currently connected accounts.
- [eth_chainId](/docs/rpc/eth_chainId): Get the chain ID of the currently active chain.
- [eth_fillTransaction](/docs/rpc/eth_fillTransaction): Fills missing transaction fields and returns wallet-aware metadata.
- [eth_requestAccounts](/docs/rpc/eth_requestAccounts): Request access to user accounts, prompting the user to connect if needed.
- [eth_sendTransaction](/docs/rpc/eth_sendTransaction): Send a transaction from the connected account.
- [eth_sendTransactionSync](/docs/rpc/eth_sendTransactionSync): Send a transaction and wait for the receipt.
- [eth_signTransaction](/docs/rpc/eth_signTransaction): Sign a transaction without broadcasting it.
- [eth_signTypedData_v4](/docs/rpc/eth_signTypedData_v4): Sign EIP-712 typed structured data with the connected account.
- [personal_sign](/docs/rpc/personal_sign): Sign a message with the connected account.
- [wallet_authorizeAccessKey](/docs/rpc/wallet_authorizeAccessKey): Authorize an access key for delegated transaction signing.
- [wallet_connect](/docs/rpc/wallet_connect): Connect account(s) with optional capabilities like access key authorization.
- [wallet_deposit](/docs/rpc/wallet_deposit): Open the wallet deposit flow with optional pre-filled fields.
- [wallet_depositZone](/docs/rpc/wallet_depositZone): Open the wallet zone-deposit flow with optional pre-filled fields.
- [wallet_disconnect](/docs/rpc/wallet_disconnect): Disconnect the connected account(s).
- [wallet_getBalances](/docs/rpc/wallet_getBalances): Get token balances for an account.
- [wallet_getCallsStatus](/docs/rpc/wallet_getCallsStatus): Get the status of a batch of calls sent via wallet_sendCalls.
- [wallet_getCapabilities](/docs/rpc/wallet_getCapabilities): Get account capabilities for specified chains.
- [wallet_revokeAccessKey](/docs/rpc/wallet_revokeAccessKey): Revoke a previously authorized access key.
- [wallet_send](/docs/rpc/wallet_send): Open the wallet send-token flow with optional pre-filled fields.
- [wallet_sendCalls](/docs/rpc/wallet_sendCalls): Send a batch of calls from the connected account.
- [wallet_swap](/docs/rpc/wallet_swap): Open the wallet swap flow with optional pre-filled swap intent fields.
- [wallet_switchEthereumChain](/docs/rpc/wallet_switchEthereumChain): Switch the provider's active chain.
- [wallet_withdrawZone](/docs/rpc/wallet_withdrawZone): Open the wallet zone-withdraw flow with optional pre-filled fields.
- [Remote](/docs/api/remote): Bridge that runs inside the wallet's iframe/popup and serves RPC requests from the host SDK.
- [Remote.create](/docs/api/remote.create): Create a remote context bound to a Messenger and Provider.
- [Remote.useEnsureVisibility](/docs/api/remote.useEnsureVisibility): React hook that monitors iframe visibility and falls back to a popup when occluded.
- [Remote.useState](/docs/api/remote.useState): React hook to subscribe to a remote context's state store.
- [Remote.useTheme](/docs/api/remote.useTheme): React hook that applies theme overrides from URL search params and live messenger updates.
- [Remote.validateSearch](/docs/api/remote.validateSearch): Validate an RPC request payload from URL search params.
- [Tempo Accounts Server Handlers](/docs/server/): Configure server-side Tempo Accounts SDK handlers for relaying wallet RPC requests, composing backends, and managing WebAuthn ceremonies.
- [Handler.auth](/docs/server/handler.auth): Server handler that issues SIWE-based authentication challenges and sessions.
- [Handler.codeAuth](/docs/server/handler.codeAuth): Server handler for the device-code (PKCE) access-key bootstrap flow.
- [Handler.compose](/docs/server/handler.compose): Compose multiple server handlers into a single handler.
- [Handler.exchange](/docs/server/handler.exchange): Server handler that returns Stablecoin DEX quotes and ready-to-submit calls.
- [Handler.relay](/docs/server/handler.relay): Server handler that proxies certain RPC requests with wallet-aware enrichment.
- [Handler.webAuthn](/docs/server/handler.webAuthn): Server-side WebAuthn ceremony handler for registration and authentication.
- [hc](/docs/server/hc): Typed RPC client for handlers built with the Tempo Accounts SDK.
- [Identity.verify](/docs/server/identity.verify): Verify a wallet-issued identity token (verified email) against an issuer's JWKS.
- [Kv](/docs/server/kv): Key-value store adapters for server-side persistence.
- [Kv.cloudflare](/docs/server/kv.cloudflare): Kv adapter backed by a Cloudflare Workers KV namespace.
- [Kv.durableObject](/docs/server/kv.durableObject): Kv adapter backed by a Cloudflare Durable Object with atomic take and create.
- [Kv.from](/docs/server/kv.from): Wrap a custom Kv-shaped object so the SDK accepts it as a Kv.
- [Kv.memory](/docs/server/kv.memory): In-memory Kv adapter for tests and single-process deployments.
- [Keystore](/docs/api/keystore): Pluggable backends for key material.
- [Keystore.p256](/docs/api/keystore.p256): Pure-JS P-256 keystore.
- [Keystore.secp256k1](/docs/api/keystore.secp256k1): Pure-JS secp256k1 keystore.
- [Keystore.webCryptoP256](/docs/api/keystore.webCryptoP256): WebCrypto P-256 keystore.
- [Storage](/docs/api/storage): Pluggable storage adapters for persisting provider state.
- [Storage.combine](/docs/api/storage.combine): Combine multiple Storage adapters into one.
- [Storage.cookie](/docs/api/storage.cookie): Cookie-backed Storage adapter.
- [Storage.from](/docs/api/storage.from): Create a Storage adapter from a custom implementation.
- [Storage.idb](/docs/api/storage.idb): IndexedDB-backed Storage adapter.
- [Storage.localStorage](/docs/api/storage.localStorage): localStorage-backed Storage adapter.
- [Storage.memory](/docs/api/storage.memory): In-memory Storage adapter.
- [asyncStorage](/docs/api/storage.asyncStorage): React Native Storage adapter backed by AsyncStorage.
- [secureMmkv](/docs/api/storage.secureMmkv): Encrypted React Native Storage adapter backed by MMKV.
- [Tempo Accounts SDK](/index): The fastest way to add stablecoins to your application.
- [Secp256k1 Adapter](/docs/adapters/secp256k1): Sign in-process with a `secp256k1` private key.
- [Bring Your Auth](/docs/enterprise/bring-your-auth/): Connect enterprise auth and signing systems to Tempo accounts.
- [Hosted Universal Wallets](/docs/enterprise/hosted-universal-wallets): Stub for hosting a universal wallet on your own domain.
- [Handler.feePayer (Deprecated)](/docs/server/handler.feePayer): Deprecated — use Handler.relay with feePayer option instead.
- [tempoWallet](/docs/wagmi/tempoWallet): Wagmi connector for the Tempo Wallet dialog.
- [webAuthn](/docs/wagmi/webAuthn): Wagmi connector for passkey-based WebAuthn accounts.
- [AWS KMS](/docs/enterprise/bring-your-auth/aws-kms): Stub for integrating AWS KMS-backed signing with the Tempo Accounts SDK.
- [Custom Auth](/docs/enterprise/bring-your-auth/custom): Stub for first-party enterprise auth and signing integrations.
- [Privy](/docs/enterprise/bring-your-auth/privy): Enterprise notes for integrating Privy-backed auth with the Tempo Accounts SDK.
- [Turnkey](/docs/enterprise/bring-your-auth/turnkey): Stub for integrating Turnkey-backed signing with the Tempo Accounts SDK.
-->

# `Provider`

Creates an EIP-1193 provider with a pluggable adapter for managing accounts on Tempo.

The returned object implements [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) (`request`, `on`, `removeListener`, `emit`, ...) and exposes a few convenience helpers (`getAccount`, `getAccessKeyStatus`, `getClient`, `store`, `chains`). See [Return Type](#return-type) for the full surface.

## Usage

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create()
```

### Using JSON-RPC Methods

You can interact with accounts via the provider's `request` method.

```ts twoslash
// @noErrors
import { Provider } from 'accounts'

const provider = Provider.create()

const { accounts } = await provider.request({ // [!code focus]
  method: 'wallet_connect', // [!code focus]
}) // [!code focus]
```

### Using Viem Actions

If you prefer to use Viem actions over raw JSON-RPC calls, the provider exposes a `getClient` accessor.

```ts twoslash
// @noErrors
import { parseUnits } from 'viem'
import { tempoActions } from 'viem/tempo'
import { Provider } from 'accounts'

const provider = Provider.create()

const client = provider.getClient().extend(tempoActions()) // [!code focus]

const { receipt } = await client.token.transferSync({ // [!code focus]
  amount: parseUnits('100', 6), // [!code focus]
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb', // [!code focus]
  token: '0x20c0000000000000000000000000000000000001', // [!code focus]
}) // [!code focus]
```

### Access Key Status

Use `getAccessKeyStatus` to check whether the active account has a matching delegated key before starting a paid or delegated flow.

```ts twoslash
// @noErrors
import { Provider } from 'accounts'

const provider = Provider.create()

const status = await provider.getAccessKeyStatus({ // [!code focus]
  calls: [{ // [!code focus]
    to: '0x20c0000000000000000000000000000000000001', // [!code focus]
    data: '0xa9059cbb', // [!code focus]
  }], // [!code focus]
}) // [!code focus]

if (status === 'pending') {
  // The next matching transaction will publish the key authorization.
}
```

## Parameters

### accessKey

* **Type:** `{ authorize?: Provider.create.AuthorizeAccessKey; keystores?: Keystore.Keystores }`
* **Optional**

Access-key configuration: `authorize` automatically authorizes an access key when no stored key satisfies a request; `keystores` is where key material lives.

#### accessKey.authorize

* **Type:** `Provider.create.AuthorizeAccessKeyParameters | (() => Provider.create.AuthorizeAccessKeyParameters | undefined)`
* **Optional**

Access-key parameters to authorize automatically when no stored key satisfies a request.

Applies to `wallet_connect` and transaction sends: the provider first checks stored access keys and reuses one that satisfies the request; if none does, `wallet_connect` includes `capabilities.authorizeAccessKey`, and sends authorize the key immediately beforehand when the requested scopes cover the transaction calls. Pass an object to use the same parameters for every request, or a function to compute them per request — return `undefined` to skip authorization for that request.

The optional `reuse` object is SDK-only. It is never sent to the wallet RPC. Use it to make reuse stricter than the default scope check.

Tempo Wallet-hosted approval pages require at least one `limits` entry and one `scopes` entry. Local adapters accept unbounded keys, but production apps should pass both so local and wallet-hosted flows use the same policy.

```ts
declare function authorize(): {
  /** Access key address. Alternative to `publicKey` when the caller already knows the derived address. */
  address?: Address | undefined
  /** Chain ID the key authorization is scoped to. Defaults to the active chain. */
  chainId?: bigint | undefined
  /** Unix timestamp (seconds) when the key expires. */
  expiry: number
  /** Key type of the external public key. Required when `publicKey` or `address` is provided. */
  keyType?: 'secp256k1' | 'p256' | 'webAuthn' | undefined
  /** TIP-20 spending limits. Optional `period` (seconds) makes the limit roll over each period. */
  limits?: { limit: bigint; period?: number; token: Address }[] | undefined
  /** Private key material to keep in SDK storage. It is not forwarded to wallets over JSON-RPC. */
  privateKey?: Hex | undefined
  /**
   * External public key to authorize. When provided, no key pair is generated —
   * the caller holds the signing material.
   */
  publicKey?: Hex | undefined
  /** Call scopes restricting which contracts/selectors this key can call. */
  scopes?:
    | { address: Address; recipients?: readonly Address[]; selector?: Hex | string }[]
    | undefined
  /** SDK-only reuse policy. Omitted before `wallet_connect` or `wallet_authorizeAccessKey` RPCs. */
  reuse?: {
    /** Minimum Unix timestamp (seconds) a stored key must be valid through. */
    minExpiry?: number | undefined
    /** Minimum spending limits a stored key must satisfy. */
    minLimits?: { limit: bigint; period?: number; token: Address }[] | undefined
  } | undefined
} | undefined
```

```ts twoslash
import { parseUnits } from 'viem'
import { Expiry, Provider } from 'accounts'

const provider = Provider.create({
  accessKey: { // [!code focus]
    authorize: { // [!code focus]
      expiry: Expiry.days(7), // [!code focus]
      limits: [{ // [!code focus]
        token: '0x20c0000000000000000000000000000000000001', // [!code focus]
        limit: parseUnits('500', 6), // [!code focus]
        period: 60 * 60 * 24, // rolling daily limit // [!code focus]
      }], // [!code focus]
      scopes: [{ // [!code focus]
        address: '0x20c0000000000000000000000000000000000001', // [!code focus]
        selector: 'transfer(address,uint256)', // [!code focus]
      }], // [!code focus]
      reuse: { // [!code focus]
        minExpiry: Expiry.hours(1), // [!code focus]
        minLimits: [{ // [!code focus]
          token: '0x20c0000000000000000000000000000000000001', // [!code focus]
          limit: parseUnits('50', 6), // [!code focus]
          period: 60 * 60 * 24, // [!code focus]
        }], // [!code focus]
      }, // [!code focus]
    }, // [!code focus]
  }, // [!code focus]
})
```

If `reuse` is omitted, the provider reuses any unexpired locally signable key whose scopes cover the requested scopes and transaction calls. Add `reuse.minExpiry` or `reuse.minLimits` when a stored key must also be valid long enough or have enough remaining policy capacity for your app's workflow.

You can also pre-derive the access key locally by passing `publicKey` or `address` with `keyType`. The wallet still authorizes that key during `wallet_connect`; the app keeps the signing material.

For `keyType: 'secp256k1'`, generate and store the private key in your app or backend, then pass either the derived `address` or the `publicKey` in `authorizeAccessKey`.

Alternatively, pass `privateKey` to let the SDK derive the access-key address and persist the private key through the configured [`storage`](#storage). `privateKey` material is not forwarded to wallets over JSON-RPC.

```ts twoslash
// @noErrors
import { Expiry, Provider } from 'accounts'

const provider = Provider.create({
  accessKey: { // [!code focus]
    authorize: { // [!code focus]
      expiry: Expiry.days(7), // [!code focus]
      keyType: 'p256', // [!code focus]
      publicKey: '0x1234', // [!code focus]
    }, // [!code focus]
  }, // [!code focus]
})
```

#### accessKey.keystores

* **Type:** `Keystore.Keystores`
* **Default:** `Keystore.defaults` — `{ p256: Keystore.webCryptoP256() }`

[Keystores](/docs/api/keystore) backing provider-generated access keys, one per key type.

```ts twoslash
import { Keystore, Provider } from 'accounts'

const provider = Provider.create({
  accessKey: { // [!code focus]
    keystores: { p256: Keystore.webCryptoP256({ extractable: true }) }, // [!code focus]
  }, // [!code focus]
})
```

### adapter

* **Type:** `Adapter`
* **Default:** `dialog()`

Adapter to use for account management.

```ts twoslash
import { Provider, webAuthn } from 'accounts'

const provider = Provider.create({
  adapter: webAuthn({ auth: '/auth' }), // [!code focus]
})
```

### auth

* **Type:** `string | { url?: string; challenge?: string; verify?: string; logout?: string; returnToken?: boolean }`
* **Optional**

Default Server Authentication configuration for `wallet_connect`. When set, every `wallet_connect` call orchestrates the SIWE round-trip against this endpoint unless the caller passes their own `capabilities.auth` (per-call override).

Designed to point at a service running [`Handler.webAuthn`](/docs/server/handler.webAuthn) from `accounts/server`.

Pass a base URL string (endpoints are derived as `${url}/challenge`, `${url}` for verify, and `${url}/logout`), or an object with explicit endpoints.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  auth: '/api/auth', // [!code focus]
})
```

Or with explicit endpoints:

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  auth: { // [!code focus]
    challenge: '/api/auth/challenge', // [!code focus]
    verify: '/api/auth/verify', // [!code focus]
    logout: '/api/auth/logout', // [!code focus]
    returnToken: true, // [!code focus]
  }, // [!code focus]
})
```

### chains

* **Type:** `readonly [Chain, ...Chain[]]`
* **Default:** `[tempo, tempoModerato, tempoDevnet]`

Supported chains. The first chain is the default.

```ts twoslash
import { Provider } from 'accounts'
import { tempo } from 'viem/tempo/chains'

const provider = Provider.create({
  chains: [tempo], // [!code focus]
})
```

### feePayer

* **Type:** `string | false | { url: string; precedence?: 'fee-payer-first' | 'user-first' }`
* **Optional**

Fee payer configuration for interacting with a service running [`Handler.relay`](/docs/server/handler.relay) from `accounts/server`. Pass a URL string, an object with `url` and optional `precedence` to control whether the fee payer or the user pays first, or `false` to opt out.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  feePayer: 'https://myapp.com/fee-payer', // [!code focus]
})
```

Or with precedence:

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  feePayer: { // [!code focus]
    url: 'https://myapp.com/fee-payer', // [!code focus]
    precedence: 'user-first', // [!code focus]
  }, // [!code focus]
})
```

### maxAccounts

* **Type:** `number`
* **Optional**

Maximum number of accounts to persist. Oldest accounts are evicted when exceeded (LRU).

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  maxAccounts: 5, // [!code focus]
})
```

### mpp

* **Type:** `boolean | Provider.mpp.Options`
* **Default:** `true`

Enable [Machine Payment Protocol](https://mpp.dev) (mppx) support. Enabled by default — pass an options object to configure, or `false` to disable.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  mpp: false, // [!code focus]
})
```

MPP session endpoints can use `deposit` or `maxDeposit` so the client opens and tops up a payment channel before sending vouchers.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  mpp: { // [!code focus]
    maxDeposit: '10', // [!code focus]
    mode: 'pull', // [!code focus]
  }, // [!code focus]
})
```

### persistCredentials

* **Type:** `boolean`
* **Default:** `true`

Whether to persist credentials and access keys to storage. When `false`, only account addresses are persisted (the user must re-authenticate on each session).

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  persistCredentials: false, // [!code focus]
})
```

### relay

* **Type:** `string`
* **Optional**

Base URL for a wallet relay endpoint. When set, every chain's transport defaults to `http("${relay}/${chainId}")` — a single endpoint that routes by chain ID via the path. Per-chain entries in `transports` override this on a chain-by-chain basis.

Designed to point at a service running [`Handler.relay`](/docs/server/handler.relay) from `accounts/server`.

Pass the base path here. The provider appends the active chain ID, so a base
path of `/relay` sends chain `33139` requests to `/relay/33139`.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  relay: '/relay', // [!code focus]
  // tempo (33139) → http('/relay/33139')
  // tempoModerato → http('/relay/<id>')
})
```

### storage

* **Type:** `Storage`
* **Default:** `Storage.idb()` in browser, `Storage.memory()` otherwise

Storage adapter for persistence. The default uses IndexedDB in browsers (via `Storage.idb()`) and an in-memory map elsewhere.

```ts twoslash
import { Provider, Storage } from 'accounts'

const provider = Provider.create({
  storage: Storage.memory(), // [!code focus]
})
```

### testnet

* **Type:** `boolean`
* **Default:** `false`

Use testnet. When `true`, the default chain will be the first testnet chain in `chains`.

```ts twoslash
import { Provider } from 'accounts'

const provider = Provider.create({
  testnet: true, // [!code focus]
})
```

### transports

* **Type:** `Record<number, Transport>`
* **Optional**

Per-chain transports keyed by chain ID. When omitted, defaults to `http()` for each chain (uses the chain's default RPC URL). Layered on top of `relay`, so explicit per-chain entries win over `relay`-derived defaults.

```ts twoslash
import { Provider } from 'accounts'
import { http } from 'viem'
import { tempo, tempoModerato } from 'viem/tempo/chains'

const provider = Provider.create({
  transports: { // [!code focus]
    [tempo.id]: http('/relay/' + tempo.id), // [!code focus]
    [tempoModerato.id]: http('/relay/' + tempoModerato.id), // [!code focus]
  }, // [!code focus]
})
```

## Return Type

The provider type is exported as `Provider` and is the intersection of [`ox.Provider.Provider`](https://oxlib.sh/Provider) (the EIP-1193 surface) and [`ox.Provider.Emitter`](https://oxlib.sh/Provider#emitter) plus a few extra accessors:

```ts
import type { Address, Hex, Provider as ox_Provider } from 'ox'
import type { Chain, Client as ViemClient, Transport } from 'viem'
import type { JsonRpcAccount } from 'viem/accounts'
import type { tempo } from 'viem/tempo/chains'

export type Provider = ox_Provider.Provider & ox_Provider.Emitter & {
  /** Configured chains. */
  chains: readonly [Chain, ...Chain[]]
  /** Returns the active root account as a viem JSON-RPC account. */
  getAccount(): JsonRpcAccount
  /** Returns local or on-chain publication status for an access key. */
  getAccessKeyStatus(options?: {
    address?: Address | undefined
    accessKey?: Address | undefined
    calls?: readonly { to?: Address | undefined; data?: Hex | undefined }[] | undefined
    chainId?: number | undefined
  }): Promise<'missing' | 'pending' | 'published' | 'expired'>
  /** Returns a viem Client for the given (or current) chain ID. */
  getClient(options?: {
    chainId?: number | undefined
    feePayer?: string | undefined
  }): ViemClient<Transport, typeof tempo>
  /** Reactive state store. */
  store: Store
}
```
