> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ravn.exchange/llms.txt
> Use this file to discover all available pages before exploring further.

# @ravnexchange/sdk

> Typed client for /api/v1, quote, execute, submit-signature, and status.

A thin, zero-dependency wrapper around the four calls in the [Quickstart](/quickstart). Same
request and response shapes as the raw API, just typed, with one error type instead of parsing
HTTP status codes yourself.

## Setup

```bash theme={null}
npm install @ravnexchange/sdk
```

```ts theme={null}
import { RavnClient } from "@ravnexchange/sdk";

const client = new RavnClient({
  apiKey: "rvn_live_your_key_here", // optional, omit for the anonymous tier
});
```

<ParamField body="apiKey" type="string">Self-serve or enterprise key. Omit for the anonymous tier: it works immediately, at a lower rate limit. See [Authentication](/authentication).</ParamField>
<ParamField body="baseUrl" type="string">Default `https://app.ravn.exchange/api/v1`.</ParamField>
<ParamField body="fetch" type="function">Swap in your own `fetch` (React Native, a test double). Defaults to the global `fetch`.</ParamField>

## Full example

Quote, execute, and track a swap end to end. `execution.executionType` also branches to
`TRANSACTION` or `SIGNATURE`; see the [Quickstart](/quickstart) for the full switch.

```ts theme={null}
const quote = await client.getQuote({
  inputChainId: 1,
  outputChainId: -2,
  inputToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  outputToken: "So11111111111111111111111111111111111111112",
  inputAmount: "1000000000000000000",
  userAddress: "0xYourUser",
  destinationAddress: "SoYourUser",
});

const execution = await client.execute({ quoteToken: quote.quoteToken });

if (execution.executionType === "DEPOSIT") {
  await wallet.send(execution.deposit.address, execution.deposit.amount);
  const status = await client.getStatus(execution.quoteToken, execution.statusRef);
}
```

## Methods

