> For the complete documentation index, see [llms.txt](https://docs.osero.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.osero.com/osero-sdk/reference/configuration.md).

# Configuration

## Configuration

`@osero/client` ships two clients — see Clients for the conceptual overview. Each is configured at creation time:

* `OseroClient.create` — the local client
* `OseroApiClient.create` — the hosted API client

***

### `OseroClient.create`

```typescript
import { OseroClient } from '@osero/client';
import { http } from 'viem';

const client = OseroClient.create({
  transports: {
    1:     http('https://eth.llamarpc.com'),
    10:    http('https://mainnet.optimism.io'),
    130:   http('https://mainnet.unichain.org'),
    8453:  http('https://mainnet.base.org'),
    42161: http('https://arb1.arbitrum.io/rpc'),
  },
  defaultSlippageBps: 10, // 0.10% — overrides the 5 bps default
});
```

#### `transports`

A map of chain ID to viem `Transport`. Any chain without an explicit transport falls back to viem's built-in public HTTP transport.

**For production use, always configure custom transports.** Public transports are rate-limited and unsuitable for anything beyond development or quick demos.

All viem transport types are supported — `http`, `webSocket`, `fallback`, and custom transports:

```typescript
import { http, webSocket, fallback } from 'viem';

const client = OseroClient.create({
  transports: {
    8453: fallback([
      http('https://base-mainnet.g.alchemy.com/v2/YOUR_KEY'),
      http('https://mainnet.base.org'),
    ]),
  },
});
```

#### `defaultSlippageBps`

The default slippage tolerance in basis points (bps) applied to any action that does not provide its own `slippageBps` in the request. Defaults to `5` (0.05%).

1 bps = 0.01%. So `defaultSlippageBps: 10` sets a 0.10% default slippage tolerance.

Individual actions can override this per-request:

```typescript
await mintSUsds(client, {
  chainId: 8453,
  amount: parseUnits('100', 6),
  sender: '0xYourAddress',
  slippageBps: 20, // 0.20% for this request only
});
```

***

### Confirmation counts

Confirmation waits are configured **on the adapter**, via the `confirmations` option to `sendWith`. This is the only place the value is honoured — setting a `confirmations` field on the `OseroClient.create` config currently has no effect on broadcast behaviour.

```typescript
import { sendWith } from '@osero/client/viem';

// Wait for 2 block confirmations before resolving
const result = await mintUsds(client, request).andThen(
  sendWith(wallet, { confirmations: 2 })
);
```

The default confirmation count is `1`. For higher-value transactions or chains with fast finality, you may want to increase this.

The Privy adapter accepts the same `confirmations` option, plus `transports` for receipt polling and `idempotencyKeys` for server-side retries — see Privy Server Wallets.

***

### Environment variables pattern

For applications that configure RPC URLs via environment variables:

```typescript
import { OseroClient } from '@osero/client';
import { http } from 'viem';

const client = OseroClient.create({
  transports: {
    1:     http(process.env.RPC_URL_MAINNET!),
    10:    http(process.env.RPC_URL_OPTIMISM!),
    130:   http(process.env.RPC_URL_UNICHAIN!),
    8453:  http(process.env.RPC_URL_BASE!),
    42161: http(process.env.RPC_URL_ARBITRUM!),
  },
});
```

A sample `.env` file for local development:

```bash
RPC_URL_MAINNET=https://eth.llamarpc.com
RPC_URL_BASE=https://mainnet.base.org
RPC_URL_ARBITRUM=https://arb1.arbitrum.io/rpc
RPC_URL_OPTIMISM=https://mainnet.optimism.io
RPC_URL_UNICHAIN=https://mainnet.unichain.org
```

***

### Reusing a single client instance

`OseroClient` is designed to be created once and reused across the lifetime of your application. There is no connection state to manage and no teardown required.

```typescript
// config/osero.ts
import { OseroClient } from '@osero/client';
import { http } from 'viem';

export const oseroClient = OseroClient.create({
  transports: {
    8453: http(process.env.RPC_URL_BASE!),
  },
});
```

***

### `OseroApiClient.create`

The hosted API client is configured with an API key. It is pure HTTP — no viem transports, no RPC URLs.

```typescript
import { OseroApiClient } from '@osero/client/api';

const api = OseroApiClient.create({
  apiKey: process.env.OSERO_API_KEY!,
});
```

#### Options

| Field     | Type                    | Required | Description                                                                 |
| --------- | ----------------------- | -------- | --------------------------------------------------------------------------- |
| `apiKey`  | `string`                | no       | Default API key for every request. Starts with `osero_`, up to 256 chars    |
| `baseUrl` | `string`                | no       | Defaults to `https://api.osero.org/v1/`. Override only for non-prod targets |
| `fetch`   | `OseroApiFetch`         | no       | Custom fetch implementation. Defaults to global `fetch`                     |
| `headers` | `Record<string,string>` | no       | Headers added to every request — useful for tracing                         |

`OseroApiClient.create` validates `baseUrl` synchronously and throws a `ValidationError` if it is malformed. It also throws an `UnexpectedError` synchronously if no `fetch` is available — pass a custom one if your runtime lacks a global `fetch`.

`apiKey` is **not** validated at construction — it is checked on every request and resolves to a `ValidationError` if missing or malformed. That makes it safe to construct a client up front and inject the key later.

#### Default headers

```typescript
const api = OseroApiClient.create({
  apiKey: process.env.OSERO_API_KEY!,
  headers: {
    'X-Request-Source': 'partner-dashboard',
  },
});
```

The client always sends `Accept: application/json` and adds `Content-Type: application/json` to non-`GET` requests. `Authorization: Bearer <apiKey>` is added when an API key is in scope. Anything you pass in `headers` is merged in.

#### Custom fetch

For environments without a global `fetch`, supply one:

```typescript
import fetch from 'node-fetch';

const api = OseroApiClient.create({
  apiKey: process.env.OSERO_API_KEY!,
  fetch: fetch as unknown as typeof globalThis.fetch,
});
```

#### Per-request options

Every method accepts a second argument with three optional fields. Use it to override the key for a single call, attach an abort signal, or merge per-request headers:

```typescript
const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);

const quote = await api.getSwapQuote(request, {
  apiKey: 'osero_partner-key',
  signal: controller.signal,
  headers: { 'X-Trace-Id': traceId },
});
```

| Option    | Type                    | Effect                                                  |
| --------- | ----------------------- | ------------------------------------------------------- |
| `apiKey`  | `string`                | Replaces the client-level key for this call             |
| `signal`  | `AbortSignal`           | Cancels the in-flight request                           |
| `headers` | `Record<string,string>` | Merged with the client-level headers (per-request wins) |

#### Reusing a single API client

`OseroApiClient` holds no connection state and is safe to create once and reuse. For multi-tenant servers, create one client with no `apiKey` and pass `{ apiKey }` per request.

#### Methods at a glance

| Method                               | HTTP                 | Returns                                             |
| ------------------------------------ | -------------------- | --------------------------------------------------- |
| `getSupportedAssets(options?)`       | `GET /assets`        | `ResultAsync<OseroApiSupportedAssetsResponse, ...>` |
| `getSwapQuote(request, options?)`    | `POST /swaps/quote`  | `ResultAsync<OseroApiSwapQuote, ...>`               |
| `getSwapStatus(request, options?)`   | `POST /swaps/status` | `ResultAsync<OseroApiSwapStatusResponse, ...>`      |
| `getSwapStatusForQuote(quote, hash)` | `POST /swaps/status` | `ResultAsync<OseroApiSwapStatusResponse, ...>`      |

See Actions for the full hosted swap-quote walkthrough.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.osero.com/osero-sdk/reference/configuration.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
