> 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/core-concepts/clients.md).

# Clients

## Clients

`@osero/client` ships two clients. They serve different needs but produce the same Execution Plan, and either one is broadcast with the same `sendWith` adapter.

* **`OseroClient`** — builds plans **locally** from on-chain reads. One chain at a time, single-chain mints and redeems, no API key.
* **`OseroApiClient`** — talks to the **hosted Osero API**. Returns priced swap quotes — including cross-chain routes between USDC on an L2 and sUSDS on Ethereum Mainnet.

Use one or the other, or both. The API client does not need an `OseroClient` to work, and the local actions do not need an API key.

***

### The local client

`OseroClient.create` takes a map of viem `Transport`s and an optional default slippage. It is stateless and meant to be created once and reused.

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

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

The local client is what you pass to the Actions in `@osero/client/actions` — `mintUsds`, `mintSUsds`, `redeemUsds`, `redeemSUsds`. Each returns a `ResultAsync<ExecutionPlan, ActionError>` that you broadcast with `sendWith`.

See Configuration for the full options reference.

***

### The hosted API client

`OseroApiClient.create` takes an API key. It is pure HTTP, so it needs neither `viem` transports nor RPC URLs:

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

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

The API client exposes two route methods — `getSupportedAssets` and `getSwapQuote` — plus `getSwapStatus` / `getSwapStatusForQuote` for tracking cross-chain bridges. A successful quote bundles an `executionPlan` you broadcast through the same `sendWith` adapter as a local action.

API keys start with the `osero_` prefix. The client validates that shape locally before every request — a malformed key fails fast with a `ValidationError` and never hits the network.

See Actions for the full hosted swap-quote walkthrough and Configuration for the full options reference.

***

### Choosing between them

| You want to…                                              | Use                           |
| --------------------------------------------------------- | ----------------------------- |
| Mint or redeem on a **single supported chain**            | `OseroClient` + local actions |
| Quote and broadcast a **cross-chain** USDC ↔ sUSDS route  | `OseroApiClient`              |
| Build a plan from **on-chain reads** with no external API | `OseroClient` + local actions |
| Have pricing and routing handled **server-side**          | `OseroApiClient`              |
| Avoid managing an API key                                 | `OseroClient` + local actions |
| Avoid configuring RPC transports                          | `OseroApiClient`              |

You can use both in the same app. A common pattern is to use the local client for L2-only flows and the hosted API for anything that involves Ethereum Mainnet sUSDS from an L2.

***

### Supported chains differ slightly

The two clients have overlapping but **not identical** chain sets — the hosted API supports Linea but not Unichain, the local client supports Unichain but not Linea:

| Chain            | Chain ID | `OseroClient` | `OseroApiClient` |
| ---------------- | -------: | :-----------: | :--------------: |
| Ethereum Mainnet |        1 |       ✓       |         ✓        |
| OP Mainnet       |       10 |       ✓       |         ✓        |
| Unichain         |      130 |       ✓       |                  |
| Base             |     8453 |       ✓       |         ✓        |
| Arbitrum One     |    42161 |       ✓       |         ✓        |
| Linea            |    59144 |               |         ✓        |

See Supported Chains for the local-client set and `getSupportedAssets()` for the hosted set at runtime.

***

### One plan model, one adapter

Whichever client you pick, the output is an `ExecutionPlan` — the same discriminated union (`TransactionRequest` / `Erc20ApprovalRequired` / `MultiStepExecution`) — and you broadcast it the same way:

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

// Local action
const localResult = await mintUsds(client, request)
  .andThen(sendWith(wallet));

// Hosted quote
const hostedResult = await api
  .getSwapQuote(request)
  .map((quote) => quote.executionPlan)
  .andThen(sendWith(wallet));
```

Both resolve to the same `Result<TransactionResult, OseroError>` — see Error Handling.

The same holds for the other adapters — `sendWith` from `@osero/client/ethers` takes an ethers `Signer`, and `sendWith` from `@osero/client/privy` takes a `PrivyClient` and a server wallet descriptor.

***

### Next steps

* Execution Plan — the shape both clients return
* Actions — the local actions and the hosted swap-quote method
* Configuration — full options for both clients


---

# 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/core-concepts/clients.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.
