---
title: createSv3Client
description: Create the SV3 TypeScript client from a viem Public Client and a deployment manifest.
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

Creates a `sv3Client`. This is the only supported way to talk to SV3 from TypeScript.

The client does not connect a wallet, choose an RPC, or import React. You pass a [viem Public Client](https://viem.sh/docs/clients/public) (and optionally a Wallet Client), the same pattern as `createPublicClient` / `createWalletClient`.

## Import

```ts
import { createSv3Client, createReadOnlySv3Client } from "@repo/contract-client";
```

`createFloorSdk` / `createReadOnlyFloorSdk` are deprecated aliases.

## Usage

```ts
import { createPublicClient, http } from "viem";
import { foundry } from "viem/chains";
import { createSv3Client } from "@repo/contract-client";
import { ANVIL_CHAIN_ID, ANVIL_DEPLOYMENT_MANIFEST } from "@repo/chain-config";

const publicClient = createPublicClient({
  chain: foundry,
  transport: http("http://127.0.0.1:8545"),
});

const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment: {
    ...ANVIL_DEPLOYMENT_MANIFEST,
    contracts: {
      directoryProxy: "0x…",
      factoryProxy: "0x…",
      marketBeacon: "0x…",
      marketImplementation: "0x…",
      floorPolicyControllerProxy: "0x…",
      floorMarketQuoter: "0x…",
    },
  },
});
```

With a wallet, so `prepare*` and `executePrepared` can run:

```ts
import { createWalletClient, custom } from "viem";

const walletClient = createWalletClient({
  chain: foundry,
  transport: custom(window.ethereum),
});

const [account] = await walletClient.getAddresses();

const sv3 = createSv3Client({
  publicClient,
  walletClient,
  account,
  chainId: ANVIL_CHAIN_ID,
  deployment,
});
```

Or bind later:

```ts
const writable = sv3.withWalletClient(walletClient).withAccount(account);
```

Read-only (writes throw `WalletClientRequiredError`):

```ts
const sv3 = createReadOnlySv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
});
```

## Return Value

`sv3Client`

Namespaces: `market`, `factory`, `directory`, `token`, `quote`, `trade`, `position`, `authorization`, `transactions`, `floor`, `network`, `events`, `errors`, `revenue`, `metrics`, `units`, `math`.

Helpers on the client:

| Method                           | Meaning                                                 |
| -------------------------------- | ------------------------------------------------------- |
| `withWalletClient(walletClient)` | Returns a new client that can send                      |
| `withAccount(account)`           | Binds the address that must match prepared transactions |
| `withBlockTag(tag)`              | Pins later reads to this tag                            |
| `getConfig()`                    | Sanitized config (no secrets)                           |
| `getSdkVersion()`                | `{ version }`                                           |
| `assertSupportedChain()`         | Throws `UnsupportedChainError` on mismatch              |
| `assertDeployment()`             | Reloads directory pointers                              |
| `getMarket(address)`             | Identity plus a snapshot                                |

## Parameters

### publicClient

- **Type:** `PublicClient`

Required. viem public client used for reads, multicall, and `simulateContract`.

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
});
```

### chainId

- **Type:** `8453 | 31337`

Must match `publicClient.chain.id` when that is set. Any other chain throws `UnsupportedChainError`.

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: 31337,
  deployment,
});
```

### deployment

- **Type:** `DeploymentManifest`

Proxy addresses and curve metadata for this chain. Spread `ANVIL_DEPLOYMENT_MANIFEST` or `BASE_DEPLOYMENT_MANIFEST` from `@repo/chain-config`, then fill `contracts`.

Required contract fields for a working client:

| Field                        | Address of                 |
| ---------------------------- | -------------------------- |
| `directoryProxy`             | Directory                  |
| `factoryProxy`               | Factory                    |
| `marketBeacon`               | Upgradeable beacon         |
| `marketImplementation`       | FloorMarket implementation |
| `floorPolicyControllerProxy` | Floor policy controller    |
| `floorMarketQuoter`          | View-only quoter           |

`deployment.curveLibrary` (`kind`, `revision`, `sourceHash`) gates local math. Unknown revisions throw `UnsupportedCurveRevisionError`.

See [Deployments](/protocol/deployments).

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment: {
    ...ANVIL_DEPLOYMENT_MANIFEST,
    contracts: {/* proxies */},
  },
});
```

### walletClient (optional)

- **Type:** `WalletClient`

Needed to send. Reads and local quotes work without it.

```ts
const sv3 = createSv3Client({
  publicClient,
  walletClient,
  account,
  chainId: ANVIL_CHAIN_ID,
  deployment,
});
```

### account (optional)

- **Type:** `Address | Account`

The account that must match prepared transactions. Bound later with `sv3.withAccount`.

```ts
const sv3 = createSv3Client({
  publicClient,
  walletClient,
  account: "0x…",
  chainId: ANVIL_CHAIN_ID,
  deployment,
});
```

### defaultDeadlineSeconds (optional)

- **Type:** `number`
- **Default:** `300`

Attached to prepared writes. Values above `maxDeadlineSeconds` throw `InvalidDeadlineError`.

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
  defaultDeadlineSeconds: 120,
});
```

### maxDeadlineSeconds (optional)

- **Type:** `number`
- **Default:** `1800`

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
  maxDeadlineSeconds: 600,
});
```

### defaultConfirmations (optional)

- **Type:** `number`
- **Default:** `1`

Passed to [`wait`](/developers/wait) unless overridden.

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
  defaultConfirmations: 2,
});
```

### multicall (optional)

- **Type:** `{ deployless?: boolean; address?: Address }`

Anvil defaults to deployless multicall. Base uses the chain Multicall3 unless you set `address`.

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: 8453,
  deployment,
  multicall: { address: "0xcA11bde05977b3631167028862bE2a173976CA11" },
});
```

### permitCapability (optional)

- **Type:** `'none' | 'eip2612'`
- **Default:** `'none'`

Contract wallets use the allowance route unless this is `'eip2612'`. See [getRequirements](/developers/get-requirements).

```ts
const sv3 = createSv3Client({
  publicClient,
  chainId: ANVIL_CHAIN_ID,
  deployment,
  permitCapability: "eip2612",
});
```

### logger (optional)

- **Type:** `{ debug, info, warn, error }`

Must not log secrets or authorization headers.

## Error

| Error                   | When                                                                             |
| ----------------------- | -------------------------------------------------------------------------------- |
| `UnsupportedChainError` | `chainId` is not `8453` or `31337`, or it disagrees with `publicClient.chain.id` |
| `InvalidSdkConfigError` | `deployment` is missing                                                          |

## Tips

- The client is cheap to construct. Prefer one instance per chain, then `withAccount` per connected wallet.
- `getConfig()` is safe to log. It does not include the wallet, RPC URL, or keys.