Every method throws `RavnApiError` on a non-2xx response; see [Errors](#errors) below. Field
meanings match the [API Reference](/api-reference/overview) pages linked from each method.

### getQuote

```ts theme={null}
const quote = await client.getQuote({
  inputChainId: 1,
  outputChainId: -2,
  inputToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  outputToken: "So11111111111111111111111111111111111111112",
  inputAmount: "1000000000000000000",
  userAddress: "0xYourUser",
  destinationAddress: "SoYourUser",
});
```

Wraps [`POST /quote`](/api-reference/quote). Omitting `destinationAddress`/`refundAddress`
returns a preview-only quote, so check `quote.executable` before calling `execute`. Pass
`excludeVenues` to drop a specific venue from the race; read `quote.alternatives` for every
other venue that also produced a usable quote, and `quote.inputUsd`/`quote.outputUsd` for a
dollar value on each side. Pass `confidential: true` for a [private swap](/supported#private-swaps)
(SDK 0.1.8 or later). When `quote.slippage?.noMinimum` is true, the venue enforces no
minimum output, so the user can receive more or less than quoted: show that before they send
funds.

### execute

```ts theme={null}
const execution = await client.execute({ quoteToken: quote.quoteToken });

switch (execution.executionType) {
  case "TRANSACTION": /* ... */ break;
  case "SIGNATURE": /* ... */ break;
  case "DEPOSIT": /* ... */ break;
}
```

Wraps [`POST /execute`](/api-reference/execute). Branch on `executionType` exactly as in the
[Quickstart](/quickstart). This client doesn't sign or send anything for you.

### submitSignature

```ts theme={null}
const { statusRef } = await client.submitSignature({
  quoteToken: execution.quoteToken,
  signature: sig,
});
```

Wraps [`POST /submit-signature`](/api-reference/submit-signature). Only for `SIGNATURE`-type
executions. Pass `execution.quoteToken`, not `quote.quoteToken`. Returns the `statusRef` to
poll `getStatus` with.

### getStatus

```ts theme={null}
const status = await client.getStatus(execution.quoteToken, statusRef);
```

Wraps [`/status`](/api-reference/status). Pass `execution.quoteToken`, not `quote.quoteToken`:
a two-hop RAVN route is rebound at execute. `ref` is the `statusRef` from `execute` (for `DEPOSIT`, and
`TRANSACTION` when present), from `submitSignature` (for `SIGNATURE`), or otherwise the
transaction hash you broadcast (for `TRANSACTION`), matching the Full example above. Once terminal, a venue that reports it adds
`deliveredAmount` and `txHash` to the result. Poll every swap to a terminal state: that is what
settles it for fee payout, see [Settlement](/api-reference/status#settlement).

## executeAndTrack

The Full example above hand-rolls the approval sequencing for `DEPOSIT`. For `TRANSACTION` and
`SIGNATURE`, where an approval can actually be involved, use `executeAndTrack` instead of
repeating that logic yourself:

```ts theme={null}
import { executeAndTrack } from "@ravnexchange/sdk";

const result = await executeAndTrack(
  client,
  { quoteToken: quote.quoteToken },
  {
    sendTransaction: (tx) => wallet.sendTransaction(tx),
    waitForReceipt: (hash) => wallet.waitForTransactionReceipt({ hash }).then(() => undefined),
    signTypedData: (typedData) => wallet.signTypedData(typedData),
    // Optional: skip a redundant approve when you already track allowance yourself.
    hasAllowance: (approval) => myAllowanceCache.covers(approval),
  }
);

console.log(result.execution.executionType, result.finalStatus?.status);
```

It sequences `execute()` → approval (if any) → wait for the approval's receipt → the main
transaction or signature → status polling, using your own `sendTransaction`/`waitForReceipt`/
`signTypedData` functions. This is the exact ordering [Quickstart](/quickstart) calls out as the
most common integration failure, just already gotten right.

<ParamField body="handlers.sendTransaction" type="(tx) => Promise<string>" required>Broadcast a transaction (an approval, or the main swap tx) and return its hash.</ParamField>
<ParamField body="handlers.waitForReceipt" type="(hash, chainId?) => Promise<void>" required>Wait for a transaction hash to confirm. Called on the approval before the main tx is ever sent.</ParamField>
<ParamField body="handlers.signTypedData" type="(typedData) => Promise<`0x${string}`>">Only required for `SIGNATURE` executions.</ParamField>
<ParamField body="handlers.hasAllowance" type="(approval: ApprovalDTO) => Promise<boolean>">An allowance read against your own RPC. Without it, the approval tx is sent unconditionally, even when the caller already has enough allowance, the SDK never reads the chain itself to check.</ParamField>
<ParamField body="options.pollUntilTerminal" type="boolean">Default `true`. Set `false` to get a ref back immediately and poll `getStatus` yourself.</ParamField>
<ParamField body="options.pollIntervalMs" type="number">Default `4000`.</ParamField>

<ResponseField name="execution" type="ExecutionDTO" />

<ResponseField name="approvalTxHash" type="string">Set only when an approval was actually sent.</ResponseField>
<ResponseField name="txHash" type="string">Set for `TRANSACTION` executions.</ResponseField>
<ResponseField name="quoteToken" type="string">Pass with `statusRef` to `client.getStatus(quoteToken, statusRef)`. Same as `execution.quoteToken`, not the quote's own token.</ResponseField>
<ResponseField name="statusRef" type="string">Pass with `quoteToken` to `client.getStatus(quoteToken, statusRef)`. For `TRANSACTION`, the execution's own `statusRef` when it has one, else `txHash`.</ResponseField>
<ResponseField name="finalStatus" type="StatusDTO">Set once polling reaches a terminal status. Absent for `DEPOSIT` (nothing to broadcast from here, the user moves funds out-of-band) or when `pollUntilTerminal` is `false`.</ResponseField>

<Note>
  Stays wallet-agnostic on purpose, no RPC dependency, so `@ravnexchange/sdk` keeps its zero-dependency
  footprint. You supply the signing/sending, `executeAndTrack` only gets the order right.
</Note>

## Errors

Every non-2xx response throws a `RavnApiError`, never a raw fetch or JSON error:

```ts theme={null}
import { RavnApiError } from "@ravnexchange/sdk";

try {
  await client.execute({ quoteToken });
} catch (err) {
  if (err instanceof RavnApiError) {
    console.log(err.code, err.message, err.details);
  }
}
```

<ResponseField name="code" type="string">The stable, machine-readable code. See [Errors](/errors) for the full table.</ResponseField>
<ResponseField name="message" type="string">Human-readable, and can change. Don't branch on it.</ResponseField>
<ResponseField name="details" type="unknown">Present on some codes, for example the failed fields on `INVALID_REQUEST`.</ResponseField>
<ResponseField name="meta" type="object">`requestId` and `version`, when the API returned an envelope at all.</ResponseField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.