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

> ## Agent Instructions
> Before reading these docs, install the Circle Skill for Arc to get pre-loaded context: use-arc (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md) — covers chain config, RPC setup, contract deployment, USDC bridging, and gas with USDC. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills.
> USDC is the gas token. Arc uses USDC for gas fees, not ETH. Configure gas payment in USDC when submitting transactions.
> Read EVM differences before writing Arc code. Arc targets the Osaka EVM baseline. Most contracts deploy unchanged, but several runtime behaviors diverge from Ethereum: USDC uses 18 decimals natively (not 6), the system emitter `0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE` logs all USDC Transfer events, the mempool enforces a 20 Gwei `maxFeePerGas` floor, blocklist reverts consume gas without a receipt, and `address(0)` sends revert rather than succeed. https://docs.arc.io/arc/references/evm-differences.md is the canonical reference for all Arc-specific runtime behaviors. Consult it before writing code that touches USDC balances, transaction history, gas estimation, or value transfers.
> Sub-second finality. Transactions are final in under 1 second. No need to wait for multiple block confirmations.
> Use App Kits for multichain payment and liquidity capabilities. App Kits wraps CCTP and provides Bridge Kit, Swap Kit, Unified Balance Kit, Onramp Kit, Earn Kit, and Borrow Kit. Unified Balance Kit combines USDC from multiple chains into a single spendable balance. Earn Kit integrates earn opportunities into your app. Borrow Kit lets users borrow USDC against cirBTC collateral on Arc.
> Use Arc Foundry for contract development. Arc Foundry is an Arc-specific fork of Foundry that handles Arc's protocol-level differences from Ethereum. It provides arc-forge, arc-cast, and arc-anvil. Install it before deploying contracts: https://docs.arc.io/arc/tutorials/install-arc-foundry.md.
> Arc is available on both Testnet and Mainnet. See https://docs.arc.io/arc/references/connect-to-arc.md for RPC endpoints and https://faucet.circle.com for testnet tokens.
> Always check Contract Addresses: https://docs.arc.io/arc/references/contract-addresses.md
> Building beyond Arc? Circle offers skills for the full platform: use-usdc (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md), use-circle-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md), use-developer-controlled-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md), use-user-controlled-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md), use-modular-wallets (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md), use-gateway (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md), use-smart-contract-platform (https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md). Full Circle developer docs: https://developers.circle.com/llms.txt.

# App Kit SDK Reference

> API reference for App Kit's public interfaces, methods, and types

This reference guide describes the public interfaces, methods, and types
available in the App Kit SDK.

## AppKit Class

The `AppKit` is how you'll perform all stablecoin operations including
crosschain bridging, same-chain swaps, token transfers, and fee estimation. It
also enables you to add event listeners for bridge transfers.

### constructor(config?)

Creates a new `AppKit` instance.

```typescript theme={null}
constructor(config?: AppKitConfig)
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| config | [`AppKitConfig`](#appkitconfig) | Optional configuration for fee estimation, developer fees, and the underlying UnifiedBalanceKit. |

**Usage**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

// Minimal — all defaults
const kit = new AppKit();

// With unified balance config
const kitWithUb = new AppKit({
  unifiedBalance: { providers: [myCustomProvider] },
});
```

### AppKitConfig

```typescript theme={null}
type AppKitConfig = CreateContextParams & {
  developerFee?: Partial<DeveloperFeeHooks>;
  disableAnalytics?: boolean;
  disableErrorReporting?: boolean;
  unifiedBalance?: UnifiedBalanceKitConfig;
};
```

**Properties**

| Name | Type | Description |
| - | - | - |
| developerFee | `Partial<DeveloperFeeHooks>` | Optional developer fee hooks passed through to BridgeKit when both are provided |
| disableAnalytics | boolean | Disable success analytics for the underlying EarnKit, SwapKit, and UnifiedBalanceKit.<br /><br /> When `true`, completed earn, swap, and unified balance operations will not POST analytics events. This does not disable error reporting; use AppKitConfig.disableErrorReporting for that. Defaults to `false`. |
| disableErrorReporting | boolean | Disable error telemetry for all underlying kits.<br /><br /> When `true`, BridgeKit, SwapKit, EarnKit, and UnifiedBalanceKit will not POST error details to the telemetry endpoint. Defaults to `false`. |
| unifiedBalance | UnifiedBalanceKitConfig | Optional config forwarded to the underlying UnifiedBalanceKit. |

***

***

## Methods

### bridge(params)

Execute a crosschain USDC bridge transfer.

Transfers USDC between different blockchain networks using Circle's Cross-Chain
Transfer Protocol (CCTP). Supports both fast and standard transfer speeds with
automatic attestation handling.

```typescript theme={null}
bridge(params: Omit<BridgeParams, 'token'> & { token?: 'USDC' }): Promise<BridgeResult>
bridge(params: BridgeParams): Promise<BridgeResult<string>>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `unknown` | Bridge parameters containing source, destination, amount, and token |

**Returns**

`Promise<BridgeResult<'USDC'>>`

**Usage Example**

```typescript theme={null}
const result = await kit.bridge({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: { adapter: destAdapter, chain: "Polygon" },
  amount: "100.50",
  token: "USDC",
});

console.log(`Bridged ${result.amount} ${result.token} (${result.state})`);
```

***

### estimateBridge(params)

Estimate the bridge operation.

Calculates gas costs, protocol fees, and optional custom fees for a crosschain
bridge transfer without executing the transaction. Useful for displaying cost
estimates to users before they confirm a transfer.

```typescript theme={null}
estimateBridge(params: Omit<BridgeParams, 'token'> & { token?: 'USDC' config: { feePayment: 'source' } }): Promise<ReceiveExactEstimateResult>
estimateBridge(params: Omit<BridgeParams, 'token'> & { token?: 'USDC' }): Promise<EstimateResult>
estimateBridge(params: BridgeParams): Promise<EstimateResult<string, string>>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `unknown` | Bridge parameters containing source, destination, amount, and token |

**Returns**

[`Promise<ReceiveExactEstimateResult>`](#receiveexactestimateresult)

#### ReceiveExactEstimateResult

Return a receive-exact bridge estimate backed by a short-lived signed quote.

```typescript theme={null}
interface ReceiveExactEstimateResult {
  amount: string
  amountReceived: string
  destination: { address: string; chain: Blockchain; recipientAddress?: string }
  feeItems: readonly ReceiveExactFeeItem[]
  fees: { amount: string \| null; error?: unknown; token: 'USDC'; type: 'kit' \| 'provider' \| 'forwarder' }[]
  feeTotal: string
  gasFees: { blockchain: Blockchain; error?: unknown; fees: EstimatedGas \| null; name: string; token: string }[]
  quote: string
  quoteExpiry: FeeQuoteExpiry
  source: { address: string; chain: Blockchain }
  token: 'USDC'
  totalDebit: string
  warnings?: BridgeWarning[]
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount being transferred |
| amountReceived | string | The exact amount the destination recipient receives, in USDC. |
| destination | `{ address: string; chain: Blockchain; recipientAddress?: string }` | Information about the destination chain and address |
| feeItems | readonly ReceiveExactFeeItem\[] | The itemized signed fee quote, with amounts in human-readable USDC. |
| fees | `{ amount: string \| null; error?: unknown; token: 'USDC'; type: 'kit' \| 'provider' \| 'forwarder' }[]` | Array of protocol and service fees for the transfer |
| feeTotal | string | The total signed fee collected on the source chain, in USDC. |
| gasFees | `{ blockchain: Blockchain; error?: unknown; fees: EstimatedGas \| null; name: string; token: string }[]` | Array of gas fees required for the transfer on different blockchains |
| quote | string | Opaque signed quote bytes to pass to BridgeKit.bridge. |
| quoteExpiry | FeeQuoteExpiry | The authoritative expiry returned by the Fee Service. |
| source | `{ address: string; chain: Blockchain }` | Information about the source chain and address |
| token | `'USDC'` | The token being estimated. |
| totalDebit | string | The total source-wallet debit (`amountReceived + feeTotal`), in USDC. |
| warnings | BridgeWarning\[] | Optional non-fatal advisories about how this estimate was produced.<br /><br /> An estimate can differ from what the caller asked for without failing — the speed may be re-priced — and that difference leaves no positive trace anywhere else in the result: it can only be inferred by comparing the quote's fee items against the speed that was asked for, on a provider whose quote exposes them. The codes are drawn from the same set a bridge uses, so a consumer checks both results the same way. |

#### ReceiveExactFeeItem

Describe one signed Fee Service line item in human-readable USDC.

```typescript theme={null}
interface ReceiveExactFeeItem {
  amount: string;
  args: readonly string[];
  argsHash: string;
  type: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The fee amount in human-readable USDC. |
| args | readonly string\[] | The ABI arguments covered by the signed quote. |
| argsHash | string | The hash of the ABI arguments covered by the signed quote. |
| type | string | The Fee Service item type, such as `FORWARD` or `PRE_FINALITY`. |

**Usage Example**

```typescript theme={null}
const estimate = await kit.estimateBridge({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: { adapter: destAdapter, chain: "Polygon" },
  amount: "100.50",
  token: "USDC",
});

console.log("Estimated fees:", estimate.fees);
```

***

### estimateSend(params)

Estimate network fees for a send operation.

Prepare the send (validation + recipient resolution) and returns the gas
estimate without executing the actual transaction. This allows developers to
show users the cost before committing to the transfer.

```typescript theme={null}
estimateSend(params: SendParams): Promise<EstimatedGas>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SendParams`](#sendparams) | Send parameters: source, destination (address or adapter), amount, token. |

#### SendParams

Parameters for sending USDC, USDT, native tokens, or custom ERC-20/SPL tokens.

This interface is the canonical input for send operations in App Kit. It
supports sending to either a destination Adapter (recipient derives from the
adapter's default account) or an explicit recipient `string` address.

* The `from` field provides the source signing context and chain.
* The `to` field identifies the destination as an adapter or an explicit
  address.
* The `amount` field is a human-readable decimal string (for example, `'10.5'`).
* The `token` field selects the asset to move and defaults to `'USDC'`.

```typescript theme={null}
interface SendParams {
  amount: string
  from: AdapterContext
  to: string \| Adapter<AdapterCapabilities>
  token?: TokenAlias \| TokenAddress
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount to transfer. |
| from | AdapterContext | The source adapter context (wallet and chain) for the transfer. |
| to | `string \| Adapter` | The destination for the transfer, supporting explicit or derived recipient addresses. |
| token | `TokenAlias \| TokenAddress` | The token to transfer. Defaults to `USDC`. If omitted, the provider will use `USDC` by default.<br /><br /> Supports both known aliases and custom token contract addresses:<br />- Known aliases: `USDC`, `USDT`, `NATIVE`, `EURC` (`EURC` requires the chain to have an `eurcAddress` configured)<br />- Custom token addresses: EVM addresses or Solana SPL token mint addresses |

**Returns**

[`Promise<EstimatedGas>`](#estimatedgas)

#### EstimatedGas

Estimated gas information for a blockchain transaction.

This interface provides a unified way to represent gas costs across different
blockchain networks, supporting both EVM-style gas calculations and other fee
models.

```typescript theme={null}
interface EstimatedGas {
  fee: string;
  gas: bigint;
  gasPrice: bigint;
}
```

**Usage Examples**

```typescript theme={null}
const estimate = await kit.estimateSend({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: recipientAdapter,
  amount: "100.50",
  token: "USDC",
});

console.log("Estimated gas:", estimate.gas);
```

```typescript theme={null}
const estimate = await kit.estimateSend({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
  amount: "50.0",
  token: "USDT",
});

console.log("Estimated gas:", estimate.gas);
```

***

### estimateSwap(params)

Estimate the output and fees for a swap operation.

Calculates the expected output amount, minimum output (with slippage), and fee
breakdown for a token swap without executing the transaction.

```typescript theme={null}
estimateSwap(params: SwapParams): Promise<SwapEstimate>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SwapParams`](#swapparams) | Swap parameters containing source, tokens, amount, and config |

#### SwapParams

```typescript theme={null}
interface SwapParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  from: SwapAdapterContext<TFromAdapterCapabilities>;
  tokenIn: SupportedSwapToken;
  tokenOut: SupportedSwapToken;
  amountIn: string;
  to?: SwapDestination;
  config?: SwapConfig;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amountIn | string | The amount of the input token to swap.<br /><br /> Expressed as a human-readable decimal string in token units (e.g., `'0.05'` for 0.05 USDC or 0.05 ETH). |
| config | SwapConfig | Optional configuration for swap behavior.<br /><br /> If omitted, defaults will be used:<br />- `allowanceStrategy`: `permit` (fallback to `approve`)<br />- `slippageBps`: 300 (3%) |
| from | `SwapAdapterContext` | The source adapter context (wallet and chain) for the swap. |
| to | SwapDestination | Optional destination chain/address.<br /><br /> For same-chain swaps this may be omitted and the source wallet address is used as the recipient. crosschain swaps require `recipientAddress`. |
| tokenIn | SupportedSwapToken | The input token to swap from.<br /><br /> Supports stablecoins (USDC, USDT, EURC, USDe, DAI, PYUSD), wrapped tokens (WBTC, WETH, WSOL, WAVAX, WPOL), and native tokens (NATIVE or chain-specific symbols). |
| tokenOut | SupportedSwapToken | The output token to swap to.<br /><br /> Supports stablecoins (USDC, USDT, EURC, USDe, DAI, PYUSD), wrapped tokens (WBTC, WETH, WSOL, WAVAX, WPOL), and native tokens (NATIVE or chain-specific symbols). |

**Returns**

[`Promise<SwapEstimate>`](#swapestimate)

#### SwapEstimate

Estimation result for a swap operation.

Contains the provider's swap quote including minimum output (stop limit),
estimated output amount, fee breakdown, and input context fields

```typescript theme={null}
interface SwapEstimate {
  readonly tokenIn: SupportedSwapToken;
  readonly tokenOut: SupportedSwapToken;
  readonly amountIn: string;
  readonly chainIn: Blockchain;
  readonly chainOut: Blockchain;
  readonly chain: Blockchain;
  readonly fromAddress: string;
  readonly toAddress: string;
  readonly stopLimit: TokenAmount;
  readonly estimatedOutput: TokenAmount;
  readonly fees?: readonly ServiceSwapFee[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amountIn | string | The input amount that will be swapped.<br /><br /> Expressed as a human-readable decimal string in token units (e.g., `'0.05'` for 0.05 USDC or 0.05 ETH). |
| chain | Blockchain | **Deprecated.** Use SwapEstimate.chainIn instead. Still populated with the source chain for a deprecation window; will be removed in a future major release. |
| chainIn | Blockchain | The source chain of the swap.<br /><br /> Returns the chain name (e.g. `Blockchain.Ethereum`). Use `getChainByEnum(chainIn)` to resolve back to a full `ChainDefinition`. |
| chainOut | Blockchain | Destination chain of the swap.<br /><br /> Equal to `chainIn` for same-chain estimates; different for crosschain estimates. Always populated. |
| estimatedOutput | TokenAmount | Estimated output amount with token information. |
| fees | readonly ServiceSwapFee\[] | Detailed fee breakdown for the swap operation. |
| fromAddress | string | The address that will initiate the swap. |
| stopLimit | TokenAmount | Estimated minimum token out amount with token information.<br /><br /> This represents the minimum amount of tokens the user should receive after accounting for slippage. Amount is in human-readable decimal format. |
| toAddress | string | The address that will receive the swapped tokens. |
| tokenIn | SupportedSwapToken | The input token that will be swapped from. |
| tokenOut | SupportedSwapToken | The output token that will be swapped to. |

**Usage Example**

```typescript theme={null}
const estimate = await kit.estimateSwap({
  from: { adapter, chain: "Ethereum" },
  tokenIn: "USDC",
  tokenOut: "USDT",
  amountIn: "100.50",
  config: {
    slippageBps: 300,
    apiKey: "TEST_API_KEY:id:secret",
  },
});

console.log("Stop limit:", estimate.stopLimit.amount, estimate.stopLimit.token);
console.log(
  "Estimated output:",
  estimate.estimatedOutput.amount,
  estimate.estimatedOutput.token,
);
console.log("Fees:", estimate.fees);
```

***

### getSupportedChains(operationType)

Get chains supported by AppKit operations.

Returns blockchain networks that support specific stablecoin operations. When no
operation type is specified, returns all chains supporting any operation
(bridge, swap, earn, or unified balance).

```typescript theme={null}
getSupportedChains(operationType: 'bridge', options?: BridgeSupportedChainsOptions): ChainDefinition[]
getSupportedChains(operationType?: Exclude<OperationType, 'bridge'>): ChainDefinition[]
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| operationType | `'bridge'` | Optional operation type to filter chains (`bridge` \| `swap` \| `earn` \| `unifiedBalance`) |
| options | [`GetSupportedChainsOptions`](#getsupportedchainsoptions) | Optional Bridge Kit chain filters when `operationType` is `'bridge'`. |

#### GetSupportedChainsOptions

Options for filtering supported chains.

```typescript theme={null}
type GetSupportedChainsOptions =
  | {
      chainType: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported: boolean;
    };
```

**Properties**

| Name | Type | Description |
| - | - | - |
| forwarderSupported | `'source' \| 'destination'` | Filter chains by forwarder support. When set, only chains whose `gateway.forwarderSupported.source` or `gateway.forwarderSupported.destination` matches the specified value are returned.<br /><br /> - `undefined` (default) — no forwarder filtering; all supported chains are returned.<br />- `'source'` — only chains that support forwarding as a source.<br />- `'destination'` — only chains that support forwarding as a destination. |

**Returns**

`ChainDefinition[]`

**Usage Examples**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();
const allChains = kit.getSupportedChains();

console.log(`Total supported chains: ${allChains.length}`);
allChains.forEach((chain) => {
  console.log(`- ${chain.name} (${chain.type})`);
});
```

```typescript theme={null}
const kit = new AppKit();
const bridgeChains = kit.getSupportedChains("bridge");

console.log(
  "Chains supporting bridge:",
  bridgeChains.map((c) => c.name),
);
```

```typescript theme={null}
const kit = new AppKit();
const sourceFeeChains = kit.getSupportedChains("bridge", {
  sourceFeeSupported: true,
});
```

***

### getSwapStatus(params)

Fetch the current status of a swap from the Stablecoin Service.

Delegates to SwapKit.getSwapStatus. Performs a single HTTP request and returns
the service's snapshot of the swap's state. For crosschain swaps the status can
remain `'PENDING'` for several minutes while attestation and destination-chain
mint complete; callers are responsible for polling — re-calling this method with
a delay — until `progress.status` is terminal (`'DONE'`, `'FAILED'`, or
`'NOT_FOUND'`). Use AppKit.waitForSwap if you'd rather not write the polling
loop yourself.

```typescript theme={null}
getSwapStatus(params: GetSwapStatusParams): Promise<SwapStatusResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`GetSwapStatusParams`](#getswapstatusparams) | `txHash` and `chainIn`, plus optional `chainOut` and `apiKey`. |

#### GetSwapStatusParams

Parameters for SwapKit.getSwapStatus.

```typescript theme={null}
interface GetSwapStatusParams {
  txHash: string;
  chainIn: SwapChainIdentifier | Blockchain;
  chainOut?: SwapChainIdentifier | Blockchain;
  apiKey?: string | undefined;
  kitKey?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| apiKey | `string \| undefined` | Circle API key used as a bearer credential for the status request. Treat this value as a secret and do not log it.<br /><br /> Optional — when omitted, the request is made without an `Authorization` header (permissionless mode). |
| chainIn | `SwapChainIdentifier \| Blockchain` | Chain the swap was initiated on.<br /><br /> Accepts a Blockchain enum value, a string literal of the enum, or a full ChainDefinition (for convenience when piping through resolved parameters). |
| chainOut | `SwapChainIdentifier \| Blockchain` | Destination chain for crosschain swaps.<br /><br /> Must be supplied when the source and destination chains differ. Omit (or match `chainIn`) for same-chain swaps. |
| kitKey | string | **Deprecated.** Use GetSwapStatusParams.`apiKey` instead. Still honored when `apiKey` is omitted, and `apiKey` takes precedence when both are set. Circle API key used as a bearer credential for the status request. |
| txHash | string | The source-chain transaction hash returned by SwapKit.swap. |

**Returns**

[`Promise<SwapStatusResult>`](#swapstatusresult)

#### SwapStatusResult

Result of a swap status lookup — a single snapshot of the swap's state at the
time of the call.

```typescript theme={null}
interface SwapStatusResult {
  readonly progress: SwapProgress;
  readonly source?: SwapSourceLeg;
  readonly destination?: SwapDestinationLeg;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| destination | SwapDestinationLeg | Destination-leg transaction, token, and amount metadata. Omitted until the service reports destination-chain data (typically once the swap reaches `'DONE'`). The received amount lives under `destination.amount`. |
| progress | SwapProgress | Lifecycle snapshot: `status`, `substatus`, and `substatusMessage`. |
| source | SwapSourceLeg | Source-leg transaction and token metadata. `source.txHash` is populated from the service's `sendingTxHash`; `source.token` is shape-reserved pending service support. |

**Usage Examples**

````typescript theme={null}
Single snapshot:
```typescript
const result = await kit.swap(swapParams)

const status = await kit.getSwapStatus({
  txHash: result.txHash,
  chainIn: result.chainIn,
  chainOut: result.chainOut,
  apiKey: process.env.CIRCLE_API_KEY,
})

console.log(status.progress.status, status.progress.substatus)
````

````typescript theme={null}
Poll until terminal (or just call `kit.waitForSwap` instead):
```typescript
let status = await kit.getSwapStatus({
  txHash: result.txHash,
  chainIn: result.chainIn,
  chainOut: result.chainOut,
  apiKey: process.env.CIRCLE_API_KEY,
})
while (status.progress.status === 'PENDING') {
  await new Promise((r) => setTimeout(r, 3_000))
  status = await kit.getSwapStatus({
    txHash: result.txHash,
    chainIn: result.chainIn,
    chainOut: result.chainOut,
    apiKey: process.env.CIRCLE_API_KEY,
  })
}
````

***

### getTokenRates(params)

Fetch cached USD rates for one or more tokens from the Stablecoin Service.

Two lookup modes are supported:

* Per-chain dump: omit `tokens` to retrieve every rate cached for `chain`.
* Targeted lookup: supply `tokens` (up to 100) to retrieve a specific set of
  rates on `chain`. Each entry may be a registered token symbol (e.g. `'USDC'`,
  `'EURC'`), the literal `'NATIVE'`, the chain's native gas symbol (e.g. `'ETH'`
  on Ethereum), or a raw EVM address / Solana mint. Unknown strings are rejected
  with a `KitError`.

The rates pipeline is broader than the swap pipeline — `chain` accepts any
Blockchain value or ChainDefinition, not just the swap-supported subset. Chains
the cron does not track return an empty `rates` map.

Response keys preserve the service's canonical casing: EVM hex addresses are
lowercased, Solana base58 mints are case-preserved. Lowercase EVM addresses
before indexing into `result.rates[chain]`.

Native gas rates: `'NATIVE'` (or a chain's native currency symbol) translates to
the chain's native sentinel address — `0xEee…` for EVM, `1111…` for Solana —
before querying the service.

```typescript theme={null}
getTokenRates(params: GetTokenRatesParams): Promise<GetTokenRatesResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`GetTokenRatesParams`](#gettokenratesparams) | `chain`, plus optional `tokens` and `apiKey`. |

#### GetTokenRatesParams

Parameters for SwapKit.getTokenRates.

```typescript theme={null}
interface GetTokenRatesParams {
  chain: ChainIdentifier;
  tokens?: readonly TokenSymbol[];
  apiKey?: string | undefined;
  kitKey?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| apiKey | `string \| undefined` | Circle API key used as a bearer credential for the rates request. Treat this value as a secret and do not log it.<br /><br /> Optional — when omitted, the request is made without an `Authorization` header (permissionless mode). |
| chain | ChainIdentifier | Chain to look up rates for. Accepts a Blockchain enum value, a string literal of the enum, or a full ChainDefinition. |
| kitKey | string | **Deprecated.** Use GetTokenRatesParams.`apiKey` instead. Still honored when `apiKey` is omitted, and `apiKey` takes precedence when both are set. Circle API key used as a bearer credential for the rates request. |
| tokens | readonly TokenSymbol\[] | Optional list of tokens (max 100) to look up on `chain`. Each entry may be:<br /><br /> - A registered TokenSymbol (e.g. `'USDC'`, `'EURC'`). The kit resolves it to the chain's address via the built-in `TokenRegistry`. Symbol matching is case-insensitive.<br />- The literal `'NATIVE'`, or the chain's native gas symbol (e.g. `'ETH'` on Ethereum, `'POL'` on Polygon). Both translate to the chain's native sentinel address — `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` for EVM, `11111111111111111111111111111111` for Solana — before querying the service.<br />- A raw on-chain address (EVM `0x` hex) or mint (Solana base58), passed through verbatim (EVM lowercased to match service response casing).<br /><br /> Omit the field to get every cached rate for the chain.<br /><br /> Unknown strings that are neither a registered symbol nor a well-formed address are rejected with a `KitError` to surface typos at the call site instead of returning a silently empty rate map. |

**Returns**

`Promise<GetTokenRatesResponse>`

**Usage Example**

```typescript theme={null}
const { rates } = await kit.getTokenRates({
  chain: "Ethereum",
  tokens: ["USDC", "EURC"],
  apiKey: process.env.CIRCLE_API_KEY,
});

const usdc = rates["Ethereum"]?.["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"];
console.log(`USDC: $${usdc?.priceUSD ?? "unknown"}`);
```

***

### off(action)

Unregister an event handler for a specific AppKit action.

This method removes a previously registered event handler. You must pass the
exact same handler function reference that was used during registration. Use the
wildcard `*` to remove handlers listening to all actions.

```typescript theme={null}
off<K extends AppKitActionName>(action: K, handler: (payload: AppKitActions[K]) => void): void
off(action: '*', handler: (payload: AppKitActions[keyof AppKitActions]) => void): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| action | `K` | The namespaced action name or `*` for all actions |
| handler | `(payload: unknown) => void` | The handler function to remove (must be the same reference) |

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();

// Define handler
const handler = (payload) => {
  console.log("Approval:", payload);
};

// Register
kit.on("bridge.approve", handler);

// Later, unregister
kit.off("bridge.approve", handler);
```

***

### on(action)

Register an event handler for a specific AppKit action.

Subscribe to step events from bridge, earn, borrow, or unified balance
operations. Action names are namespaced: `bridge.`, `earn.`, `borrow.`, and
`unifiedBalance.`. Use `'*'` to receive every action.

Handlers receive strongly-typed payloads for the chosen action. Multiple
handlers may be registered for the same action.

```typescript theme={null}
on<K extends AppKitActionName>(action: K, handler: (payload: AppKitActions[K]) => void): void
on(action: '*', handler: (payload: AppKitActions[keyof AppKitActions]) => void): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| action | `K` | The namespaced action name or `*` for all actions |
| handler | `(payload: unknown) => void` | Callback invoked when the action occurs |

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();

// Listen to specific bridge action
kit.on("bridge.approve", (payload) => {
  console.log("Approval transaction:", payload.values.txHash);
});

// Listen to earn deposit steps
kit.on("earn.deposit", (payload) => {
  console.log("Earn deposit step:", payload.values.state);
});

// Listen to unified balance action
kit.on("unifiedBalance.gateway.spend.succeeded", (payload) => {
  console.log("Spend succeeded:", payload.data);
});

// Listen to all actions
kit.on("*", (payload) => {
  console.log("Action:", payload);
});
```

***

### removeCustomFeePolicy(operation)

Remove an AppKit-level custom fee policy for one operation.

Bridge and swap policies are removed from AppKit's persistent context so future
operations fall back to legacy fee hooks. Unified balance policies are also
removed from the namespaced Unified Balance Kit.

```typescript theme={null}
removeCustomFeePolicy(operation: AppKitCustomFeePolicyScope): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| operation | `unknown` | Operation whose custom fee policy should be removed. |

**Usage Example**

```typescript theme={null}
kit.removeCustomFeePolicy("bridge");
```

***

### retryBridge(result)

Retry a failed crosschain USDC bridge transfer.

Resume a bridge operation that failed due to a transient error. Use
isRetryableError to check whether a failed step's error is eligible for retry
before calling this method.

```typescript theme={null}
retryBridge<TToken extends string = string>(result: BridgeResult<TToken>, retryContext: RetryContext): Promise<BridgeResult<TToken>>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| result | [`BridgeResult`](#bridgeresult) | The bridge result from the failed operation |
| retryContext | [`RetryContext`](#retrycontext) | The retry context with source and optional destination adapters |

#### BridgeResult

Result object returned after a successful crosschain bridge operation.

This interface contains all the details about a completed bridge, including the
bridge parameters, source and destination information, and the sequence of steps
that were executed.

```typescript theme={null}
interface BridgeResult {
  amount: string
  config?: BridgeConfig
  destination: { address: string; chain: ChainDefinition; recipientAddress?: string; useForwarder?: boolean }
  provider: string
  source: { address: string; chain: ChainDefinition }
  state: 'pending' \| 'success' \| 'error'
  steps: BridgeStep[]
  token: TToken
  warnings?: BridgeWarning[]
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount that was transferred (as a string to avoid precision issues) |
| config | BridgeConfig | The bridge configuration that was used for this operation |
| destination | `{ address: string; chain: ChainDefinition; recipientAddress?: string; useForwarder?: boolean }` | Information about the destination chain and address |
| provider | string | The provider that was used for this operation |
| source | `{ address: string; chain: ChainDefinition }` | Information about the source chain and address |
| state | `'pending' \| 'success' \| 'error'` | The state of the transfer |
| steps | BridgeStep\[] | Array of steps that were executed during the bridge process |
| token | TToken | The token that was transferred. |
| warnings | BridgeWarning\[] | Non-fatal advisories surfaced during the bridge (e.g. a FAST→SLOW speed downgrade). Optional and additive — providers populate it when relevant and leave it undefined otherwise. See BridgeWarning. |

#### RetryContext

Context for retry operations containing source and destination adapter contexts.

This interface provides the necessary context for retry operations, including
both the source adapter context (where the retry originates) and the destination
adapter context (where the retry is targeted). This ensures that retry
operations have access to both the source and destination chain information
needed for validation and execution.

The destination adapter (`to`) is optional to support forwarder-only
destinations where Circle's Orbit relayer handles the mint transaction without
requiring a destination adapter. When `to` is undefined, the retry operation
relies on IRIS API confirmation instead of on-chain transaction confirmation.

```typescript theme={null}
interface RetryContext {
  from: Adapter<TFromAdapterCapabilities>;
  to?: Adapter<TToAdapterCapabilities>;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| from | `Adapter` | The source adapter context for the retry operation |
| to | `Adapter` | The destination adapter context for the retry operation.<br /><br /> Optional for forwarder-only destinations where Circle's Orbit relayer handles the mint transaction. When undefined, the retry operation relies on IRIS API confirmation (`forwardState === 'CONFIRMED'`) instead of on-chain transaction confirmation via the adapter. |

**Returns**

`Promise<BridgeResult<TToken>>`

**Usage Example**

```typescript theme={null}
import { AppKit, isRetryableError } from "@circle-fin/app-kit";

const kit = new AppKit();

const result = await kit.bridge({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: { adapter: destAdapter, chain: "Polygon" },
  amount: "100.50",
});

const failedStep = result.steps.find((s) => s.error);
if (
  result.state === "error" &&
  failedStep?.error &&
  isRetryableError(failedStep.error)
) {
  const retried = await kit.retryBridge(result, {
    from: sourceAdapter,
    to: destAdapter,
  });
  console.log("Retry result:", retried.state);
}
```

***

### send(params)

Execute a send operation for known token aliases (USDC, USDT, NATIVE) or custom
ERC-20/SPL tokens. For custom tokens, the token address must be provided.

This method handles the complete send transfer flow using the underlying AppKit
infrastructure. It supports sending to either a destination adapter or an
explicit recipient address, with full type safety and comprehensive error
handling.

```typescript theme={null}
send(params: SendParams): Promise<BridgeStep>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SendParams`](#sendparams-2) | Send parameters containing source, destination, amount, and token |

#### SendParams

Parameters for sending USDC, USDT, native tokens, or custom ERC-20/SPL tokens.

This interface is the canonical input for send operations in App Kit. It
supports sending to either a destination Adapter (recipient derives from the
adapter's default account) or an explicit recipient `string` address.

* The `from` field provides the source signing context and chain.
* The `to` field identifies the destination as an adapter or an explicit
  address.
* The `amount` field is a human-readable decimal string (for example, `'10.5'`).
* The `token` field selects the asset to move and defaults to `'USDC'`.

```typescript theme={null}
interface SendParams {
  amount: string
  from: AdapterContext
  to: string \| Adapter<AdapterCapabilities>
  token?: TokenAlias \| TokenAddress
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount to transfer. |
| from | AdapterContext | The source adapter context (wallet and chain) for the transfer. |
| to | `string \| Adapter` | The destination for the transfer, supporting explicit or derived recipient addresses. |
| token | `TokenAlias \| TokenAddress` | The token to transfer. Defaults to `USDC`. If omitted, the provider will use `USDC` by default.<br /><br /> Supports both known aliases and custom token contract addresses:<br />- Known aliases: `USDC`, `USDT`, `NATIVE`, `EURC` (`EURC` requires the chain to have an `eurcAddress` configured)<br />- Custom token addresses: EVM addresses or Solana SPL token mint addresses |

**Returns**

[`Promise<BridgeStep>`](#bridgestep)

#### BridgeStep

A step in the bridge process.

```typescript theme={null}
interface BridgeStep {
  batched?: boolean
  batchId?: string
  data?: unknown
  error?: unknown
  errorCategory?: BridgeStepErrorCategory
  errorMessage?: string
  explorerUrl?: string
  forwarded?: boolean
  name: string
  state: 'pending' \| 'success' \| 'error' \| 'noop'
  txHash?: string
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| batched | boolean | Whether this step was executed as part of an EIP-5792 batched `wallet_sendCalls` request.<br /><br /> - `true`: The step was included in a batched call bundle<br />- `undefined`: The step was executed individually (sequential flow) |
| batchId | string | The wallet-assigned batch identifier from `wallet_sendCalls`.<br /><br /> Present only when batched is `true`. Can be used with `wallet_getCallsStatus` to query the status of the entire bundle. |
| data | unknown | Optional data for the step |
| error | unknown | Optional raw error object (can be Viem/Ethers/Chain error) |
| errorCategory | BridgeStepErrorCategory | Optional machine-readable classification of the error.<br /><br /> Present when the step is in `state: 'error'` and the SDK was able to categorize the failure. See BridgeStepErrorCategory for the list of categories and how they map to underlying error shapes. |
| errorMessage | string | Optional human-readable error message |
| explorerUrl | string | Optional explorer URL for viewing this transaction on a block explorer |
| forwarded | boolean | Whether this step was executed via Circle's Forwarder (relay service). Only applicable for mint steps.<br /><br /> - `true`: The mint was handled by Circle's Orbit relayer<br />- `false`: The user submitted the mint transaction directly<br />- `undefined`: Not applicable (non-mint steps) |
| name | string | Human-readable name of the step (e.g., "Approve", "Burn", "Mint") |
| state | `'pending' \| 'success' \| 'error' \| 'noop'` | The state of the step |
| txHash | string | Optional transaction hash for this step (if applicable) |

**Usage Examples**

```typescript theme={null}
// Send USDC to a recipient adapter (same chain)
const result = await kit.send({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: recipientAdapter,
  amount: "100.50",
  token: "USDC",
});

console.log("Send completed:", result.txHash);
```

```typescript theme={null}
// Send a custom token to an explicit address
const result = await kit.send({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: "0x742d35Cc4634C0532925a3b8D1d7",
  amount: "100.50",
  token: "0x6B175474E89094C44Da98b954EedeAC495271d0F", // DAI on Ethereum
});
console.log("Send completed:", result.txHash);
```

```typescript theme={null}
// Send USDT to an explicit address
const result = await kit.send({
  from: { adapter: sourceAdapter, chain: "Ethereum" },
  to: "0x742d35Cc4634C0532925a3b8D1d7",
  amount: "50.25",
  token: "USDT",
});

console.log("Send completed:", result.txHash);
```

***

### setCustomFeePolicy(policy)

Set operation-scoped custom fee policies.

Configure custom fees for only the operations that need them. Bridge and swap
policies are forwarded to the underlying kits when those operations run. Unified
balance policies are applied immediately to the namespaced Unified Balance Kit.

```typescript theme={null}
setCustomFeePolicy(policy: AppKitCustomFeePolicy): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| policy | [`AppKitCustomFeePolicy`](#appkitcustomfeepolicy) | Partial custom fee policy grouped by operation. |

#### AppKitCustomFeePolicy

Operation-scoped custom fee policies configured at the AppKit level.

Each property is optional so consumers can enable custom fees only for the
operation they use. AppKit forwards the supplied policy to the matching
underlying kit when that operation runs.

```typescript theme={null}
interface AppKitCustomFeePolicy {
  bridge?: CustomFeePolicy;
  swap?: CustomFeePolicy;
  unifiedBalance?: CustomFeePolicy;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| bridge | CustomFeePolicy | Custom fee policy forwarded to BridgeKit bridge operations. |
| swap | CustomFeePolicy | Custom fee policy forwarded to SwapKit swap operations. |
| unifiedBalance | CustomFeePolicy | Custom fee policy forwarded to UnifiedBalanceKit spend operations. |

**Usage Example**

```typescript theme={null}
kit.setCustomFeePolicy({
  bridge: {
    computeFee: () => "1.00",
    resolveFeeRecipientAddress: () =>
      "0x1234567890123456789012345678901234567890",
  },
});
```

***

### swap(params)

Execute a same-chain token swap operation.

Swaps between USDC, USDT, and native tokens on the same blockchain with
configurable slippage tolerance and allowance strategies.

```typescript theme={null}
swap(params: SwapParams): Promise<SwapResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SwapParams`](#swapparams-2) | Swap parameters containing source, tokens, amount, and config |

#### SwapParams

```typescript theme={null}
interface SwapParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  from: SwapAdapterContext<TFromAdapterCapabilities>;
  tokenIn: SupportedSwapToken;
  tokenOut: SupportedSwapToken;
  amountIn: string;
  to?: SwapDestination;
  config?: SwapConfig;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amountIn | string | The amount of the input token to swap.<br /><br /> Expressed as a human-readable decimal string in token units (e.g., `'0.05'` for 0.05 USDC or 0.05 ETH). |
| config | SwapConfig | Optional configuration for swap behavior.<br /><br /> If omitted, defaults will be used:<br />- `allowanceStrategy`: `permit` (fallback to `approve`)<br />- `slippageBps`: 300 (3%) |
| from | `SwapAdapterContext` | The source adapter context (wallet and chain) for the swap. |
| to | SwapDestination | Optional destination chain/address.<br /><br /> For same-chain swaps this may be omitted and the source wallet address is used as the recipient. crosschain swaps require `recipientAddress`. |
| tokenIn | SupportedSwapToken | The input token to swap from.<br /><br /> Supports stablecoins (USDC, USDT, EURC, USDe, DAI, PYUSD), wrapped tokens (WBTC, WETH, WSOL, WAVAX, WPOL), and native tokens (NATIVE or chain-specific symbols). |
| tokenOut | SupportedSwapToken | The output token to swap to.<br /><br /> Supports stablecoins (USDC, USDT, EURC, USDe, DAI, PYUSD), wrapped tokens (WBTC, WETH, WSOL, WAVAX, WPOL), and native tokens (NATIVE or chain-specific symbols). |

**Returns**

[`Promise<SwapResult>`](#swapresult)

#### SwapResult

Result of an executed swap operation.

Captures the source-chain execution outcome for a swap transaction.

```typescript theme={null}
interface SwapResult {
  readonly tokenIn: SupportedSwapToken;
  readonly tokenOut: SupportedSwapToken;
  readonly chainIn: Blockchain;
  readonly chainOut: Blockchain;
  readonly chain: Blockchain;
  readonly amountIn: string;
  readonly fromAddress: string;
  readonly toAddress: string;
  readonly config?: SwapResultConfig;
  readonly txHash: string;
  readonly explorerUrl?: string;
  fees?: readonly ServiceSwapFee[];
  readonly progress: SwapProgress;
  readonly amountOut?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amountIn | string | The input amount that was swapped, as a human-readable decimal string in token units (e.g. `'0.05'` for 0.05 USDC or 0.05 ETH). |
| amountOut | string | Output amount when `.swap()` can confirm the result inline.<br /><br /> Expressed as a human-readable decimal string in output-token units (run through the output-token transform), never base units.<br /><br /> Populated for same-chain swaps when the best-effort status peek reaches `DONE`. Undefined for crosschain swaps; call SwapKit.getSwapStatus to retrieve destination-leg details. |
| chain | Blockchain | **Deprecated.** Use SwapResult.chainIn instead. Still populated with the source chain for a deprecation window; will be removed in a future major release. |
| chainIn | Blockchain | The source chain of the swap.<br /><br /> Returns the chain name (e.g. `Blockchain.Ethereum`). Use `getChainByEnum(chainIn)` to resolve back to a full `ChainDefinition`. |
| chainOut | Blockchain | Destination chain of the swap.<br /><br /> Equal to `chainIn` for same-chain swaps; different for crosschain swaps. Always populated so consumers don't have to fall back to `chainIn` when the destination is implicit. |
| config | SwapResultConfig | The swap configuration that was used for this operation. |
| explorerUrl | string | The formatted explorer URL for the source-chain transaction. Only present when `txHash` is non-empty. |
| fees | readonly ServiceSwapFee\[] | Detailed fee breakdown for the swap operation. Includes both provider fees (charged by the DEX aggregator/protocol) and kit fees. |
| fromAddress | string | The address that initiated the swap. |
| progress | SwapProgress | Lifecycle snapshot: `status`, `substatus`, and `substatusMessage`.<br /><br /> `status` is `'DONE'` when the swap completed end-to-end (same-chain only), `'PENDING'` while the destination leg is still in-flight, or a terminal failure value (`'FAILED'` / `'NOT_FOUND'`). |
| toAddress | string | The address that received the swapped tokens. |
| tokenIn | SupportedSwapToken | The input token that was swapped from. |
| tokenOut | SupportedSwapToken | The output token that was swapped to. |
| txHash | string | The source-chain transaction hash for the executed swap. |

**Usage Example**

```typescript theme={null}
const result = await kit.swap({
  from: { adapter, chain: "Ethereum" },
  tokenIn: "USDC",
  tokenOut: "USDT",
  amountIn: "100.50",
  config: {
    slippageBps: 300, // 3% slippage
    allowanceStrategy: "permit",
    apiKey: "TEST_API_KEY:id:secret",
  },
});

console.log("Swap completed:", result.txHash);
```

***

### waitForSwap(params)

Poll the Stablecoin Service until a swap reaches a terminal status (`'DONE'`,
`'FAILED'`, `'NOT_FOUND'`) or `timeoutMs` elapses.

Delegates to SwapKit.waitForSwap. Use this after `kit.swap()` to collapse the
`while (status === 'PENDING')` polling loop into a single awaitable. Same-chain
swaps return on the first poll because they are already terminal at `swap` time;
crosschain swaps follow an escalating backoff (3s → 6s → 12s → 24s → 24s) until
the wait budget expires. Timeouts surface as a RETRYABLE `KitError` so callers
can re-invoke with the same `txHash`.

```typescript theme={null}
waitForSwap(params: WaitForSwapParams): Promise<SwapStatusResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`WaitForSwapParams`](#waitforswapparams) | Wait configuration: identifiers, API key, and optional `timeoutMs` / `onProgress`. |

#### WaitForSwapParams

Parameters for SwapKit.waitForSwap.

```typescript theme={null}
type WaitForSwapParams = WaitForSwapResultParams | WaitForSwapDiscreteParams;
```

**Returns**

[`Promise<SwapStatusResult>`](#swapstatusresult-2)

#### SwapStatusResult

Result of a swap status lookup — a single snapshot of the swap's state at the
time of the call.

```typescript theme={null}
interface SwapStatusResult {
  readonly progress: SwapProgress;
  readonly source?: SwapSourceLeg;
  readonly destination?: SwapDestinationLeg;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| destination | SwapDestinationLeg | Destination-leg transaction, token, and amount metadata. Omitted until the service reports destination-chain data (typically once the swap reaches `'DONE'`). The received amount lives under `destination.amount`. |
| progress | SwapProgress | Lifecycle snapshot: `status`, `substatus`, and `substatusMessage`. |
| source | SwapSourceLeg | Source-leg transaction and token metadata. `source.txHash` is populated from the service's `sendingTxHash`; `source.token` is shape-reserved pending service support. |

#### WaitForSwapResultParams

`waitForSwap` parameter shape that pipes a SwapResult straight through — the
most ergonomic form when you've just called SwapKit.swap or SwapKit.executeSwap.

```typescript theme={null}
interface WaitForSwapResultParams extends WaitForSwapCommonParams {
  readonly result: SwapResult;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| apiKey | string | Circle API key used as a bearer credential. Treat as a secret and do not log it.<br /><br /> Optional — when omitted, the request is made without an `Authorization` header (permissionless mode). |
| kitKey | string | **Deprecated.** Use `apiKey` instead. Still honored when `apiKey` is omitted, and `apiKey` takes precedence when both are set. Circle API key used as a bearer credential. |
| onProgress | (status: SwapStatusResult) => void | Fired on every poll that produces a status snapshot. Useful for surfacing `substatus` transitions to a UI (e.g. spinner copy, log lines). Not called on retried 429/5xx responses. |
| result | SwapResult | The SwapResult returned by SwapKit.swap or SwapKit.executeSwap. `txHash`, `chainIn`, and `chainOut` are read directly from this object. |
| timeoutMs | number | Overall wait budget, in milliseconds. The promise rejects with a RETRYABLE KitError when this elapses without a terminal status. crosschain swaps typically settle within 30s–3min; pad the budget if production traffic shows occasional outliers.<br /><br /> Default: `300_000` (5 minutes). |

#### WaitForSwapDiscreteParams

`waitForSwap` parameter shape for callers that don't have a SwapResult on hand —
e.g. picking up an in-flight swap from a persisted record or a copy-pasted tx
hash.

```typescript theme={null}
interface WaitForSwapDiscreteParams extends WaitForSwapCommonParams {
  readonly txHash: string;
  readonly chainIn: SwapChainIdentifier | Blockchain;
  readonly chainOut?: SwapChainIdentifier | Blockchain;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| apiKey | string | Circle API key used as a bearer credential. Treat as a secret and do not log it.<br /><br /> Optional — when omitted, the request is made without an `Authorization` header (permissionless mode). |
| chainIn | `SwapChainIdentifier \| Blockchain` | Chain the swap was initiated on. Accepts a Blockchain enum value, a string literal of the enum, or a full ChainDefinition. |
| chainOut | `SwapChainIdentifier \| Blockchain` | Destination chain for crosschain swaps. Omit (or match `chainIn`) for same-chain swaps. |
| kitKey | string | **Deprecated.** Use `apiKey` instead. Still honored when `apiKey` is omitted, and `apiKey` takes precedence when both are set. Circle API key used as a bearer credential. |
| onProgress | (status: SwapStatusResult) => void | Fired on every poll that produces a status snapshot. Useful for surfacing `substatus` transitions to a UI (e.g. spinner copy, log lines). Not called on retried 429/5xx responses. |
| timeoutMs | number | Overall wait budget, in milliseconds. The promise rejects with a RETRYABLE KitError when this elapses without a terminal status. crosschain swaps typically settle within 30s–3min; pad the budget if production traffic shows occasional outliers.<br /><br /> Default: `300_000` (5 minutes). |
| txHash | string | The source-chain transaction hash returned by SwapKit.swap or SwapKit.executeSwap. |

**Usage Examples**

````typescript theme={null}
Pipe a `SwapResult` straight in — the common case:
```typescript
const result = await kit.swap(swapParams)

const final = await kit.waitForSwap({
  result,
  apiKey: process.env.CIRCLE_API_KEY,
  onProgress: (snap) => console.log(snap.progress.status),
})

if (final.progress.status === 'DONE') {
  console.log(`Received ${final.destination?.amount}`)
}
````

````typescript theme={null}
Resume from a persisted tx hash (no `SwapResult` on hand):
```typescript
const final = await kit.waitForSwap({
  txHash: persisted.txHash,
  chainIn: persisted.chainIn,
  chainOut: persisted.chainOut,
  apiKey: process.env.CIRCLE_API_KEY,
})
````

***

## kit.unifiedBalance Methods

`unifiedBalance` is a property on every `AppKit` instance. Call these methods as
`kit.unifiedBalance.methodName()`.

### addDelegate(params)

Grant spending rights to another address on the owner's account.

```typescript theme={null}
addDelegate(params: UpdateDelegateParams): Promise<UpdateDelegateResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`UpdateDelegateParams`](#updatedelegateparams) | The owner's adapter context and the delegate address. |

#### UpdateDelegateParams

Parameters for adding or removing a delegate on a Gateway account.

```typescript theme={null}
interface UpdateDelegateParams {
  delegateAddress: string;
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  token?: SupportedTokenInput;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| delegateAddress | string | The address being added or removed as an authorized delegate. |
| from | `AdapterContext` | The owner's adapter context identifying the account and chain to which the delegate will be authorized. |
| token | SupportedTokenInput | The token for which delegation applies. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<UpdateDelegateResult>`](#updatedelegateresult)

#### UpdateDelegateResult

Result returned after a successful add or remove delegate operation.

```typescript theme={null}
interface UpdateDelegateResult {
  account: string
  chain: Blockchain
  delegateAddress: string
  explorerUrl?: string
  state: 'added' \| 'removed'
  txHash: string
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| account | string | The Gateway account that was modified. |
| chain | Blockchain | The chain on which the delegate was updated. |
| delegateAddress | string | The delegate address that was added or removed. |
| explorerUrl | string | Link to view the transaction details on the appropriate blockchain explorer. |
| state | `'added' \| 'removed'` | Whether the delegate was added or removed. |
| txHash | string | Unique identifier returned by the blockchain once the transaction is mined. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.addDelegate({
  from: { adapter, chain: "Ethereum" },
  delegateAddress: "0xDelegate…",
});
```

***

### deposit(params)

Deposit USDC into the caller's account on a specific chain.

```typescript theme={null}
deposit(params: DepositParams): Promise<DepositResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`DepositParams`](#depositparams) | Deposit details including the depositor context and amount. |

#### DepositParams

Parameters for depositing tokens into the caller's own Gateway account on a
specific chain.

```typescript theme={null}
interface DepositParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends BridgeChainIdentifier = BridgeChainIdentifier,
> {
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  amount: string;
  token?: SupportedTokenInput;
  allowanceStrategy?: AllowanceStrategy;
  to?: {
    chain: UnifiedBalanceChainIdentifier;
  };
  config?: DepositConfig;
  quote?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allowanceStrategy | AllowanceStrategy | The token allowance strategy to authorize the deposit.<br /><br /> Only valid for same-chain (STANDARD) deposits. Must not be set when `config.transferSpeed` is `'FAST'` (FAST crosschain deposits do not use an allowance strategy). |
| amount | string | The amount of tokens to deposit (human-readable decimal string). |
| config | DepositConfig | Transfer configuration for the deposit. |
| from | `AdapterContext` | The adapter context identifying the depositor and chain. |
| quote | string | Opaque signed fee-quote bytes from the Quote API.<br /><br /> Pass this to commit to the fee price returned by a previous estimateDeposit call (see EstimateDepositResult.quote). When omitted a fresh quote is fetched automatically (FAST path only). |
| to | `{ chain: UnifiedBalanceChainIdentifier; }` | Destination chain for a FAST crosschain deposit.<br /><br /> When set, the deposit follows the prepaid-FORWARD CCTP v2 path: the burned USDC is minted to the GenericExecutor on the destination chain, which then calls Gateway `deposit` in a single relayed flow.<br /><br /> Must not be set when `config.transferSpeed` is `'STANDARD'`. |
| token | SupportedTokenInput | The token to deposit. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalized to uppercase internally. |

**Returns**

[`Promise<DepositResult>`](#depositresult)

#### DepositResult

Result returned after a successful deposit operation.

```typescript theme={null}
interface DepositResult {
  amount: string;
  token: SupportedToken;
  depositedTo: string;
  depositedBy: string;
  chain: Blockchain;
  txHash: string;
  explorerUrl?: string;
  sourceChain?: Blockchain;
  destinationChain?: Blockchain;
  fees?: FeeEntry[];
  progress?: DepositProgress;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The deposited amount (human-readable decimal string). |
| chain | Blockchain | The chain where the deposit balance lands. |
| depositedBy | string | The address that signed and funded the deposit. |
| depositedTo | string | The Gateway account address credited by the deposit. |
| destinationChain | Blockchain | Destination chain of the crosschain deposit (FAST path only).<br /><br /> Present for every FAST deposit. When `to` was omitted this is the default destination (`Arc` or `Arc_Testnet`). |
| explorerUrl | string | Link to view the transaction on a block explorer. |
| fees | FeeEntry\[] | Itemised fee breakdown for the crosschain deposit (FAST path only).<br /><br /> Contains at least a `gasFee` entry and a `forwarder` entry (Circle FORWARD fee). The `gasFee` covers the source-chain burn gas; when a `usdc.approve` was required it also includes the actual on-chain approve gas derived from the transaction receipt. |
| progress | DepositProgress | Relay progress after the source-chain burn (FAST path only).<br /><br /> Present on every FAST deposit result. Use this to determine whether the destination-chain mint completed within the \~60-second relay window. |
| sourceChain | Blockchain | Source chain of the crosschain deposit (FAST path only).<br /><br /> Present for every FAST deposit, including those where `to` was omitted and defaulted to Arc. |
| token | SupportedToken | The token that was deposited. |
| txHash | string | Transaction hash of the completed deposit. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.deposit({
  from: { adapter, chain: "Ethereum" },
  amount: "100",
  token: "USDC",
});
```

***

### depositFor(params)

Deposit USDC into another account (not the caller's).

```typescript theme={null}
depositFor(params: DepositForParams): Promise<DepositResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`DepositForParams`](#depositforparams) | Deposit details including the depositor context, amount, and the account address to credit. |

#### DepositForParams

Parameters for depositing tokens into another Gateway account.

```typescript theme={null}
interface DepositForParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends BridgeChainIdentifier = BridgeChainIdentifier,
> extends Omit<
  DepositParams<TAdapterCapabilities, TChainIdentifier>,
  "allowanceStrategy"
> {
  depositAccount: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount of tokens to deposit (human-readable decimal string). |
| config | DepositConfig | Transfer configuration for the deposit. |
| depositAccount | string | The Gateway account address to credit with the deposit.<br /><br /> When provided the deposit is credited to this account rather than the caller's own. |
| from | `AdapterContext` | The adapter context identifying the depositor and chain. |
| quote | string | Opaque signed fee-quote bytes from the Quote API.<br /><br /> Pass this to commit to the fee price returned by a previous estimateDeposit call (see EstimateDepositResult.quote). When omitted a fresh quote is fetched automatically (FAST path only). |
| to | `{ chain: UnifiedBalanceChainIdentifier }` | Destination chain for a FAST crosschain deposit.<br /><br /> When set, the deposit follows the prepaid-FORWARD CCTP v2 path: the burned USDC is minted to the GenericExecutor on the destination chain, which then calls Gateway `deposit` in a single relayed flow.<br /><br /> Must not be set when `config.transferSpeed` is `'STANDARD'`. |
| token | SupportedTokenInput | The token to deposit. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalized to uppercase internally. |

**Returns**

[`Promise<DepositResult>`](#depositresult-2)

#### DepositResult

Result returned after a successful deposit operation.

```typescript theme={null}
interface DepositResult {
  amount: string;
  token: SupportedToken;
  depositedTo: string;
  depositedBy: string;
  chain: Blockchain;
  txHash: string;
  explorerUrl?: string;
  sourceChain?: Blockchain;
  destinationChain?: Blockchain;
  fees?: FeeEntry[];
  progress?: DepositProgress;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The deposited amount (human-readable decimal string). |
| chain | Blockchain | The chain where the deposit balance lands. |
| depositedBy | string | The address that signed and funded the deposit. |
| depositedTo | string | The Gateway account address credited by the deposit. |
| destinationChain | Blockchain | Destination chain of the crosschain deposit (FAST path only).<br /><br /> Present for every FAST deposit. When `to` was omitted this is the default destination (`Arc` or `Arc_Testnet`). |
| explorerUrl | string | Link to view the transaction on a block explorer. |
| fees | FeeEntry\[] | Itemised fee breakdown for the crosschain deposit (FAST path only).<br /><br /> Contains at least a `gasFee` entry and a `forwarder` entry (Circle FORWARD fee). The `gasFee` covers the source-chain burn gas; when a `usdc.approve` was required it also includes the actual on-chain approve gas derived from the transaction receipt. |
| progress | DepositProgress | Relay progress after the source-chain burn (FAST path only).<br /><br /> Present on every FAST deposit result. Use this to determine whether the destination-chain mint completed within the \~60-second relay window. |
| sourceChain | Blockchain | Source chain of the crosschain deposit (FAST path only).<br /><br /> Present for every FAST deposit, including those where `to` was omitted and defaulted to Arc. |
| token | SupportedToken | The token that was deposited. |
| txHash | string | Transaction hash of the completed deposit. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.depositFor({
  from: { adapter, chain: "Ethereum" },
  amount: "50",
  depositAccount: "0x742d35Cc6634C0532925a3b844D97D35e2B60E53",
});
```

***

### estimateDeposit(params)

Estimate fees for a crosschain deposit without executing it.

Returns plain, serializable data that can be spread directly into
UnifiedBalanceKit.deposit or UnifiedBalanceKit.depositFor:

`typescript const estimate = await kit.estimateDeposit({ from, amount, to }) const result = await kit.deposit({ ...estimate, from })`

```typescript theme={null}
estimateDeposit(params: EstimateDepositParams): Promise<EstimateDepositResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`EstimateDepositParams`](#estimatedepositparams) | Estimate details including the depositor context, amount, destination chain (defaults to Arc / Arc\_Testnet for FAST), and optional transfer speed. |

#### EstimateDepositParams

Parameters for estimating the fees of a fast crosschain deposit.

The result is plain, serializable data — no live adapter reference is included.
Pass the result (plus `from`) directly to DepositParams or DepositForParams for
execution:

`typescript const estimate = await kit.estimateDeposit({ from, amount, token, to }) const result = await kit.deposit({ ...estimate, from })`

```typescript theme={null}
interface EstimateDepositParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends BridgeChainIdentifier = BridgeChainIdentifier,
> {
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  amount: string;
  token?: SupportedTokenInput;
  to?: {
    chain: UnifiedBalanceChainIdentifier;
  };
  config?: DepositConfig;
  depositAccount?: string;
  allowanceStrategy?: AllowanceStrategy;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allowanceStrategy | AllowanceStrategy | Allowance strategy echoed to the result for round-trip convenience. |
| amount | string | The amount of tokens to deposit (human-readable decimal string). |
| config | DepositConfig | Transfer configuration. |
| depositAccount | string | Gateway account address to credit (for a `depositFor` round-trip).<br /><br /> When provided, this value is echoed on the result so `kit.depositFor({ ...estimate, from })` works without re-specifying it. |
| from | `AdapterContext` | The adapter context identifying the depositor and source chain. The adapter is used for source-chain gas estimation. |
| to | `{ chain: UnifiedBalanceChainIdentifier; }` | Destination chain for a FAST crosschain deposit.<br /><br /> Must not be set when `config.transferSpeed` is `'STANDARD'` (the default). |
| token | SupportedTokenInput | The token to deposit. |

**Returns**

[`Promise<EstimateDepositResult>`](#estimatedepositresult)

#### EstimateDepositResult

Fee-preview result returned by `estimateDeposit`.

Plain, serializable data — no live adapter reference. Pass the result directly
to `deposit` or `depositFor` (re-attaching only `from`):

`typescript const estimate = await kit.estimateDeposit({ from, amount, token, to }) const result = await kit.deposit({ ...estimate, from })`

```typescript theme={null}
interface EstimateDepositResult {
  amount: string;
  token: SupportedToken;
  to?: {
    chain: UnifiedBalanceChainIdentifier;
  };
  config: Required<DepositConfig>;
  fees: FeeEntry[];
  quote?: string;
  depositAccount?: string;
  allowanceStrategy?: AllowanceStrategy;
  exchangeRates?: FeeQuoteExchangeRates;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allowanceStrategy | AllowanceStrategy | Allowance strategy (echoed from input for `deposit` round-trip). |
| amount | string | Deposit amount (human-readable decimal string). |
| config | `Required` | Transfer configuration (echoed with defaults applied). |
| depositAccount | string | Gateway account to credit (echoed from input for `depositFor` round-trip). |
| exchangeRates | FeeQuoteExchangeRates | Optional USD exchange-rate metadata from the Quote API.<br /><br /> Present when the Quote API returns exchange rates for the fee token and destination token. Non-binding; useful for USD-denominated display. |
| fees | FeeEntry\[] | Itemized fee breakdown.<br /><br /> Always contains at least a `gasFee` entry. For FAST transfers the gas cost includes the source-chain burn; when the current USDC allowance is insufficient it also includes the `usdc.approve` transaction. For STANDARD deposits on EVM with `allowanceStrategy: 'approve'`, or any `depositFor` on EVM, the gas cost includes both the `usdc.increaseAllowance` and the deposit transaction. A `forwarder` entry is always present for FAST crosschain transfers. |
| quote | string | Opaque signed fee-quote bytes from the Quote API.<br /><br /> Present for FAST crosschain deposits; absent for STANDARD or same-chain. Pass this to deposit or depositFor to commit to the quoted price. |
| to | `{ chain: UnifiedBalanceChainIdentifier; }` | Destination chain (echoed from input).<br /><br /> Present for FAST transfers; absent for STANDARD. |
| token | SupportedToken | Normalized token to deposit. |

#### FeeQuoteExchangeRates

USD exchange-rate metadata.

Non-binding, useful for USD-denominated fee estimates. `feeTokenUsd` prices the
source-chain fee token (the token `feeTotalAmount` is denominated in).

```typescript theme={null}
interface FeeQuoteExchangeRates {
  destinationTokenUsd: string;
  feeTokenUsd: string;
}
```

**Usage Example**

```typescript theme={null}
const estimate = await kit.unifiedBalance.estimateDeposit({
  from: { adapter, chain: "Ethereum" },
  amount: "100",
  to: { chain: "Polygon" },
  config: { transferSpeed: "FAST" },
});

const result = await kit.unifiedBalance.deposit({
  ...estimate,
  from: { adapter, chain: "Ethereum" },
});
```

***

### estimateSpend(params)

Estimate the fees for a spend operation without executing it.

```typescript theme={null}
estimateSpend(params: SpendParams): Promise<EstimateSpendResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SpendParams`](#spendparams) | The same spend parameters used in AppKitUnifiedBalance.spend. |

#### SpendParams

Parameters for spending (minting) USDC on a destination chain from one or more
Gateway account sources.

```typescript theme={null}
type SpendParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends UnifiedBalanceChainIdentifier =
    UnifiedBalanceChainIdentifier,
> =
  | SpendParamsWithFrom<
      TFromAdapterCapabilities,
      TToAdapterCapabilities,
      TChainIdentifier
    >
  | SpendParamsRetry<
      TFromAdapterCapabilities,
      TToAdapterCapabilities,
      TChainIdentifier
    >;
```

**Returns**

[`Promise<EstimateSpendResult>`](#estimatespendresult)

#### EstimateSpendResult

Cost estimation for a spend (mint) operation.

```typescript theme={null}
interface EstimateSpendResult {
  fees: FeeEntry[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| fees | FeeEntry\[] | Itemised fee breakdown for the spend operation. |

**Usage Example**

```typescript theme={null}
const estimate = await kit.unifiedBalance.estimateSpend({
  from: { adapter, allocations: [{ amount: "100", chain: "Ethereum" }] },
  to: { adapter, chain: "Base" },
  token: "USDC",
});
```

***

### getBalances(params)

Fetch aggregated and per-chain balances for one or more accounts.

```typescript theme={null}
getBalances(params: GetBalancesParams): Promise<GetBalancesResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`GetBalancesParams`](#getbalancesparams) | Balance query parameters (adapter or account address). |

#### GetBalancesParams

Parameters for the balances and pending-deposits API requests.

Specify the `token` to query and one or more `sources` identifying the accounts
or adapters whose balances should be retrieved. When `includePending` is true,
the result includes pending balances and pending transaction details per chain.

```typescript theme={null}
interface GetBalancesParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  token?: SupportedTokenInput;
  sources: Sources<TAdapterCapabilities>;
  includePending?: boolean;
  networkType?: NetworkType;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| includePending | boolean | When true, the result includes pending balances. When false or omitted, only confirmed balances are returned. |
| networkType | NetworkType | Network to use when no chains are specified on a source. When omitted, mainnet is used when chains cannot be derived. |
| sources | `Sources` | One or more sources identifying the accounts or adapters to query. Accepts a single object or an array. |
| token | SupportedTokenInput | The token to query balances for. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<GetBalancesResult>`](#getbalancesresult)

#### GetBalancesResult

Result returned from the provider's `getBalances` method (combined confirmed and
pending).

When `includePending` is false (default), only `totalConfirmedBalance` and
`breakdown` with confirmed fields are returned. When `includePending` is true,
`totalPendingBalance` is present and breakdown entries include pending amounts
and `pendingTransactions` per chain.

```typescript theme={null}
interface GetBalancesResult {
  token: SupportedToken;
  totalConfirmedBalance: string;
  totalPendingBalance?: string;
  breakdown: BalanceWithPendingBreakdown[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| breakdown | BalanceWithPendingBreakdown\[] | Per-account, per-chain breakdown. |
| token | SupportedToken | Token that was queried. |
| totalConfirmedBalance | string | Total confirmed balance across all accounts and chains (human-readable decimal string). |
| totalPendingBalance | string | Total pending balance across all accounts and chains. Present only when `includePending` is true. |

#### NetworkType

Network type for balance queries when the target chain(s) are not explicitly
specified. Default is mainnet.

```typescript theme={null}
type NetworkType = "mainnet" | "testnet";
```

#### BalanceWithPendingBreakdown

Per-account balance breakdown used in GetBalancesResult.

When `includePending` is true, `totalPending` is present and each chain entry
may include `pendingBalance` and `pendingTransactions`.

```typescript theme={null}
interface BalanceWithPendingBreakdown {
  depositor: string;
  totalConfirmed: string;
  totalPending?: string;
  breakdown: ChainBalanceBreakdown[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| breakdown | ChainBalanceBreakdown\[] | Per-chain breakdown for this depositor. |
| depositor | string | Gateway account (depositor) address. |
| totalConfirmed | string | Total confirmed balance across chains (human-readable decimal string). |
| totalPending | string | Total pending balance across chains. Present only when `includePending` is true. |

#### ChainBalanceBreakdown

Per-chain balance within a breakdown in GetBalancesResult.

When `includePending` is true, `pendingBalance` and `pendingTransactions` are
present.

```typescript theme={null}
interface ChainBalanceBreakdown {
  chain: Blockchain;
  confirmedBalance: string;
  pendingBalance?: string;
  pendingTransactions?: PendingBalanceTransaction[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| chain | Blockchain | The chain. |
| confirmedBalance | string | Confirmed balance (human-readable decimal string). |
| pendingBalance | string | Pending balance on this chain. Present only when GetBalancesParams.includePending is true. |
| pendingTransactions | PendingBalanceTransaction\[] | Pending deposit transactions on this chain. Present only when GetBalancesParams.includePending is true. |

#### PendingBalanceTransaction

A pending transaction included in GetBalancesResult when `includePending` is
true.

```typescript theme={null}
interface PendingBalanceTransaction {
  transactionHash: string;
  amount: string;
  blockTimestamp: string;
}
```

**Usage Example**

```typescript theme={null}
const balances = await kit.unifiedBalance.getBalances({
  token: "USDC",
  sources: { address: "0x1234…abcd" },
});
```

***

### getDelegateStatus(params)

Check the finality-aware delegate status of an address.

```typescript theme={null}
getDelegateStatus(params: GetDelegateStatusParams): Promise<DelegateStatus>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`GetDelegateStatusParams`](#getdelegatestatusparams) | The adapter context and delegate address to check. |

#### GetDelegateStatusParams

Parameters for checking the delegate status of an address on a Gateway account.

```typescript theme={null}
interface GetDelegateStatusParams {
  delegateAddress: string;
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  token?: SupportedTokenInput;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| delegateAddress | string | The address to check for delegate status. |
| from | `AdapterContext` | The adapter context identifying the account owner and chain. |
| token | SupportedTokenInput | The token for which delegation is checked. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<DelegateStatus>`](#delegatestatus)

#### DelegateStatus

The finality-aware status of a delegate on a Gateway account.

* `'none'` — not a delegate on-chain.
* `'pending'` — delegate set on-chain but Gateway hasn't finalized it yet; spend
  will fail until the status advances to `'ready'`.
* `'ready'` — finalized at Gateway; spend will succeed.

```typescript theme={null}
type DelegateStatus = "none" | "pending" | "ready";
```

**Usage Example**

```typescript theme={null}
const status = await kit.unifiedBalance.getDelegateStatus({
  from: { adapter, chain: 'Ethereum' },
  delegateAddress: '0xDelegate…',
})
if (status === 'ready') { // safe to spend }
```

***

### getSupportedChains(token)

Get all chains supported by the unified balance operations.

```typescript theme={null}
getSupportedChains(token?: SupportedToken, options?: GetSupportedChainsOptions): ChainDefinition[]
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| token | `'USDC'` | Optional token filter (defaults to USDC). |
| options | [`GetSupportedChainsOptions`](#getsupportedchainsoptions) | Optional filtering (e.g. forwarder support). |

#### GetSupportedChainsOptions

Options for filtering supported chains.

```typescript theme={null}
type GetSupportedChainsOptions =
  | {
      chainType: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported: boolean;
      sourceFeeSupported?: boolean;
    }
  | {
      chainType?: CCTPV2SupportedChainType | CCTPV2SupportedChainType[];
      isTestnet?: boolean;
      forwarderSupported?: boolean;
      sourceFeeSupported: boolean;
    };
```

**Properties**

| Name | Type | Description |
| - | - | - |
| forwarderSupported | `'source' \| 'destination'` | Filter chains by forwarder support. When set, only chains whose `gateway.forwarderSupported.source` or `gateway.forwarderSupported.destination` matches the specified value are returned.<br /><br /> - `undefined` (default) — no forwarder filtering; all supported chains are returned.<br />- `'source'` — only chains that support forwarding as a source.<br />- `'destination'` — only chains that support forwarding as a destination. |

**Returns**

`ChainDefinition[]`

**Usage Example**

```typescript theme={null}
const chains = kit.unifiedBalance.getSupportedChains();
const usdcChains = kit.unifiedBalance.getSupportedChains("USDC");
```

***

### initiateRemoveFund(params)

Initiate a trustless recovery removal from an account.

Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
recovery path for situations where the normal spend flow is unavailable. Calling
this method starts the 7-day withdrawal delay before the removal can be
completed.

```typescript theme={null}
initiateRemoveFund(params: InitiateRemoveFundParams): Promise<InitiateRemoveFundResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`InitiateRemoveFundParams`](#initiateremovefundparams) | The account owner's adapter context, amount, and token. |

#### InitiateRemoveFundParams

Parameters for initiating a delayed recovery fund removal from a Gateway
account.

```typescript theme={null}
interface InitiateRemoveFundParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends UnifiedBalanceChainIdentifier =
    UnifiedBalanceChainIdentifier,
> {
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  amount: string;
  token?: SupportedTokenInput;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount to remove (human-readable decimal string). |
| from | `AdapterContext` | The account owner's adapter context identifying the account, chain, and address. |
| token | SupportedTokenInput | The token to remove. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<InitiateRemoveFundResult>`](#initiateremovefundresult)

#### InitiateRemoveFundResult

Result returned after successfully initiating a fund removal.

```typescript theme={null}
interface InitiateRemoveFundResult {
  amount: string;
  token: SupportedToken;
  account: string;
  chain: Blockchain;
  withdrawingBalance: string;
  withdrawalBlock: number;
  txHash: string;
  explorerUrl?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| account | string | The Gateway account from which this removal will occur. |
| amount | string | The amount requested for removal. |
| chain | Blockchain | The chain on which this removal was initiated. |
| explorerUrl | string | Link to view the transaction details on the appropriate blockchain explorer. |
| token | SupportedToken | The token type (always USDC). |
| txHash | string | Unique identifier returned by the blockchain once the transaction is mined. |
| withdrawalBlock | number | The block number at which the removal can be completed. |
| withdrawingBalance | string | The balance currently in the withdrawing state for this account. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.initiateRemoveFund({
  from: { adapter, chain: "Ethereum" },
  amount: "50",
  token: "USDC",
});
```

***

### off(action)

Unregister an event handler for a specific gateway lifecycle action.

Removes a previously registered event handler. You must pass the exact same
handler function reference that was used during registration.

```typescript theme={null}
off(action: string, handler: (payload: unknown) => void): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| action | `string` | The action name or `'*'` for all actions. |
| handler | `(payload: unknown) => void` | The exact handler reference to remove. |

**Usage Example**

```typescript theme={null}
const kit = new AppKit();
const handler = (payload: unknown) => console.log(payload);

kit.unifiedBalance.on("gateway.deposit.succeeded", handler);
kit.unifiedBalance.off("gateway.deposit.succeeded", handler);
```

***

### on(action)

Register an event handler for a specific gateway lifecycle action.

Subscribe to events emitted during gateway operations such as deposit, spend,
getBalances, etc. Handlers receive strongly-typed payloads based on the action
name.

Multiple handlers can be registered for the same action, and all will be invoked
when the action occurs. Use the wildcard `'*'` to listen to all actions.

Note: TypeScript autocomplete may only show `'*'` due to internal type erasure.
The following action names are available at runtime and can be imported as
`GatewayActionName` from `@circle-fin/provider-gateway-v1`:

| Action | Stages |
| - | - |
| `gateway.deposit` | `.started` `.succeeded` `.failed` |
| `gateway.depositFor` | `.started` `.succeeded` `.failed` |
| `gateway.spend` | `.started` `.succeeded` `.failed` |
| `gateway.spend.step` | `.buildBurnIntents` `.signBurnIntents` `.fetchAttestation` `.mint` |
| `gateway.estimateSpend` | `.started` `.succeeded` `.failed` |
| `gateway.getBalances` | `.started` `.succeeded` `.failed` |
| `gateway.addDelegate` | `.started` `.succeeded` `.failed` |
| `gateway.removeDelegate` | `.started` `.succeeded` `.failed` |
| `gateway.initiateRemoveFund` | `.started` `.succeeded` `.failed` |
| `gateway.removeFund` | `.started` `.succeeded` `.failed` |

```typescript theme={null}
on(action: string, handler: (payload: unknown) => void): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| action | `string` | The action name or `'*'` for all actions. |
| handler | `(payload: unknown) => void` | Callback to invoke when the action occurs. |

**Usage Example**

```typescript theme={null}
const kit = new AppKit();

kit.unifiedBalance.on("gateway.spend.started", (payload) => {
  console.log("Spend started:", payload);
});

kit.unifiedBalance.on("*", (payload) => {
  console.log("Event:", payload);
});
```

***

### removeCustomFeePolicy()

Remove the custom fee policy for the kit.

```typescript theme={null}
removeCustomFeePolicy(): void
```

**Usage Example**

```typescript theme={null}
kit.unifiedBalance.removeCustomFeePolicy();
```

***

### removeDelegate(params)

Revoke spending rights from a delegate on the owner's account.

```typescript theme={null}
removeDelegate(params: UpdateDelegateParams): Promise<UpdateDelegateResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`UpdateDelegateParams`](#updatedelegateparams-2) | The owner's adapter context and the delegate address. |

#### UpdateDelegateParams

Parameters for adding or removing a delegate on a Gateway account.

```typescript theme={null}
interface UpdateDelegateParams {
  delegateAddress: string;
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  token?: SupportedTokenInput;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| delegateAddress | string | The address being added or removed as an authorized delegate. |
| from | `AdapterContext` | The owner's adapter context identifying the account and chain to which the delegate will be authorized. |
| token | SupportedTokenInput | The token for which delegation applies. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<UpdateDelegateResult>`](#updatedelegateresult-2)

#### UpdateDelegateResult

Result returned after a successful add or remove delegate operation.

```typescript theme={null}
interface UpdateDelegateResult {
  account: string
  chain: Blockchain
  delegateAddress: string
  explorerUrl?: string
  state: 'added' \| 'removed'
  txHash: string
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| account | string | The Gateway account that was modified. |
| chain | Blockchain | The chain on which the delegate was updated. |
| delegateAddress | string | The delegate address that was added or removed. |
| explorerUrl | string | Link to view the transaction details on the appropriate blockchain explorer. |
| state | `'added' \| 'removed'` | Whether the delegate was added or removed. |
| txHash | string | Unique identifier returned by the blockchain once the transaction is mined. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.removeDelegate({
  from: { adapter, chain: "Ethereum" },
  delegateAddress: "0xDelegate…",
});
```

***

### removeFeeRecipients()

Remove the declarative fee recipient map for the kit.

```typescript theme={null}
removeFeeRecipients(): void
```

**Usage Example**

```typescript theme={null}
kit.unifiedBalance.removeFeeRecipients();
```

***

### removeFund(params)

Complete a trustless recovery removal after the withdrawal delay.

Use `spend` for normal movement out of a Unified Balance. `removeFund` is a
recovery path for situations where the normal spend flow is unavailable. Both
EVM and Solana removals require a 7-day withdrawal delay after
`initiateRemoveFund` before funds can be removed.

```typescript theme={null}
removeFund(params: RemoveFundParams): Promise<RemoveFundResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`RemoveFundParams`](#removefundparams) | The account owner context matching the original initiation. |

#### RemoveFundParams

Parameters for completing a recovery fund removal after the withdrawal delay.

```typescript theme={null}
interface RemoveFundParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends UnifiedBalanceChainIdentifier =
    UnifiedBalanceChainIdentifier,
> {
  from: AdapterContext<TAdapterCapabilities, TChainIdentifier>;
  token?: SupportedTokenInput;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| from | `AdapterContext` | The account owner's adapter context. Must match the one used when initiating the fund removal. |
| token | SupportedTokenInput | The token to remove. Accepts any case (e.g. `'usdc'`, `'Usdc'`); normalised to uppercase internally. |

**Returns**

[`Promise<RemoveFundResult>`](#removefundresult)

#### RemoveFundResult

Result returned after successfully completing a fund removal.

```typescript theme={null}
interface RemoveFundResult {
  amount: string;
  token: SupportedToken;
  account: string;
  chain: Blockchain;
  txHash: string;
  explorerUrl?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| account | string | The Gateway account from which the tokens were removed. |
| amount | string | The final removed amount. |
| chain | Blockchain | The chain on which the removal occurred. |
| explorerUrl | string | Link to view the transaction details on the appropriate blockchain explorer. |
| token | SupportedToken | The token type (always USDC). |
| txHash | string | Unique identifier returned by the blockchain once the transaction is mined. |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.removeFund({
  from: { adapter, chain: "Ethereum" },
  token: "USDC",
});
```

***

### setCustomFeePolicy(policy)

Set a custom fee policy for spend operations. Once set, every subsequent
`spend()` and `estimateSpend()` call will include the computed fee unless
overridden by per-call `config.customFee`.

```typescript theme={null}
setCustomFeePolicy(policy: CustomFeePolicy): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| policy | [`CustomFeePolicy`](#customfeepolicy) | The fee computation and recipient resolution policy. |

#### CustomFeePolicy

```typescript theme={null}
interface CustomFeePolicy {
  computeFee: SpendFeeFunction;
  resolveFeeRecipientAddress?: SpendFeeRecipientFunction;
}
```

**Usage Example**

```typescript theme={null}
kit.unifiedBalance.setCustomFeePolicy({
  computeFee: () => "0.10",
  resolveFeeRecipientAddress: () => "0xFeeRecipient…",
});
```

***

### setFeeRecipients(config)

Set a declarative fee recipient map, keyed by chain type.

Once set, `spend()`/`estimateSpend()` resolve the fee recipient by looking up
the spend's destination chain type in this map — taking priority over
`customFeePolicy`'s `resolveFeeRecipientAddress` callback.

```typescript theme={null}
setFeeRecipients(config: FeeRecipientsConfig): void
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| config | [`FeeRecipientsConfig`](#feerecipientsconfig) | Fee recipient addresses keyed by chain type (e.g. `{ evm: '0x...', solana: 'Sol...' }`). |

#### FeeRecipientsConfig

```typescript theme={null}
type FeeRecipientsConfig = Partial<Record<FeeRecipientChainType, string>>;
```

**Usage Example**

```typescript theme={null}
kit.unifiedBalance.setFeeRecipients({
  evm: "0x1234567890123456789012345678901234567890",
  solana: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
});
```

***

### spend(params)

Spend (mint) USDC on a destination chain by pulling funds from one or more
account sources.

```typescript theme={null}
spend(params: SpendParams): Promise<SpendResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`SpendParams`](#spendparams-2) | Spend details including source(s), destination, and token. |

#### SpendParams

Parameters for spending (minting) USDC on a destination chain from one or more
Gateway account sources.

```typescript theme={null}
type SpendParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TToAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
  TChainIdentifier extends UnifiedBalanceChainIdentifier =
    UnifiedBalanceChainIdentifier,
> =
  | SpendParamsWithFrom<
      TFromAdapterCapabilities,
      TToAdapterCapabilities,
      TChainIdentifier
    >
  | SpendParamsRetry<
      TFromAdapterCapabilities,
      TToAdapterCapabilities,
      TChainIdentifier
    >;
```

**Returns**

[`Promise<SpendResult>`](#spendresult)

#### SpendResult

Result returned after a successful spend (mint) operation.

```typescript theme={null}
interface SpendResult {
  allocations?: AllocationResult[];
  recipientAddress: string;
  destinationChain: Blockchain;
  txHash: string;
  explorerUrl?: string;
  fees?: FeeEntry[];
  transferId?: string;
  expirationBlock?: string;
  steps?: SpendStep[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allocations | AllocationResult\[] | Flattened list of allocations that were executed, each with its source Gateway account. Only present for non-retry spends. |
| destinationChain | Blockchain | The destination chain on which the recipient received the USDC. |
| expirationBlock | string | Block height after which the transfer attestation expires. Returned by the Gateway transfer API. |
| explorerUrl | string | Link to view the transaction details on the appropriate blockchain explorer. |
| fees | FeeEntry\[] | Fee breakdown (provider, gasFee, optional kit, forwarder) for the executed spend. Same shape as estimateSpend fees. Omitted when using config.retry. |
| recipientAddress | string | The address that received the minted USDC. |
| steps | SpendStep\[] | Ordered list of steps executed during the spend operation. |
| transferId | string | Gateway transfer identifier. Present when `useForwarder` is enabled and can be used to query transfer status via `GET /v1/transfer/{id}`. |
| txHash | string | Unique identifier returned by the blockchain once the transaction is mined. |

#### AllocationResult

Extends Allocation with the resolved source Gateway account address.

```typescript theme={null}
interface AllocationResult extends Allocation {
  sourceAccount: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount to pull from this chain (human-readable decimal string). |
| chain | UnifiedBalanceChainIdentifier | The chain from which to pull the funds. |
| sourceAccount | string | The Gateway account address from which this amount was pulled. |

#### SpendStep

Data payload for a single step in a spend operation.

```typescript theme={null}
interface SpendStep {
  data?: unknown
  error?: unknown
  errorMessage?: string
  explorerUrl?: string
  name: string
  state: 'pending' \| 'success' \| 'error'
  txHash?: string
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| data | unknown | Optional data for the step. |
| error | unknown | Optional raw error object. |
| errorMessage | string | Optional human-readable error message. |
| explorerUrl | string | Optional explorer URL for viewing this transaction on a block explorer. |
| name | string | Human-readable name of the step (e.g., "buildBurnIntents", "mint"). |
| state | `'pending' \| 'success' \| 'error'` | The state of the step. |
| txHash | string | Optional transaction hash for this step (if applicable). |

**Usage Example**

```typescript theme={null}
const result = await kit.unifiedBalance.spend({
  from: { adapter, allocations: [{ amount: "100", chain: "Ethereum" }] },
  to: { adapter, chain: "Base" },
  token: "USDC",
});
```

***

## kit.earn Methods

`earn` is a property on every `AppKit` instance. Call these methods as
`kit.earn.methodName()`.

### deposit(params)

Deposit into an earn vault.

```typescript theme={null}
deposit(params: SameChainDepositParams<TFromAdapterCapabilities>): Promise<EarnSameChainDepositResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `SameChainDepositParams<TFromAdapterCapabilities>` | Deposit parameters |

**Returns**

[`Promise<EarnSameChainDepositResult>`](#earnsamechaindepositresult)

#### EarnSameChainDepositResult

Result of a deposit operation returned by EarningProvider.deposit.

Contains the confirmed on-chain transaction hash and explorer URL alongside the
vault and deposit amount.

```typescript theme={null}
interface EarnSameChainDepositResult {
  readonly kind?: "same-chain";
  readonly txHash: string;
  readonly explorerUrl: string;
  readonly vaultAddress: string;
  readonly amount: string;
}
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.earn.deposit({
  from: { adapter, chain: EarnChain.Arc_Testnet },
  vaultAddress: "0x...",
  amount: "100.50",
});
```

***

### exploreVaults(params)

Discover earn vaults available on a chain.

```typescript theme={null}
exploreVaults(params: ExploreVaultsParams): Promise<EarnExploreVaultsResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `ExploreVaultsParams` | Discovery parameters with chain and optional filters |

**Returns**

[`Promise<EarnExploreVaultsResult>`](#earnexplorevaultsresult)

#### EarnExploreVaultsResult

Result of a vault discovery query.

```typescript theme={null}
type EarnExploreVaultsResult = Omit<ExploreVaultsResult, "vaults"> & {
  readonly vaults: readonly EarnVaultInfo[];
};
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.earn.exploreVaults({
  chain: EarnChain.Arc_Testnet,
  minApy: "0.03",
  sortBy: "apy",
});
```

***

### exploreVaultsIterator(params)

Lazily iterate every earn vault available on a chain.

```typescript theme={null}
exploreVaultsIterator(params: ExploreVaultsIteratorParams): AsyncGenerator<EarnVaultInfo, void, undefined>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `ExploreVaultsIteratorParams` | Discovery parameters (no `page`; the iterator manages it) |

**Returns**

`AsyncGenerator<EarnVaultInfo, void, undefined>`

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
for await (const vault of kit.earn.exploreVaultsIterator({
  chain: EarnChain.Arc_Testnet,
})) {
  console.log(vault.name);
}
```

***

### getCrossChainDepositStatus(params)

Fetch the current status of a crosschain Earn deposit.

```typescript theme={null}
getCrossChainDepositStatus(params: GetCrossChainDepositStatusParams): Promise<EarnCrossChainDepositStatus>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `GetCrossChainDepositStatusParams` | Status query parameters identifying the deposit by execId |

**Returns**

[`Promise<EarnCrossChainDepositStatus>`](#earncrosschaindepositstatus)

***

### getDepositQuote(params)

Fetch a deposit quote.

```typescript theme={null}
getDepositQuote(params: GetDepositQuoteParams<TFromAdapterCapabilities>): Promise<EarnDepositQuoteInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `GetDepositQuoteParams<TFromAdapterCapabilities>` | Deposit quote parameters |

**Returns**

[`Promise<EarnDepositQuoteInfo>`](#earndepositquoteinfo)

#### EarnDepositQuoteInfo

Result of a deposit quote operation.

```typescript theme={null}
type EarnDepositQuoteInfo = Omit<
  DepositQuoteInfo,
  "deposit" | "expectedShares" | "fees" | "gasFees"
> & {
  readonly deposit: EarnAssetAmount;
  readonly expectedShares: EarnAssetAmount;
  readonly fees: readonly EarnAssetAmount[];
  readonly gasFees?: readonly EarnGasFeeEstimate[] | undefined;
};
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const quote = await kit.earn.getDepositQuote({
  from: { adapter, chain: EarnChain.Arc_Testnet },
  vaultAddress: "0x...",
  amount: "100.50",
});
```

***

### getPosition(params)

Fetch wallet position information for an earn vault.

```typescript theme={null}
getPosition(params: GetPositionParams<TFromAdapterCapabilities>): Promise<EarnPositionInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `GetPositionParams<TFromAdapterCapabilities>` | Position query parameters |

**Returns**

[`Promise<EarnPositionInfo>`](#earnpositioninfo)

#### EarnPositionInfo

Position information returned by the SDK.

```typescript theme={null}
type EarnPositionInfo = Omit<
  PositionInfo,
  "currentBalance" | "shares" | "pnl" | "accruedRewards"
> & {
  readonly currentBalance: string;
  readonly shares: string;
  readonly pnl: EarnPositionPnLInfo;
  readonly accruedRewards: readonly EarnAccruedRewardInfo[];
};
```

#### EarnAccruedRewardInfo

Accrued reward returned by the SDK in human-readable decimal form.

```typescript theme={null}
type EarnAccruedRewardInfo = Omit<AccruedRewardInfo, "amount"> & {
  readonly amount: string;
};
```

#### EarnPositionPnLInfo

Profit-and-loss calculation state returned by the SDK.

```typescript theme={null}
type EarnPositionPnLInfo =
  | (Omit<
      ProviderAvailablePositionPnLInfo,
      "principalDeposited" | "totalYieldEarned"
    > & {
      readonly principalDeposited: string;
      readonly totalYieldEarned: string;
    })
  | Exclude<PositionPnLInfo, ProviderAvailablePositionPnLInfo>;
```

#### BorrowLoanInfo

Kit-level loan info.

Mirrors the provider's `LoanPosition` — the Borrow Service already returns
human-readable amounts carrying their token identity, so nothing is reformatted
here. `chain` is passed through as the raw string the provider returns, matching
`Loan`/`RepayQuote`/`CloseLoanQuote` above: the provider has already validated
it against the supported-chain enum, so re-narrowing it here to a
chain-identifier union would require an unchecked `as` cast at the boundary (see
GR-032) for no added safety.

Carries the same economics as the matching Loan in a BorrowKit.getLoans page, so
reading one loan never returns less than listing the wallet that owns it. It
differs from `Loan` in exactly one way, inherited from the provider: the owner
is named `wallet` rather than `walletAddress`.

```typescript theme={null}
interface BorrowLoanInfo {
  readonly loanId: string;
  readonly wallet: string;
  readonly chain: string;
  readonly marketId: string;
  readonly dataStatus: BorrowLoanDataStatus;
  readonly collateral: BorrowAssetAmount | null;
  readonly borrowed: BorrowAssetAmount | null;
  readonly principalBorrowed: BorrowAssetAmount | null;
  readonly accruedInterest: BorrowAssetAmount | null;
  readonly borrowApy: number | null;
  readonly ltv: number | null;
  readonly healthFactor: number | null;
  readonly healthFactorBand: BorrowHealthFactorBand | null;
  readonly liquidationPrice: BorrowAssetAmount | null;
  readonly status: "active" | "closed";
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| accruedInterest | `BorrowAssetAmount \| null` | Interest accrued on top of BorrowLoanInfo.principalBorrowed; `null` while `dataStatus` is `PENDING`. |
| borrowApy | `number \| null` | Current borrow rate as a decimal fraction (`0.05` is 5%); `null` while `dataStatus` is `PENDING`. |
| borrowed | `BorrowAssetAmount \| null` | Outstanding debt on this loan; `null` while `dataStatus` is `PENDING`. |
| chain | string | Blockchain where the loan is deployed. |
| collateral | `BorrowAssetAmount \| null` | Collateral held against this loan; `null` while `dataStatus` is `PENDING`. |
| dataStatus | BorrowLoanDataStatus | Whether this loan's economics have converged. Every economic field below reads `null` while this is `PENDING` — the state a loan is in right after BorrowKit.borrow. |
| healthFactor | `number \| null` | Health factor of the loan. Below `1.0` means the loan is eligible for liquidation. `null` when the loan carries no debt, and `null` while `dataStatus` is `PENDING`. |
| healthFactorBand | `BorrowHealthFactorBand \| null` | Banded reading of BorrowLoanInfo.healthFactor; `null` whenever the health factor is. |
| liquidationPrice | `BorrowAssetAmount \| null` | Collateral price at which this loan becomes liquidatable, denominated in the borrowed asset; `null` while `dataStatus` is `PENDING`. |
| loanId | string | Unique identifier for this loan. |
| ltv | `number \| null` | Debt value divided by collateral value; `null` while `dataStatus` is `PENDING`. |
| marketId | string | Morpho market this loan borrows from. |
| principalBorrowed | `BorrowAssetAmount \| null` | Debt excluding accrued interest; `null` while `dataStatus` is `PENDING`. |
| status | `'active' \| 'closed'` | Current lifecycle status of the loan. |
| wallet | string | Wallet address that owns this loan. |

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const position = await kit.earn.getPosition({
  from: { adapter, chain: EarnChain.Arc_Testnet },
  vaultAddress: "0x...",
});
```

***

### getVaults(params)

Fetch earn vault information.

```typescript theme={null}
getVaults(params: GetVaultsParams): Promise<EarnGetVaultsResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `GetVaultsParams` | Vault query parameters |

**Returns**

[`Promise<EarnGetVaultsResult>`](#earngetvaultsresult)

#### EarnGetVaultsResult

Result of a batch vault lookup.

```typescript theme={null}
type EarnGetVaultsResult = Omit<GetVaultsResult, "vaults"> & {
  readonly vaults: readonly EarnVaultInfo[];
};
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.earn.getVaults({
  vaults: [{ chain: EarnChain.Arc_Testnet, vaultAddress: "0x..." }],
});
```

***

### getWithdrawalQuote(params)

Fetch a withdrawal quote.

```typescript theme={null}
getWithdrawalQuote(params: GetWithdrawalQuoteParams<TFromAdapterCapabilities>): Promise<EarnWithdrawalQuoteInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `GetWithdrawalQuoteParams<TFromAdapterCapabilities>` | Withdrawal quote parameters |

**Returns**

[`Promise<EarnWithdrawalQuoteInfo>`](#earnwithdrawalquoteinfo)

#### EarnWithdrawalQuoteInfo

Result of a withdrawal quote operation.

```typescript theme={null}
type EarnWithdrawalQuoteInfo = Omit<
  WithdrawalQuoteInfo,
  "withdrawal" | "sharesToRedeem" | "maxWithdrawable" | "fees" | "gasFees"
> & {
  readonly withdrawal: EarnAssetAmount;
  readonly sharesToRedeem: EarnAssetAmount;
  readonly maxWithdrawable: EarnAssetAmount;
  readonly fees: readonly EarnAssetAmount[];
  readonly gasFees?: readonly EarnGasFeeEstimate[] | undefined;
};
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const quote = await kit.earn.getWithdrawalQuote({
  from: { adapter, chain: EarnChain.Arc_Testnet },
  vaultAddress: "0x...",
  amount: "50.00",
});
```

***

### retry(error)

Resume a multi-phase earn operation that previously failed.

Pass the KitError caught from `deposit`, `withdraw`, or `claimRewards`. The
error carries the original inputs and step progress, so completed phases (for
example a successful token approval) can be skipped. Call
`isRetryableError(error)` first.

```typescript theme={null}
retry(error: unknown): Promise<EarnDepositOutcome \| EarnWithdrawResult \| EarnClaimRewardsResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| error | `unknown` | The error caught from a previous multi-phase earn operation |

**Returns**

`Promise<EarnDepositOutcome \| EarnWithdrawResult \| EarnClaimRewardsResult>`

#### EarnDepositOutcome

Result of a deposit operation returned by EarningProvider.deposit.

`kind` is always set at runtime, but it is optional on the same-chain member, so
narrow against the required crosschain discriminator.

```typescript theme={null}
type EarnDepositOutcome =
  EarnSameChainDepositResult | EarnCrossChainDepositResult;
```

#### EarnCrossChainDepositResult

Result of a crosschain deposit submitted through the bridge flow.

```typescript theme={null}
interface EarnCrossChainDepositResult {
  readonly kind: "cross-chain";
  readonly execId: string;
  readonly status: string;
  readonly vaultAddress: string;
  readonly amount: string;
  readonly sourceChain: Blockchain;
  readonly destinationChain: Blockchain;
  readonly expiresAt: string;
  readonly quoteIssuedAt?: string | undefined;
  readonly quoteExpiry?: EarnBridgeQuoteExpiry | undefined;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | Deposit amount in human-readable decimal format. |
| destinationChain | Blockchain | Destination chain where the vault lives. |
| execId | string | Idempotency execution ID for the crosschain deposit. |
| expiresAt | string | ISO-8601 UTC timestamp after which the prepared bundle expires.<br /><br /> `retry()` resumes the same bridge execution and replays the original prepared bundle before this timestamp. After this timestamp the expiry error is FATAL (not retryable); call `deposit()` again, which starts a fresh bridge execution. |
| kind | `'cross-chain'` | Discriminator for narrowing EarnDepositOutcome. |
| quoteExpiry | `EarnBridgeQuoteExpiry \| undefined` | Optional source-fee quote expiry metadata for display and refresh UX. This deadline is independent of the prepared-bundle `expiresAt` above. |
| quoteIssuedAt | `string \| undefined` | ISO-8601 UTC timestamp at which the source-fee quote was issued. |
| sourceChain | Blockchain | Source chain where the ERC-3009 authorization is signed. |
| status | string | API-defined bridge lifecycle status returned by bridge submit.<br /><br /> The value space is owned by the bridge API and unions two vocabularies: a first-time submit reports the relay state (for example `'PENDING'`, `'SENT'`, `'COMPLETE'`, `'FAILED'`), while a replayed submit for an already-relayed execution reports the bridge lifecycle (for example `'SOURCE_PENDING'`, `'ATTESTING'`, `'DESTINATION_PENDING'`, `'COMPLETE'`, `'FAILED'`, `'CANCELLED'`). Neither set is exhaustive; treat unrecognized values as in-progress rather than branching exhaustively.<br /><br /> `deposit()` returns the submit response only. It does not currently poll bridge settlement or vault-position completion. |
| vaultAddress | string | Vault contract address deposited into. |

#### EarnBridgeQuoteExpiry

Source-fee quote expiry metadata returned by bridge prepare.

`TIMESTAMP` expiries use an ISO-8601 UTC `expiresAt`; `BLOCK_NUMBER` expiries
use a source-chain `expiresAtBlock`, with an optional ISO-8601 UTC
`blockEstimatedAt` for when that block estimate was produced.

```typescript theme={null}
type EarnBridgeQuoteExpiry = Readonly<
  Exclude<
    | { mode: "TIMESTAMP"; expiresAt: string }
    | {
        mode: "BLOCK_NUMBER";
        expiresAtBlock: number;
        blockEstimatedAt?: string;
      },
    undefined
  >
>;
```

#### EarnClaimRewardsResult

Kit-level result of a claim rewards operation.

```typescript theme={null}
type EarnClaimRewardsResult =
  BorrowNoClaimableRewardsResult | EarnClaimedRewardsResult;
```

#### EarnClaimedRewardsResult

Kit-level result returned after claimable rewards are submitted on-chain.

```typescript theme={null}
interface EarnClaimedRewardsResult {
  readonly status: "claimed";
  readonly rewards: readonly EarnClaimedAmount[];
  readonly txHash: string;
  readonly explorerUrl: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| explorerUrl | string | Explorer URL for the confirmed on-chain transaction. |
| rewards | readonly EarnClaimedAmount\[] | Reward token amounts that were claimed. |
| status | `'claimed'` | Discriminates the successful on-chain claim result. |
| txHash | string | Confirmed on-chain transaction hash. |

#### EarnClaimedAmount

Kit-level reward amount returned from a claim rewards operation.

```typescript theme={null}
type EarnClaimedAmount = Omit<ClaimedAmount, "amount"> & {
  readonly amount: string;
};
```

#### BorrowRetryResult

Result of retry / retryBorrow.

The variant matches the failed write: a repaid loan returns a repay result, not
a borrow result.

```typescript theme={null}
type BorrowRetryResult =
  | BorrowResult
  | BorrowRepayResult
  | BorrowAddCollateralResult
  | BorrowCloseLoanResult
  | BorrowWithdrawCollateralResult;
```

**Usage Example**

```typescript theme={null}
import { AppKit, isRetryableError } from "@circle-fin/app-kit";

const kit = new AppKit();

try {
  await kit.earn.deposit(params);
} catch (error) {
  if (isRetryableError(error)) {
    const result = await kit.earn.retry(error);
  }
}
```

***

### waitForCrossChainDeposit(params)

Poll a crosschain Earn deposit until it reaches a terminal bridge state.

```typescript theme={null}
waitForCrossChainDeposit(params: WaitForCrossChainDepositParams): Promise<EarnCrossChainDepositWaitResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `WaitForCrossChainDepositParams` | Wait parameters including execId and optional polling knobs |

**Returns**

[`Promise<EarnCrossChainDepositWaitResult>`](#earncrosschaindepositwaitresult)

#### EarnCrossChainDepositWaitResult

Result returned by waiters for crosschain Earn deposits.

The raw bridge status is preserved in `status`. `outcome` summarizes why the
wait stopped, while `terminal` and `timedOut` let callers branch without
re-deriving bridge lifecycle semantics.

```typescript theme={null}
interface EarnCrossChainDepositWaitResult {
  readonly status: EarnCrossChainDepositStatus;
  readonly outcome: EarnCrossChainDepositWaitOutcome;
  readonly terminal: boolean;
  readonly timedOut: boolean;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| outcome | EarnCrossChainDepositWaitOutcome | Normalized outcome that caused the waiter to stop. |
| status | EarnCrossChainDepositStatus | Last observed structured crosschain deposit status. |
| terminal | boolean | Whether the observed bridge status is terminal. |
| timedOut | boolean | Whether the wait budget elapsed before a terminal status was observed. |

#### EarnCrossChainDepositWaitOutcome

Normalized outcome used by crosschain deposit waiters.

`timeout` is a waiter outcome only; it is not derived from an API status.

```typescript theme={null}
type EarnCrossChainDepositWaitOutcome =
  "complete" | "failed" | "cancelled" | "timeout";
```

***

### withdraw(params)

Withdraw from an earn vault.

```typescript theme={null}
withdraw(params: WithdrawParams<TFromAdapterCapabilities>): Promise<EarnWithdrawResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | `WithdrawParams<TFromAdapterCapabilities>` | Withdrawal parameters |

**Returns**

[`Promise<EarnWithdrawResult>`](#earnwithdrawresult)

#### EarnWithdrawResult

Result of a withdrawal operation returned by EarningProvider.withdraw.

Contains the confirmed on-chain transaction hash and explorer URL alongside the
vault and withdrawal amount.

```typescript theme={null}
interface EarnWithdrawResult {
  readonly txHash: string;
  readonly explorerUrl: string;
  readonly vaultAddress: string;
  readonly amount: string;
}
```

**Usage Example**

```typescript theme={null}
import { AppKit, EarnChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.earn.withdraw({
  from: { adapter, chain: EarnChain.Arc_Testnet },
  vaultAddress: "0x...",
  amount: "50.00",
});
```

***

## kit.borrow Methods

`borrow` is a property on every `AppKit` instance. Call these methods as
`kit.borrow.methodName()`.

### addCollateral(params)

Supply more collateral to a loan.

```typescript theme={null}
addCollateral(params: BorrowAddCollateralParams): Promise<AddCollateralResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowAddCollateralParams`](#borrowaddcollateralparams) | Source adapter, loan id, and collateral amount |

#### BorrowAddCollateralParams

```typescript theme={null}
interface BorrowAddCollateralParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends Omit<BorrowAddCollateralQuoteParams, "chain"> {
  readonly from: AdapterContext<TAdapterCapabilities>;
  readonly idempotencyKey?: string | undefined;
}
```

**Returns**

`Promise<AddCollateralResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.addCollateral({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  loanId: "550e8400-...",
  collateralAmount: "0.25",
});
```

***

### borrow(params)

Open a loan, or borrow more against an existing one.

```typescript theme={null}
borrow(params: BorrowParams): Promise<BorrowResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowParams`](#borrowparams) | Source adapter, market or loan id, and borrow amount |

#### BorrowParams

Parameters for atomically executing a borrow.

Exactly one of `marketId` (open a loan) or `loanId` (borrow more) applies.

```typescript theme={null}
type BorrowParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> =
  | BorrowOpenLoanParams<TAdapterCapabilities>
  | BorrowMoreParams<TAdapterCapabilities>;
```

**Returns**

[`Promise<BorrowResult>`](#borrowresult)

#### BorrowResult

Result of submitting an atomic borrow.

```typescript theme={null}
type BorrowResult =
  | ConfirmedBorrowResult
  | ConfirmedBorrowDetailsUnavailableResult
  | SubmittedBorrowResult;
```

#### BorrowMoreParams

Parameters for borrowing more against an existing loan.

```typescript theme={null}
interface BorrowMoreParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends BorrowParamsBase<TAdapterCapabilities> {
  readonly loanId: string;
  readonly marketId?: never;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| borrowAmount | string | Loan asset amount to borrow, in human-readable decimal format. |
| config | BorrowServiceConfig | Per-request Borrow Service configuration. |
| from | `AdapterContext` | Wallet adapter, chain, and optional developer-controlled address. |
| idempotencyKey | string | Stable key to reuse when retrying the same borrow request. |
| loanId | string | Loan to borrow more against; its market comes from the loan. |
| marketId | never | |
| slippageBps | number | Slippage tolerance in basis points bounding the service-sized legs.<br /><br /> Omitting it applies Borrow Service's default of 300 bps. `0` is honored as no drift buffer, not read as unset, so the service sizes collateral exactly. Pick it only for exact-or-fail behaviour, since a position that moves between the quote and execution can then make the write revert. |

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.borrow({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  marketId: "0x...",
  borrowAmount: "100.00",
});
```

***

### claimRewards(params)

Claim the borrow rewards accrued by a wallet.

```typescript theme={null}
claimRewards(params: ClaimRewardsParams<TFromAdapterCapabilities>): Promise<BorrowClaimRewardsResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowClaimRewardsParams`](#borrowclaimrewardsparams) | Source adapter context for the claiming wallet |

#### BorrowClaimRewardsParams

```typescript theme={null}
interface BorrowClaimRewardsParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  readonly from: BorrowAdapterContext<TFromAdapterCapabilities>;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

[`Promise<BorrowClaimRewardsResult>`](#borrowclaimrewardsresult)

#### BorrowClaimRewardsResult

Kit-level result of a claim rewards operation.

```typescript theme={null}
type BorrowClaimRewardsResult =
  BorrowNoClaimableRewardsResult | BorrowClaimedRewardsResult;
```

#### BorrowClaimedRewardsResult

Kit-level result after claimable rewards are submitted on-chain.

```typescript theme={null}
interface BorrowClaimedRewardsResult {
  readonly status: "claimed";
  readonly rewards: readonly BorrowClaimedAmount[];
  readonly txHash: string;
  readonly explorerUrl: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| explorerUrl | string | Explorer URL for the confirmed on-chain transaction. |
| rewards | readonly BorrowClaimedAmount\[] | Reward token amounts that were claimed. |
| status | `'claimed'` | Discriminates the successful on-chain claim result. |
| txHash | string | Confirmed on-chain transaction hash. |

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.claimRewards({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
});
```

***

### closeLoan(params)

Repay a loan in full and release its collateral.

```typescript theme={null}
closeLoan(params: BorrowCloseLoanParams): Promise<CloseLoanResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowCloseLoanParams`](#borrowcloseloanparams) | Source adapter and loan id |

#### BorrowCloseLoanParams

```typescript theme={null}
interface BorrowCloseLoanParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends Omit<BorrowCloseLoanQuoteParams, "chain"> {
  readonly from: AdapterContext<TAdapterCapabilities>;
  readonly idempotencyKey?: string | undefined;
}
```

**Returns**

`Promise<CloseLoanResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.closeLoan({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  loanId: "550e8400-...",
});
```

***

### exploreMarkets(params)

Discover the markets available on a chain.

```typescript theme={null}
exploreMarkets(params: BorrowExploreMarketsParams): Promise<ExploreMarketsResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowExploreMarketsParams`](#borrowexploremarketsparams) | Chain, optional filters, and pagination |

#### BorrowExploreMarketsParams

```typescript theme={null}
interface BorrowExploreMarketsParams {
  readonly chain: ChainIdentifier;
  readonly minLltv?: string | undefined;
  readonly maxLltv?: string | undefined;
  readonly minBorrow?: string | undefined;
  readonly maxBorrow?: string | undefined;
  readonly sortBy?: BorrowMarketSortBy | undefined;
  readonly pageSize?: number | undefined;
  readonly pageAfter?: string | undefined;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<ExploreMarketsResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.exploreMarkets({
  chain: BorrowChain.Arc_Testnet,
  sortBy: "borrowApy",
});
```

***

### exploreMarketsIterator(params)

Lazily iterate every market available on a chain.

Prefer this over AppKitBorrowOperations.exploreMarkets when rendering a full
list: the iterator walks the service's pages, so the call site does not change
when the market count outgrows a single page.

```typescript theme={null}
exploreMarketsIterator(params: BorrowExploreMarketsIteratorParams): AsyncGenerator<MarketInfo, void, undefined>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowExploreMarketsIteratorParams`](#borrowexploremarketsiteratorparams) | Discovery parameters (no `pageAfter`; the iterator manages it) |

#### BorrowExploreMarketsIteratorParams

```typescript theme={null}
type BorrowExploreMarketsIteratorParams = Omit<
  BorrowExploreMarketsParams,
  "pageAfter"
>;
```

**Returns**

`AsyncGenerator<MarketInfo, void, undefined>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
for await (const market of kit.borrow.exploreMarketsIterator({
  chain: BorrowChain.Arc_Testnet,
})) {
  console.log(market.marketId);
}
```

***

### getAddCollateralQuote(params)

Price a collateral addition.

```typescript theme={null}
getAddCollateralQuote(params: BorrowAddCollateralQuoteParams): Promise<AddCollateralQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowAddCollateralQuoteParams`](#borrowaddcollateralquoteparams) | Loan id, chain, and collateral amount |

#### BorrowAddCollateralQuoteParams

```typescript theme={null}
interface BorrowAddCollateralQuoteParams {
  readonly loanId: string;
  readonly chain: ChainIdentifier;
  readonly collateralAmount: string;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<AddCollateralQuote>`

***

### getBorrowQuote(params)

Price a borrow before signing it.

```typescript theme={null}
getBorrowQuote(params: BorrowQuoteParams): Promise<BorrowQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowQuoteParams`](#borrowquoteparams) | Market and owner for a new loan, or the id of an existing one |

#### BorrowQuoteParams

Parameters for previewing a borrow.

Supply either a loan ID to preview borrowing more, or the complete owner, chain,
and market tuple to preview opening a loan.

```typescript theme={null}
type BorrowQuoteParams = BorrowOpenLoanQuoteParams | BorrowMoreQuoteParams;
```

**Returns**

[`Promise<BorrowQuote>`](#borrowquote)

#### BorrowMoreQuoteParams

Parameters for previewing a borrow against an existing loan.

```typescript theme={null}
interface BorrowMoreQuoteParams extends BorrowQuoteParamsBase {
  readonly loanId: string;
  readonly walletAddress?: never;
  readonly chain?: never;
  readonly marketId?: never;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| borrowAmount | string | Loan asset amount to price, in human-readable decimal format. |
| chain | never | |
| config | BorrowServiceConfig | Per-request Borrow Service configuration. |
| loanId | string | Existing loan whose owner, chain, and market the service resolves. |
| marketId | never | |
| slippageBps | number | Slippage tolerance in basis points bounding the service-sized legs. |
| walletAddress | never | |

#### BorrowQuote

Quote for opening a loan or borrowing more against one.

`collateralAmount` is the collateral the service sized for the borrow, not an
echo of a caller input.

```typescript theme={null}
interface BorrowQuote {
  readonly chain: `${Blockchain}`;
  readonly collateralAmount: BorrowAssetAmount;
  readonly loanAssetAmount: BorrowAssetAmount;
  readonly borrowApy: number | null;
  readonly fees: readonly BorrowFee[];
  readonly gasFees: readonly BorrowQuoteGasFee[];
  readonly resultingHealthFactor: number | null;
  readonly resultingLtv: number | null;
  readonly resultingBand: BorrowHealthFactorBand;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| borrowApy | `number \| null` | The market's borrow APY at quote time. |
| chain | `${Blockchain}` | |
| collateralAmount | BorrowAssetAmount | Collateral the borrow would pull, as sized by the service. |
| fees | readonly BorrowFee\[] | |
| gasFees | readonly BorrowQuoteGasFee\[] | |
| liquidationPrice | `BorrowAssetAmount \| null` | |
| loanAssetAmount | BorrowAssetAmount | Loan asset amount the quote priced. |
| resultingBand | BorrowHealthFactorBand | |
| resultingHealthFactor | `number \| null` | |
| resultingLtv | `number \| null` | |

#### BorrowQuoteGasFee

```typescript theme={null}
interface BorrowQuoteGasFee {
  readonly name: string;
  readonly fees: BorrowQuoteGas;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| fees | BorrowQuoteGas | |
| name | string | |

#### BorrowQuoteGas

Gas estimate for one quote action.

`gas` is a decimal string of gas units passed through from the service.
`gasPrice` and `fee` are decimal strings of native-wei integers.

```typescript theme={null}
interface BorrowQuoteGas {
  readonly gas: string;
  readonly gasPrice: string;
  readonly fee: string;
}
```

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const quote = await kit.borrow.getBorrowQuote({
  walletAddress: "0x...",
  chain: BorrowChain.Arc_Testnet,
  marketId: "0x...",
  borrowAmount: "100.00",
});
```

***

### getClaimRewardsQuote(params)

Price a borrow rewards claim.

```typescript theme={null}
getClaimRewardsQuote(params: GetClaimRewardsQuoteParams<TFromAdapterCapabilities>): Promise<BorrowClaimRewardsQuoteInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowGetClaimRewardsQuoteParams`](#borrowgetclaimrewardsquoteparams) | Source adapter context for the claiming wallet |

#### BorrowGetClaimRewardsQuoteParams

```typescript theme={null}
interface BorrowGetClaimRewardsQuoteParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  readonly from: BorrowAdapterContext<TFromAdapterCapabilities>;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

[`Promise<BorrowClaimRewardsQuoteInfo>`](#borrowclaimrewardsquoteinfo)

#### BorrowClaimRewardsQuoteInfo

Kit-level result of a claimable-rewards read.

```typescript theme={null}
interface BorrowClaimRewardsQuoteInfo {
  readonly rewards: readonly BorrowClaimedAmount[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| rewards | readonly BorrowClaimedAmount\[] | Reward tokens currently available for claiming. |

***

### getCloseLoanQuote(params)

Price a full loan close.

```typescript theme={null}
getCloseLoanQuote(params: BorrowCloseLoanQuoteParams): Promise<CloseLoanQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowCloseLoanQuoteParams`](#borrowcloseloanquoteparams) | Loan id, chain, and optional slippage bound |

#### BorrowCloseLoanQuoteParams

```typescript theme={null}
interface BorrowCloseLoanQuoteParams {
  readonly loanId: string;
  readonly chain: ChainIdentifier;
  readonly slippageBps?: number | undefined;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<CloseLoanQuote>`

***

### getIntegratorConfig(params)

Read the integrator fee configuration for the calling API key.

Requires an API key in `params.config.apiKey`; the call throws
`INPUT_VALIDATION_FAILED` without one. The key is server-only.

```typescript theme={null}
getIntegratorConfig(params?: BorrowGetIntegratorConfigParams): Promise<IntegratorConfig>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowGetIntegratorConfigParams`](#borrowgetintegratorconfigparams) | Per-request Borrow Service configuration carrying `config.apiKey`. |

#### BorrowGetIntegratorConfigParams

```typescript theme={null}
interface BorrowGetIntegratorConfigParams {
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<IntegratorConfig>`

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();
const config = await kit.borrow.getIntegratorConfig({
  config: { apiKey: process.env.CIRCLE_API_KEY as string },
});
```

***

### getLoans(params)

List the loans an address owns on a chain.

```typescript theme={null}
getLoans(params: BorrowGetLoansParams): Promise<ListLoansResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowGetLoansParams`](#borrowgetloansparams) | Owner address, chain, and optional pagination |

#### BorrowGetLoansParams

```typescript theme={null}
interface BorrowGetLoansParams {
  readonly walletAddress: string;
  readonly chain: ChainIdentifier;
  readonly pageSize?: number | undefined;
  readonly pageAfter?: string | undefined;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<ListLoansResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.getLoans({
  walletAddress: "0x...",
  chain: BorrowChain.Arc_Testnet,
});
```

***

### getMarket(params)

Fetch a single market by id.

```typescript theme={null}
getMarket(params: BorrowGetMarketParams): Promise<MarketInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowGetMarketParams`](#borrowgetmarketparams) | Chain and market id |

#### BorrowGetMarketParams

```typescript theme={null}
interface BorrowGetMarketParams {
  readonly chain: ChainIdentifier;
  readonly marketId: string;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<MarketInfo>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const market = await kit.borrow.getMarket({
  chain: BorrowChain.Arc_Testnet,
  marketId: "0x...",
});
```

***

### getMaxBorrow(params)

Size the largest borrow a collateral amount supports.

```typescript theme={null}
getMaxBorrow(params: MaxBorrowParams): Promise<MaxBorrowQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`MaxBorrowParams`](#maxborrowparams) | Chain, market, and collateral amount |

#### MaxBorrowParams

Parameters for previewing what a collateral amount can borrow.

```typescript theme={null}
interface MaxBorrowParams extends BorrowPreviewParamsBase {
  readonly collateralAmount: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| chain | ChainIdentifier | Chain the market lives on. |
| collateralAmount | string | Collateral amount to borrow against, in human-readable decimal format. |
| config | BorrowServiceConfig | Per-request Borrow Service configuration. |
| marketId | string | Market to price the preview in. |

**Returns**

[`Promise<MaxBorrowQuote>`](#maxborrowquote)

#### MaxBorrowQuote

The most a collateral amount can borrow, and the health that leaves.

```typescript theme={null}
interface MaxBorrowQuote {
  readonly chain: `${Blockchain}`;
  readonly maxBorrowAmount: BorrowAssetAmount;
  readonly resultingHealthFactor: number | null;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| chain | `${Blockchain}` | |
| liquidationPrice | `BorrowAssetAmount \| null` | |
| maxBorrowAmount | BorrowAssetAmount | Largest loan asset amount the collateral supports. |
| resultingHealthFactor | `number \| null` | |

***

### getPosition(params)

Fetch a single loan by id.

```typescript theme={null}
getPosition(params: BorrowGetPositionParams): Promise<BorrowLoanInfo>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowGetPositionParams`](#borrowgetpositionparams) | The loan id to look up |

#### BorrowGetPositionParams

```typescript theme={null}
interface BorrowGetPositionParams {
  readonly loanId: string;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

[`Promise<BorrowLoanInfo>`](#borrowloaninfo)

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();
const loan = await kit.borrow.getPosition({ loanId: "550e8400-..." });
```

***

### getRepayQuote(params)

Price a partial repayment.

```typescript theme={null}
getRepayQuote(params: BorrowRepayQuoteParams): Promise<RepayQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowRepayQuoteParams`](#borrowrepayquoteparams) | Loan id, chain, and repayment amount |

#### BorrowRepayQuoteParams

```typescript theme={null}
interface BorrowRepayQuoteParams {
  readonly loanId: string;
  readonly chain: ChainIdentifier;
  readonly repayAmount: string;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<RepayQuote>`

***

### getRequiredCollateral(params)

Size the collateral a borrow needs to reach a target health factor.

```typescript theme={null}
getRequiredCollateral(params: BorrowRequiredCollateralParams): Promise<RequiredCollateralQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowRequiredCollateralParams`](#borrowrequiredcollateralparams) | Chain, market, borrow amount, and target health factor |

#### BorrowRequiredCollateralParams

```typescript theme={null}
interface BorrowRequiredCollateralParams extends BorrowPreviewParamsBase {
  readonly borrowAmount: string;
  readonly targetHealthFactor: number;
}
```

**Returns**

`Promise<RequiredCollateralQuote>`

***

### getWithdrawCollateralRepayIfNeededQuote(params)

Price a collateral withdrawal.

```typescript theme={null}
getWithdrawCollateralRepayIfNeededQuote(params: BorrowWithdrawCollateralQuoteParams): Promise<WithdrawCollateralQuote>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowWithdrawCollateralQuoteParams`](#borrowwithdrawcollateralquoteparams) | Loan id, chain, and collateral amount |

#### BorrowWithdrawCollateralQuoteParams

```typescript theme={null}
interface BorrowWithdrawCollateralQuoteParams {
  readonly loanId: string;
  readonly chain: ChainIdentifier;
  readonly collateralAmount: string;
  readonly slippageBps?: number | undefined;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<WithdrawCollateralQuote>`

***

### registerWebhook(params)

Register, or unset, the webhook callback for a loan.

```typescript theme={null}
registerWebhook(params: RegisterWebhookParams<TFromAdapterCapabilities>): Promise<RegisterWebhookResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowRegisterWebhookParams`](#borrowregisterwebhookparams) | Owner adapter context, loan id, and callback URL |

#### BorrowRegisterWebhookParams

```typescript theme={null}
interface BorrowRegisterWebhookParams<
  TFromAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> {
  readonly from: BorrowAdapterContext<TFromAdapterCapabilities>;
  readonly loanId: string;
  readonly webhookUrl?: string | null | undefined;
  readonly deadline?: number | undefined;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<RegisterWebhookResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.registerWebhook({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  loanId: "550e8400-...",
  webhookUrl: "https://example.com/loans",
});
```

***

### repay(params)

Repay part of a loan.

```typescript theme={null}
repay(params: BorrowRepayParams): Promise<RepayResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowRepayParams`](#borrowrepayparams) | Source adapter, loan id, and repayment amount |

#### BorrowRepayParams

```typescript theme={null}
interface BorrowRepayParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends Omit<BorrowRepayQuoteParams, "chain"> {
  readonly from: AdapterContext<TAdapterCapabilities>;
  readonly idempotencyKey?: string | undefined;
}
```

**Returns**

`Promise<RepayResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.repay({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  loanId: "550e8400-...",
  repayAmount: "25.00",
});
```

***

### retry(error)

Resume a borrow write that failed partway through.

Pass the error caught from `borrow`, `repay`, `closeLoan`, `addCollateral`, or
`withdrawCollateralRepayIfNeeded`. Call `isResumableError(error)` first.

```typescript theme={null}
retry(error: unknown): Promise<BorrowRetryResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| error | `unknown` | The error caught from a previous borrow write |

**Returns**

[`Promise<BorrowRetryResult>`](#borrowretryresult)

#### BorrowRetryResult

Result of retry / retryBorrow.

The variant matches the failed write: a repaid loan returns a repay result, not
a borrow result.

```typescript theme={null}
type BorrowRetryResult =
  | BorrowResult
  | BorrowRepayResult
  | BorrowAddCollateralResult
  | BorrowCloseLoanResult
  | BorrowWithdrawCollateralResult;
```

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain, isResumableError } from "@circle-fin/app-kit";

const kit = new AppKit();

try {
  await kit.borrow.borrow({
    from: { adapter, chain: BorrowChain.Arc_Testnet },
    marketId: "0x1234...",
    borrowAmount: "1000",
  });
} catch (error) {
  if (isResumableError(error)) {
    const result = await kit.borrow.retry(error);
  }
}
```

***

### setIntegratorConfig(params)

Set the integrator fee charged on borrow operations.

Requires an API key in `config.apiKey`; the call throws
`INPUT_VALIDATION_FAILED` without one. The key is server-only.

```typescript theme={null}
setIntegratorConfig(params: BorrowSetIntegratorConfigParams): Promise<IntegratorConfig>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowSetIntegratorConfigParams`](#borrowsetintegratorconfigparams) | Fee in basis points, the address that receives it, and `config.apiKey`. |

#### BorrowSetIntegratorConfigParams

```typescript theme={null}
interface BorrowSetIntegratorConfigParams {
  readonly integratorFeeBps: number;
  readonly integratorFeeAddress: string | null;
  readonly config?: BorrowServiceConfig | undefined;
}
```

**Returns**

`Promise<IntegratorConfig>`

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();
const config = await kit.borrow.setIntegratorConfig({
  integratorFeeBps: 25,
  integratorFeeAddress: "0x...",
  config: { apiKey: process.env.CIRCLE_API_KEY as string },
});
```

***

### withdrawCollateralRepayIfNeeded(params)

Release collateral from a loan.

```typescript theme={null}
withdrawCollateralRepayIfNeeded(params: BorrowWithdrawCollateralParams): Promise<WithdrawCollateralResult>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| params | [`BorrowWithdrawCollateralParams`](#borrowwithdrawcollateralparams) | Source adapter, loan id, and collateral amount |

#### BorrowWithdrawCollateralParams

```typescript theme={null}
interface BorrowWithdrawCollateralParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends Omit<BorrowWithdrawCollateralQuoteParams, "chain"> {
  readonly from: AdapterContext<TAdapterCapabilities>;
  readonly idempotencyKey?: string | undefined;
}
```

**Returns**

`Promise<WithdrawCollateralResult>`

**Usage Example**

```typescript theme={null}
import { AppKit, BorrowChain } from "@circle-fin/app-kit";

const kit = new AppKit();
const result = await kit.borrow.withdrawCollateralRepayIfNeeded({
  from: { adapter, chain: BorrowChain.Arc_Testnet },
  loanId: "550e8400-...",
  collateralAmount: "0.25",
});
```

***

## kit.onramp Methods

`onramp` is a property on every `AppKit` instance. Call these methods as
`kit.onramp.methodName()`.

### fetchSession(options)

`POST` a session request to the host-app endpoint and return the minted session.

```typescript theme={null}
fetchSession(options: FetchOnrampSessionOptions): Promise<OnrampSession>
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| options | [`FetchOnrampSessionOptions`](#fetchonrampsessionoptions) | Request options including the URL, body, and optional fetch / headers / abort signal. |

#### FetchOnrampSessionOptions

Options accepted by fetchOnrampSession.

```typescript theme={null}
interface FetchOnrampSessionOptions {
  readonly url: string;
  readonly body: OnrampSessionRequest;
  readonly headers?: Readonly<Record<string, string>>;
  readonly fetch?: typeof globalThis.fetch;
  readonly signal?: AbortSignal;
  readonly credentials?: RequestCredentials;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| body | OnrampSessionRequest | Request body forwarded to url. |
| credentials | RequestCredentials | Credentials mode for the underlying `fetch` call. Defaults to `'same-origin'` — most session endpoints are first-party. |
| fetch | typeof globalThis.fetch | Override `globalThis.fetch` for the call. Useful for SSR frameworks that intercept the global fetch, or for test fixtures. |
| headers | `Readonly` | Extra request headers (e.g. CSRF token, auth bearer). `Content-Type` and `Accept` are managed by the helper. |
| signal | AbortSignal | Forward an `AbortSignal` so the host can cancel the in-flight request (e.g. on component unmount). |
| url | string | URL of the host-app endpoint that mints onramp sessions. |

**Returns**

[`Promise<OnrampSession>`](#onrampsession)

**Usage Example**

```typescript theme={null}
const session = await kit.onramp.fetchSession({
  url: "/api/onramp/sessions",
  body: { appUserId: "usr_1", destinationAddress: "0x..." },
});
```

***

### mountIframe(options)

Mount the onramp widget inline into a host DOM element.

```typescript theme={null}
mountIframe(options: OnrampIframeOptions): OnrampWidget
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| options | [`OnrampIframeOptions`](#onrampiframeoptions) | Launch options including the session, container element, and lifecycle callbacks. |

#### OnrampIframeOptions

Iframe-only launch options.

```typescript theme={null}
interface OnrampIframeOptions extends OnrampLifecycleOptions {
  readonly container: HTMLElement;
  readonly title?: string | undefined;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| container | HTMLElement | Host DOM element to mount the iframe into. |
| loadTimeout | number | Startup timeout in milliseconds. Defaults to 10 000. |
| metadata | unknown | Opaque value forwarded to every callback via the catch-all dispatch path. |
| onAnyEvent | (envelope: OnrampEventEnvelope) => void | Catch-all callback fired after the type-specific callback for every lifecycle event, in addition to any registered `widget.on(...)` subscribers. |
| onDepositNotCompleted | (envelope: OnrampDepositNotCompletedEnvelope) => void | Fires when the deposit flow ends without a settled deposit (timeout, cancel, KYC reject, provider error, …). |
| onDepositSettled | (envelope: OnrampDepositSettledEnvelope) => void | Fires when a previously submitted deposit settles on-chain. |
| onDepositSubmitted | (envelope: OnrampDepositSubmittedEnvelope) => void | Fires when the customer submits a deposit. May or may not be followed by `DEPOSIT_SETTLED` — inspect `envelope.payload.settlementExpected`. |
| onHandlerError | (err: unknown) => void | Reporter for lifecycle callbacks (and `widget.on(...)` subscribers) that throw. Defaults to a silent no-op. |
| onInitializationError | (envelope: OnrampInitializationErrorEnvelope) => void | Fires when OnRamp could not start. |
| onInitializationSuccess | (envelope: OnrampInitializationSuccessEnvelope) => void | Fires once OnRamp finishes initialising and the session token has been accepted. |
| onSessionExpired | `(envelope: OnrampDepositNotCompletedEnvelope \| OnrampInitializationErrorEnvelope) => void` | Fires when the current session is no longer usable and the host must mint a new one before showing the widget again. |
| session | OnrampSession | Session minted by the server kit. |
| title | `string \| undefined` | Optional iframe `title` attribute. Defaults to `'Circle Onramp'`. |

**Returns**

[`OnrampWidget`](#onrampwidget)

**Usage Example**

```typescript theme={null}
const widget = kit.onramp.mountIframe({
  session,
  container: document.getElementById("onramp-root")!,
  onDepositSettled: (envelope) => console.log(envelope.payload),
});
```

***

### openWindow(options)

Open the onramp widget in a popup window.

```typescript theme={null}
openWindow(options: OnrampWindowOptions): OnrampWindowResult
```

**Parameters**

| Name | Type | Description |
| - | - | - |
| options | [`OnrampWindowOptions`](#onrampwindowoptions) | Launch options including the session and lifecycle callbacks. |

#### OnrampWindowOptions

Window-only launch options.

```typescript theme={null}
interface OnrampWindowOptions extends OnrampLifecycleOptions {
  readonly target?: string | undefined;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| loadTimeout | number | Startup timeout in milliseconds. Defaults to 10 000. |
| metadata | unknown | Opaque value forwarded to every callback via the catch-all dispatch path. |
| onAnyEvent | (envelope: OnrampEventEnvelope) => void | Catch-all callback fired after the type-specific callback for every lifecycle event, in addition to any registered `widget.on(...)` subscribers. |
| onDepositNotCompleted | (envelope: OnrampDepositNotCompletedEnvelope) => void | Fires when the deposit flow ends without a settled deposit (timeout, cancel, KYC reject, provider error, …). |
| onDepositSettled | (envelope: OnrampDepositSettledEnvelope) => void | Fires when a previously submitted deposit settles on-chain. |
| onDepositSubmitted | (envelope: OnrampDepositSubmittedEnvelope) => void | Fires when the customer submits a deposit. May or may not be followed by `DEPOSIT_SETTLED` — inspect `envelope.payload.settlementExpected`. |
| onHandlerError | (err: unknown) => void | Reporter for lifecycle callbacks (and `widget.on(...)` subscribers) that throw. Defaults to a silent no-op. |
| onInitializationError | (envelope: OnrampInitializationErrorEnvelope) => void | Fires when OnRamp could not start. |
| onInitializationSuccess | (envelope: OnrampInitializationSuccessEnvelope) => void | Fires once OnRamp finishes initialising and the session token has been accepted. |
| onSessionExpired | `(envelope: OnrampDepositNotCompletedEnvelope \| OnrampInitializationErrorEnvelope) => void` | Fires when the current session is no longer usable and the host must mint a new one before showing the widget again. |
| session | OnrampSession | Session minted by the server kit. |
| target | `string \| undefined` | `window.open` target name. Defaults to `'circle-onramp'`. |

**Returns**

[`OnrampWindowResult`](#onrampwindowresult)

#### OnrampWindowResult

Discriminated result of `onrampKit.openWindow()`.

```typescript theme={null}
type OnrampWindowResult =
  | {
      readonly status: "opened";
      readonly widget: OnrampWidget;
    }
  | {
      readonly status: "blocked";
      readonly reason: OnrampWindowBlockedReason;
      readonly errorMessage: string;
    };
```

**Usage Example**

```typescript theme={null}
button.onclick = () => {
  const result = kit.onramp.openWindow({ session });
  if (result.status === "blocked") {
    showRetryDialog(result.errorMessage);
    return;
  }
  result.widget.on("DEPOSIT_SETTLED", (e) => console.log(e.payload));
};
```

***

## Supporting Types

### Common

#### AdapterContext

Represents the context of an adapter used for crosschain operations.

An AdapterContext must always specify both the adapter and the chain explicitly.
The address field behavior is determined by the adapter's address control model:

* Developer-controlled adapters: The `address` field is required because each
  operation must explicitly specify which address to use.
* User-controlled adapters: The `address` field is forbidden because the address
  is automatically resolved from the connected wallet or signer.
* Legacy adapters: The `address` field remains optional for backward
  compatibility.

This ensures clear, debuggable code where the intended chain is always visible
at the call site, and address requirements are enforced at compile time based on
adapter capabilities.

```typescript theme={null}
type AdapterContext = {
  adapter: Adapter<TAdapterCapabilities>;
  chain: TChainIdentifier;
} & AddressField<ExtractAddressContext<TAdapterCapabilities>>;
```

**Properties**

| Name | Type | Description |
| - | - | - |
| adapter | `Adapter<TAdapterCapabilities>` | The adapter instance for blockchain operations |
| chain | TChainIdentifier | The chain reference, which can be a ChainDefinition, Blockchain enum, or string literal |

***

#### Amount

An immutable token amount with fluent API methods.

```typescript theme={null}
interface Amount {
  readonly raw: bigint;
  readonly decimals: number;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| decimals | number | Number of decimal places for this token. |
| raw | bigint | The raw value in smallest units (e.g., wei for ETH, micro-units for USDC). |
| abs | unknown | |
| add | unknown | |
| compare | unknown | |
| div | unknown | |
| eq | unknown | |
| formatted | unknown | |
| gt | unknown | |
| gte | unknown | |
| isNegative | unknown | |
| isPositive | unknown | |
| isZero | unknown | |
| lt | unknown | |
| lte | unknown | |
| max | unknown | |
| min | unknown | |
| mul | unknown | |
| neg | unknown | |
| sub | unknown | |
| toDecimals | unknown | |
| toJSON | unknown | |
| toString | unknown | |
| from | unknown | |
| fromJSON | unknown | |
| isAmount | unknown | |
| of | unknown | |
| parse | unknown | |
| sum | unknown | |
| zero | unknown | |

***

#### DeveloperFeeHooks

```typescript theme={null}
interface DeveloperFeeHooks {
  getFee: (params: BridgeParams) => bigint \| Promise<bigint>
  getFeeRecipient: (chain: ChainDefinition) => string \| Promise<string>
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| getFee | `(params: BridgeParams) => bigint \| Promise<bigint>` | Returns the developer fee in USDC's smallest units (e.g. 6 decimals). |
| getFeeRecipient | `(chain: ChainDefinition) => string \| Promise<string>` | Returns the fee recipient for the given chain. |

***

#### KitError

Structured error details with consistent properties for programmatic handling.

This interface provides a standardized format for all errors in the App Kits
system, enabling developers to handle different error types consistently and
provide appropriate user feedback.

```typescript theme={null}
class KitError extends Error implements ErrorDetails {
  public readonly code!: number;
  public override readonly name!: string;
  public readonly type!: ErrorType;
  public readonly recoverability!: Recoverability;
  public override readonly cause?: {
    trace?: unknown;
  };
  constructor(details: ErrorDetails) {
    let message = details.message;
    if (message.length > MAX_MESSAGE_LENGTH) {
      message = `${message.slice(0, MAX_MESSAGE_LENGTH - 3)}...`;
    }
    const truncatedDetails = { ...details, message };
    const validatedDetails = validateErrorDetails(truncatedDetails);
    super(validatedDetails.message);
    Object.defineProperties(this, {
      [KIT_ERROR_BRAND]: {
        value: true,
        writable: false,
        enumerable: false,
        configurable: false,
      },
      name: {
        value: validatedDetails.name,
        writable: false,
        enumerable: true,
        configurable: false,
      },
      code: {
        value: validatedDetails.code,
        writable: false,
        enumerable: true,
        configurable: false,
      },
      type: {
        value: validatedDetails.type,
        writable: false,
        enumerable: true,
        configurable: false,
      },
      recoverability: {
        value: validatedDetails.recoverability,
        writable: false,
        enumerable: true,
        configurable: false,
      },
      ...(validatedDetails.cause && {
        cause: {
          value: validatedDetails.cause,
          writable: false,
          enumerable: true,
          configurable: false,
        },
      }),
    });
  }
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| constructor | unknown | |
| cause | `{ trace?: unknown }` | Raw error details, context, or the original error that caused this one. |
| code | number | Numeric identifier following standardized ranges (1000+ for INPUT errors) |
| message | string | User-friendly explanation with context |
| name | string | Human-readable ID (e.g., "NETWORK\_MISMATCH") |
| recoverability | `'RETRYABLE' \| 'RESUMABLE' \| 'FATAL'` | Error handling strategy |
| stack | string | |
| type | `'INPUT' \| 'BALANCE' \| 'ONCHAIN' \| 'RPC' \| 'NETWORK' \| 'RATE_LIMIT' \| 'SERVICE' \| 'LIQUIDITY' \| 'UNKNOWN'` | Error category indicating where the error originated |
| stackTraceLimit | number | The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`).<br /><br /> The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.<br /><br /> If set to a non-number value, or set to a negative number, stack traces will not capture any frames. |
| captureStackTrace | unknown | |
| prepareStackTrace | unknown | |

***

### Chains

#### BaseChainDefinition

Base information that all chain definitions must include.

```typescript theme={null}
interface BaseChainDefinition {
  chain: Blockchain;
  name: string;
  title?: string;
  nativeCurrency: Currency;
  isTestnet: boolean;
  explorerUrl: string;
  rpcEndpoints: readonly string[];
  eurcAddress: string | null;
  usdcAddress: string | null;
  usdtAddress: string | null;
  cctp: CCTPConfig | null;
  kitContracts?: KitContracts;
  cctpx?: CCTPXChainConfig;
  gateway?: GatewayConfig;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| cctp | `CCTPConfig \| null` | Optional CCTP configuration. |
| cctpx | CCTPXChainConfig | Optional CCTPx configuration. |
| chain | Blockchain | The blockchain identifier from the Blockchain enum. |
| eurcAddress | `string \| null` | The contract address for EURC. |
| explorerUrl | string | Template URL for the blockchain explorer to view transactions. |
| gateway | GatewayConfig | Optional Gateway contract configuration for Gateway protocol support. |
| isTestnet | boolean | Indicates whether this is a testnet or mainnet. |
| kitContracts | KitContracts | Optional kit-specific contract addresses for enhanced chain functionality. |
| name | string | The display name of the blockchain. |
| nativeCurrency | Currency | Information about the native currency of the blockchain. |
| rpcEndpoints | readonly string\[] | Default RPC endpoints for connecting to the blockchain network. |
| title | string | Optional title or alternative name for the blockchain. |
| usdcAddress | `string \| null` | The contract address for USDC. |
| usdtAddress | `string \| null` | The contract address for USDT. |

***

#### Blockchain

Enumeration of all blockchains known to this library.

This enum contains every blockchain that has a chain definition, regardless of
whether bridging is currently supported. For chains that support bridging via
CCTPv2, see BridgeChain.

```typescript theme={null}
enum Blockchain {
  Algorand = 'Algorand'
  Algorand_Testnet = 'Algorand_Testnet'
  Aptos = 'Aptos'
  Aptos_Testnet = 'Aptos_Testnet'
  Arbitrum = 'Arbitrum'
  Arbitrum_Sepolia = 'Arbitrum_Sepolia'
  Arc = 'Arc'
  Arc_Testnet = 'Arc_Testnet'
  Avalanche = 'Avalanche'
  Avalanche_Fuji = 'Avalanche_Fuji'
  Base = 'Base'
  Base_Sepolia = 'Base_Sepolia'
  Celo = 'Celo'
  Celo_Alfajores_Testnet = 'Celo_Alfajores_Testnet'
  Codex = 'Codex'
  Codex_Testnet = 'Codex_Testnet'
  Cronos = 'Cronos'
  Cronos_Testnet = 'Cronos_Testnet'
  Edge = 'Edge'
  Edge_Testnet = 'Edge_Testnet'
  Ethereum = 'Ethereum'
  Ethereum_Sepolia = 'Ethereum_Sepolia'
  Hedera = 'Hedera'
  Hedera_Testnet = 'Hedera_Testnet'
  HyperEVM = 'HyperEVM'
  HyperEVM_Testnet = 'HyperEVM_Testnet'
  Injective = 'Injective'
  Injective_Testnet = 'Injective_Testnet'
  Ink = 'Ink'
  Ink_Testnet = 'Ink_Testnet'
  Linea = 'Linea'
  Linea_Sepolia = 'Linea_Sepolia'
  Monad = 'Monad'
  Monad_Testnet = 'Monad_Testnet'
  Morph = 'Morph'
  Morph_Testnet = 'Morph_Testnet'
  NEAR = 'NEAR'
  NEAR_Testnet = 'NEAR_Testnet'
  Noble = 'Noble'
  Noble_Testnet = 'Noble_Testnet'
  Optimism = 'Optimism'
  Optimism_Sepolia = 'Optimism_Sepolia'
  Pharos = 'Pharos'
  Pharos_Testnet = 'Pharos_Testnet'
  Plasma = 'Plasma'
  Plasma_Testnet = 'Plasma_Testnet'
  Plume = 'Plume'
  Plume_Testnet = 'Plume_Testnet'
  Polkadot_Asset_Hub = 'Polkadot_Asset_Hub'
  Polkadot_Westmint = 'Polkadot_Westmint'
  Polygon = 'Polygon'
  Polygon_Amoy_Testnet = 'Polygon_Amoy_Testnet'
  Sei = 'Sei'
  Sei_Testnet = 'Sei_Testnet'
  Solana = 'Solana'
  Solana_Devnet = 'Solana_Devnet'
  Sonic = 'Sonic'
  Sonic_Testnet = 'Sonic_Testnet'
  Stellar = 'Stellar'
  Stellar_Testnet = 'Stellar_Testnet'
  Sui = 'Sui'
  Sui_Testnet = 'Sui_Testnet'
  Unichain = 'Unichain'
  Unichain_Sepolia = 'Unichain_Sepolia'
  World_Chain = 'World_Chain'
  World_Chain_Sepolia = 'World_Chain_Sepolia'
  X_Layer = 'X_Layer'
  X_Layer_Testnet = 'X_Layer_Testnet'
  XDC = 'XDC'
  XDC_Apothem = 'XDC_Apothem'
  ZKSync_Era = 'ZKSync_Era'
  ZKSync_Sepolia = 'ZKSync_Sepolia'
}
```

**Values**

`Algorand`, `Algorand_Testnet`, `Aptos`, `Aptos_Testnet`, `Arbitrum`,
`Arbitrum_Sepolia`, `Arc`, `Arc_Testnet`, `Avalanche`, `Avalanche_Fuji`, `Base`,
`Base_Sepolia`, `Celo`, `Celo_Alfajores_Testnet`, `Codex`, `Codex_Testnet`,
`Cronos`, `Cronos_Testnet`, `Edge`, `Edge_Testnet`, `Ethereum`,
`Ethereum_Sepolia`, `Hedera`, `Hedera_Testnet`, `HyperEVM`, `HyperEVM_Testnet`,
`Injective`, `Injective_Testnet`, `Ink`, `Ink_Testnet`, `Linea`,
`Linea_Sepolia`, `Monad`, `Monad_Testnet`, `Morph`, `Morph_Testnet`, `NEAR`,
`NEAR_Testnet`, `Noble`, `Noble_Testnet`, `Optimism`, `Optimism_Sepolia`,
`Pharos`, `Pharos_Testnet`, `Plasma`, `Plasma_Testnet`, `Plume`,
`Plume_Testnet`, `Polkadot_Asset_Hub`, `Polkadot_Westmint`, `Polygon`,
`Polygon_Amoy_Testnet`, `Sei`, `Sei_Testnet`, `Solana`, `Solana_Devnet`,
`Sonic`, `Sonic_Testnet`, `Stellar`, `Stellar_Testnet`, `Sui`, `Sui_Testnet`,
`Unichain`, `Unichain_Sepolia`, `World_Chain`, `World_Chain_Sepolia`, `X_Layer`,
`X_Layer_Testnet`, `XDC`, `XDC_Apothem`, `ZKSync_Era`, `ZKSync_Sepolia`

***

#### ChainDefinition

Public chain definition type.

```typescript theme={null}
type ChainDefinition = EVMChainDefinition | NonEVMChainDefinition;
```

***

#### ChainIdentifier

```typescript theme={null}
type ChainIdentifier = ChainDefinition | Blockchain | `${Blockchain}`;
```

***

#### Currency

Represents basic information about a currency or token.

```typescript theme={null}
interface Currency {
  name: string;
  symbol: string;
  decimals: number;
}
```

***

#### EVMChainDefinition

Represents chain definitions for Ethereum Virtual Machine (EVM) compatible
blockchains.

```typescript theme={null}
interface EVMChainDefinition extends BaseChainDefinition {
  type: "evm";
  chainId: number;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| cctp | `CCTPConfig \| null` | Optional CCTP configuration. |
| cctpx | CCTPXChainConfig | Optional CCTPx configuration. |
| chain | Blockchain | The blockchain identifier from the Blockchain enum. |
| chainId | number | The unique identifier for the blockchain. |
| eurcAddress | `string \| null` | The contract address for EURC. |
| explorerUrl | string | Template URL for the blockchain explorer to view transactions. |
| gateway | GatewayConfig | Optional Gateway contract configuration for Gateway protocol support. |
| isTestnet | boolean | Indicates whether this is a testnet or mainnet. |
| kitContracts | `Partial<Record<KitContractType, string>>` | Optional kit-specific contract addresses for enhanced chain functionality. |
| name | string | The display name of the blockchain. |
| nativeCurrency | Currency | Information about the native currency of the blockchain. |
| rpcEndpoints | readonly string\[] | Default RPC endpoints for connecting to the blockchain network. |
| title | string | Optional title or alternative name for the blockchain. |
| type | `'evm'` | Discriminator for EVM chains. |
| usdcAddress | `string \| null` | The contract address for USDC. |
| usdtAddress | `string \| null` | The contract address for USDT. |

***

#### KitContractType

Available kit contract types for enhanced chain functionality.

```typescript theme={null}
type KitContractType = "bridge" | "adapter" | "senderPreservingBatcher";
```

***

#### NonEVMChainDefinition

Represents chain definitions for non-EVM blockchains.

```typescript theme={null}
interface NonEVMChainDefinition extends BaseChainDefinition {
  type:
    | "algorand"
    | "avalanche"
    | "solana"
    | "aptos"
    | "near"
    | "stellar"
    | "sui"
    | "hedera"
    | "noble"
    | "polkadot";
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| cctp | `CCTPConfig \| null` | Optional CCTP configuration. |
| cctpx | CCTPXChainConfig | Optional CCTPx configuration. |
| chain | Blockchain | The blockchain identifier from the Blockchain enum. |
| eurcAddress | `string \| null` | The contract address for EURC. |
| explorerUrl | string | Template URL for the blockchain explorer to view transactions. |
| gateway | GatewayConfig | Optional Gateway contract configuration for Gateway protocol support. |
| isTestnet | boolean | Indicates whether this is a testnet or mainnet. |
| kitContracts | `Partial<Record<KitContractType, string>>` | Optional kit-specific contract addresses for enhanced chain functionality. |
| name | string | The display name of the blockchain. |
| nativeCurrency | Currency | Information about the native currency of the blockchain. |
| rpcEndpoints | readonly string\[] | Default RPC endpoints for connecting to the blockchain network. |
| title | string | Optional title or alternative name for the blockchain. |
| type | `'algorand' \| 'avalanche' \| 'solana' \| 'aptos' \| 'near' \| 'stellar' \| 'sui' \| 'hedera' \| 'noble' \| 'polkadot'` | Discriminator for non-EVM chains. |
| usdcAddress | `string \| null` | The contract address for USDC. |
| usdtAddress | `string \| null` | The contract address for USDT. |

***

#### TokenInfo

Represents the metadata associated with a token.

```typescript theme={null}
interface TokenInfo {
  name: string;
  symbol: string;
  decimals: number;
}
```

***

### Event Actions

#### AppKitActions

All actions available in AppKit.

```typescript theme={null}
type AppKitActions = AppKitBridgeActions &
  AppKitUnifiedBalanceActions &
  AppKitEarnActions &
  AppKitBorrowActions;
```

***

#### AppKitBorrowActions

Prefixed borrow actions for AppKit.

Borrow step events are exposed under the `borrow.` namespace (for example
`borrow.fetchParams`, `borrow.approve`, `borrow.setAuthorization`,
`borrow.execute`) so they can be subscribed to via `kit.on()` alongside bridge,
earn, and unified balance events.

```typescript theme={null}
type AppKitBorrowActions = PrefixActions<"borrow", BorrowActions>;
```

***

#### AppKitBridgeActions

Prefixed bridge actions for AppKit.

All BridgeKit events are prefixed with `bridge.` to namespace them within the
AppKit event system.

```typescript theme={null}
type AppKitBridgeActions = PrefixActions<"bridge", DefaultBridgeKitActions>;
```

***

#### AppKitEarnActions

Prefixed earn actions for AppKit.

Earn step events are exposed under the `earn.` namespace (for example
`earn.deposit`, `earn.approve`, `earn.withdraw`) so they can be subscribed to
via `kit.on()` alongside bridge and unified balance events.

```typescript theme={null}
type AppKitEarnActions = PrefixActions<"earn", EarnActions>;
```

***

#### AppKitUnifiedBalanceActions

Prefixed unified balance actions for AppKit.

All UnifiedBalanceKit (Gateway) events are prefixed with `unifiedBalance.` to
namespace them within the AppKit event system.

```typescript theme={null}
type AppKitUnifiedBalanceActions = PrefixActions<
  "unifiedBalance",
  GatewayV1Actions
>;
```

***

### Bridge

#### BridgeChain

Enumeration of blockchains that support crosschain bridging via CCTPv2.

The enum is derived from the full Blockchain enum but filtered to only include
chains with active CCTPv2 support. When new chains gain CCTPv2 support, they are
added to this enum.

```typescript theme={null}
enum BridgeChain {
  Arbitrum = 'Arbitrum'
  Arbitrum_Sepolia = 'Arbitrum_Sepolia'
  Arc = 'Arc'
  Arc_Testnet = 'Arc_Testnet'
  Avalanche = 'Avalanche'
  Avalanche_Fuji = 'Avalanche_Fuji'
  Base = 'Base'
  Base_Sepolia = 'Base_Sepolia'
  Codex = 'Codex'
  Codex_Testnet = 'Codex_Testnet'
  Cronos = 'Cronos'
  Cronos_Testnet = 'Cronos_Testnet'
  Edge = 'Edge'
  Edge_Testnet = 'Edge_Testnet'
  Ethereum = 'Ethereum'
  Ethereum_Sepolia = 'Ethereum_Sepolia'
  HyperEVM = 'HyperEVM'
  HyperEVM_Testnet = 'HyperEVM_Testnet'
  Injective = 'Injective'
  Injective_Testnet = 'Injective_Testnet'
  Ink = 'Ink'
  Ink_Testnet = 'Ink_Testnet'
  Linea = 'Linea'
  Linea_Sepolia = 'Linea_Sepolia'
  Monad = 'Monad'
  Monad_Testnet = 'Monad_Testnet'
  Morph = 'Morph'
  Morph_Testnet = 'Morph_Testnet'
  Optimism = 'Optimism'
  Optimism_Sepolia = 'Optimism_Sepolia'
  Pharos = 'Pharos'
  Pharos_Testnet = 'Pharos_Testnet'
  Plasma = 'Plasma'
  Plasma_Testnet = 'Plasma_Testnet'
  Plume = 'Plume'
  Plume_Testnet = 'Plume_Testnet'
  Polygon = 'Polygon'
  Polygon_Amoy_Testnet = 'Polygon_Amoy_Testnet'
  Sei = 'Sei'
  Sei_Testnet = 'Sei_Testnet'
  Solana = 'Solana'
  Solana_Devnet = 'Solana_Devnet'
  Sonic = 'Sonic'
  Sonic_Testnet = 'Sonic_Testnet'
  Unichain = 'Unichain'
  Unichain_Sepolia = 'Unichain_Sepolia'
  World_Chain = 'World_Chain'
  World_Chain_Sepolia = 'World_Chain_Sepolia'
  X_Layer = 'X_Layer'
  X_Layer_Testnet = 'X_Layer_Testnet'
  XDC = 'XDC'
  XDC_Apothem = 'XDC_Apothem'
}
```

**Values**

`Arbitrum`, `Arbitrum_Sepolia`, `Arc`, `Arc_Testnet`, `Avalanche`,
`Avalanche_Fuji`, `Base`, `Base_Sepolia`, `Codex`, `Codex_Testnet`, `Cronos`,
`Cronos_Testnet`, `Edge`, `Edge_Testnet`, `Ethereum`, `Ethereum_Sepolia`,
`HyperEVM`, `HyperEVM_Testnet`, `Injective`, `Injective_Testnet`, `Ink`,
`Ink_Testnet`, `Linea`, `Linea_Sepolia`, `Monad`, `Monad_Testnet`, `Morph`,
`Morph_Testnet`, `Optimism`, `Optimism_Sepolia`, `Pharos`, `Pharos_Testnet`,
`Plasma`, `Plasma_Testnet`, `Plume`, `Plume_Testnet`, `Polygon`,
`Polygon_Amoy_Testnet`, `Sei`, `Sei_Testnet`, `Solana`, `Solana_Devnet`,
`Sonic`, `Sonic_Testnet`, `Unichain`, `Unichain_Sepolia`, `World_Chain`,
`World_Chain_Sepolia`, `X_Layer`, `X_Layer_Testnet`, `XDC`, `XDC_Apothem`

***

#### BridgeChainIdentifier

Type representing valid bridge chain identifiers.

This type constrains chain parameters to only accept chains that support CCTPv2
bridging

Accepts:

* A BridgeChain enum value (e.g., `BridgeChain.Ethereum`)
* A string literal matching a BridgeChain value (e.g., `'Ethereum'`)
* A ChainDefinition object for a supported chain

```typescript theme={null}
type BridgeChainIdentifier = ChainDefinition | BridgeChain | `${BridgeChain}`;
```

***

#### BridgeConfig

Configuration options for customizing bridge behavior.

```typescript theme={null}
interface BridgeConfig {
  batchTransactions?: boolean
  customFee?: CustomFee
  feePayment?: 'source' \| 'destination'
  maxFee?: string
  transferSpeed?: TransferSpeed \| 'FAST' \| 'SLOW'
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| batchTransactions | boolean | Enable or disable EIP-5792 batched transaction execution.<br /><br /> When `true` (or `undefined` / omitted), the bridge will attempt to batch the approve and burn calls into a single `wallet_sendCalls` request if the connected wallet supports it. Set to `false` to explicitly opt out and always use the sequential approve -> burn flow. |
| customFee | CustomFee | The custom fee to charge for the transfer.<br /><br /> Whatever value you provide here is added on top of the transfer amount. The user must have enough balance for `amount + customFee`, and the wallet signs for that total on the source chain. The custom fee is split automatically:<br /><br /> - 10% routes to Circle.<br />- 90% routes to your `recipientAddress`.<br /><br /> The original transfer amount proceeds through CCTPv2 unchanged, and the protocol fee (1–14 bps in FAST mode, 0% in STANDARD) is taken from that transfer amount. |
| feePayment | `'source' \| 'destination'` | Which leg pays the protocol fee.<br /><br /> `'source'` leaves the delivered amount unreduced; `'destination'` takes the fee from it. Omit it to let the routed provider decide — a provider rejects a value it cannot honour. |
| maxFee | string | The maximum fee to pay for the burn operation.<br /><br /> Provide the amount as a base-10 numeric string representing the token amount in human-readable format. For example: to set a maximum fee of 1 USDC, pass `"1"`. Decimal values are supported (e.g., `"0.5"` for half a USDC). |
| transferSpeed | `TransferSpeed \| 'FAST' \| 'SLOW'` | The transfer speed mode for CCTPv2 transfers.<br /><br /> Controls whether to use fast burn mode (FAST) or standard mode (SLOW). Fast burn may reduce transfer time but could have different fee implications. |

***

#### BridgeParams

Parameters for initiating a crosschain USDC bridge transfer.

This type is used as the primary input to BridgeKit.bridge, allowing users to
specify the source and destination adapters, transfer amount, and optional
configuration.

* The `from` field specifies the source adapter context (wallet and chain).
* The `to` field specifies the destination, supporting both explicit and derived
  recipient addresses.
* The `config` field allows customization of bridge behavior (e.g., transfer
  speed).
* The `token` field is optional and defaults to `'USDC'`. It accepts `'USDC'`, a
  known CCTPx symbol, or a bytes32 CCTPx token id.

```typescript theme={null}
interface BridgeParams {
  amount: string;
  config?: BridgeConfig;
  from: AdapterContext<TFromAdapterCapabilities, BridgeChainIdentifier>;
  invocationMeta?: InvocationMeta;
  quote?: unknown;
  to: BridgeDestination<TToAdapterCapabilities, BridgeChainIdentifier>;
  token?: BridgeToken;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The amount to transfer |
| config | BridgeConfig | Optional bridge configuration (e.g., transfer speed). If omitted, defaults will be used |
| from | `AdapterContext<TFromAdapterCapabilities, BridgeChainIdentifier>` | The source adapter context (wallet and chain) for the transfer. |
| invocationMeta | InvocationMeta | Optional invocation metadata for tracing and correlation.<br /><br /> When provided, the `traceId` is used to correlate all events emitted during the bridge operation. If not provided, an OpenTelemetry-compatible `traceId` will be auto-generated. |
| quote | unknown | Optional server-signed quote to reuse — pass the `quote` returned by an earlier BridgeKit.estimate \| estimate call straight back so the fee you were quoted is the fee you pay.<br /><br /> Treat the value as opaque, and never log or decode it. It belongs to whichever provider issued it and carries that provider's own shape, which is why it is typed `unknown` here: a route is matched to a provider after these parameters are validated, so the kit cannot know whose quote this is. The provider that serves the route validates it before reading any field.<br /><br /> An unusable quote is not handled the same way everywhere, so take the value from an estimate result rather than constructing one:<br />- A provider with a reusable quote model (e.g. CCTPx) reuses it while it is fresh and matches the requested fee token and speed; otherwise it transparently fetches a fresh quote and flags a `QUOTE_NOT_REUSED` result warning, so a stale quote is never worse than passing none.<br />- Receive-exact bridging (`config.feePayment: 'source'`) instead rejects a quote that is invalid, mismatched, expired, or too close to expiry, rather than repricing behind your back.<br />- Providers with no quote model (e.g. USDC via CCTP v2) ignore it — silently. Route selection happens after these parameters are validated, so the kit cannot tell whose quote this is, and nothing checks that it reached the provider that issued it. In practice this bites when the token changes between `estimate` and `bridge`: a quote from a CCTPx token (`cirBTC`, `wETH`) passed to a plain USDC bridge is dropped without an error or a warning, and the fee comes from CCTP v2 instead. Keeping the same token routes back to the same provider, so the quote arrives. Re-estimate whenever the transfer changes.<br /><br /> The transfer parameters (amount, recipient, chains) are validated on-chain, so a quote reused for a different transfer is rejected by the contract rather than silently — reuse a quote only for the transfer it was estimated for.<br /><br /> This field is for BridgeKit.bridge \| bridge only. A quote is produced by `estimate` and consumed by `bridge`, and `estimate` always returns a freshly-priced one. Passing a quote back into `estimate` is a usage error: CCTPx rejects it outright, while receive-exact ignores it and prices afresh, so the quote you get back is never the one you sent. Take the quote from the estimate result, not from your input. |
| to | `BridgeDestination<TToAdapterCapabilities, BridgeChainIdentifier>` | The destination for the transfer, supporting explicit or derived recipient addresses |
| token | BridgeToken | The token to transfer. Defaults to `'USDC'`.<br /><br /> A known symbol is a convenience for a canonical CCTPx registration. A symbol that maps to more than one bridge resolves to the registration pinned by the provider. Pass the bridge's bytes32 token id directly when an exact registration is required.<br /><br /> If omitted, defaults to `'USDC'`. |

***

#### BridgeWarning

A non-fatal advisory surfaced on a BridgeResult or an EstimateResult.

Warnings report things the caller should know about that did not fail the
operation — for example a requested FAST transfer that was degraded to SLOW.
They are additive and optional: providers populate them when relevant and leave
`warnings` undefined otherwise, so consumers that ignore the field are
unaffected.

The codes are shared across both results, so a check written against one works
against the other. A code is raised only where its condition can arise, so an
estimate reaches a subset of what a bridge does.

```typescript theme={null}
interface BridgeWarning {
  code: string;
  data?: Record<string, unknown>;
  message?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | string | Stable machine-readable warning code (e.g. `'SPEED_DOWNGRADED'`). Prefer branching on this over `message`. |
| data | `Record<string, unknown>` | Optional structured context for the warning (e.g. `{ requested: 'FAST', actual: 'SLOW' }`). |
| message | string | Optional human-readable explanation for logging or display. |

***

#### CCTPConfig

Configuration for the Cross-Chain Transfer Protocol (CCTP).

```typescript theme={null}
interface CCTPConfig {
  domain: number;
  contracts: CCTPContracts;
  forwarderSupported: {
    source: boolean;
    destination: boolean;
  };
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| contracts | CCTPContracts | The contracts required for CCTP. |
| domain | number | The CCTP domain identifier. |
| forwarderSupported | `{ source: boolean; destination: boolean; }` | Indicates whether the chain supports forwarder for source and destination. |

***

#### CCTPMergedConfig

Merged CCTP contract configuration.

Used by chains that deploy a single unified CCTP contract. This simplified
architecture is used by newer chain integrations.

```typescript theme={null}
interface CCTPMergedConfig {
  type: "merged";
  contract: string;
  tokenMessengerWithFees?: string;
  confirmations: number;
}
```

***

#### CCTPSplitConfig

Split CCTP contract configuration.

Used by chains that deploy separate TokenMessenger and MessageTransmitter
contracts. This is the traditional CCTP architecture used by most EVM chains.

```typescript theme={null}
interface CCTPSplitConfig {
  type: "split";
  tokenMessenger: string;
  messageTransmitter: string;
  tokenMessengerWithFees?: string;
  confirmations: number;
}
```

***

#### TransferSpeed

Transfer speed options for crosschain operations.

Defines the available speed modes for CCTPv2 transfers, affecting both transfer
time and potential fee implications.

```typescript theme={null}
enum TransferSpeed {
  FAST = 'FAST'
  SLOW = 'SLOW'
}
```

**Values**

`FAST`, `SLOW`

***

### Swap

#### AllowanceStrategy

Allowance strategy for token approvals during swap operations.

Defines how token allowances should be granted to the swap contract:

* `permit`: Use EIP-2612 permit signature (gas-efficient, no approval
  transaction)
* `approve`: Traditional approval transaction

The default strategy is `permit` with fallback to `approve` if permit is not
supported.

```typescript theme={null}
type AllowanceStrategy = "approve" | "permit" | "authorize";
```

***

#### SwapConfig

Configuration options for swap operations.

Controls swap behavior including allowance strategy, slippage tolerance, minimum
output amounts, custom fees, and kit identification.

```typescript theme={null}
interface SwapConfig {
  allowanceStrategy?: AllowanceStrategy;
  slippageBps?: number;
  stopLimit?: string;
  customFee?: {
    percentageBps: number;
    recipientAddress: string;
  };
  apiKey?: string | undefined;
  kitKey?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allowanceStrategy | AllowanceStrategy | Strategy for granting token allowances to the swap contract.<br /><br /> Defaults to `permit` with fallback to `approve`. |
| apiKey | `string \| undefined` | Circle API key used to authenticate service-backed swap requests.<br /><br /> Format: `<ENV>_API_KEY:<keyId>:<keySecret>`. A legacy `KIT_KEY:<keyId>:<keySecret>` value is also accepted.<br /><br /> Treat this value as a credential. Do not log it, embed it in client-side source, or expose it in telemetry. |
| customFee | `{ percentageBps: number; recipientAddress: string; }` | Custom fee configuration for this swap (percentage-based approach).<br /><br /> Allows specifying a percentage fee and recipient address at the transaction level. This is mutually exclusive with kit-level callback fee policy. If both are set, transaction-level takes precedence.<br /><br /> For complex fee logic (VIP tiers, database lookups), use kit-level callback approach via `setCustomFeePolicy()` instead. |
| kitKey | string | **Deprecated.** Use SwapConfig.`apiKey` instead. Still honored when `apiKey` is omitted, and `apiKey` takes precedence when both are set. Circle API key used to authenticate service-backed swap requests. |
| slippageBps | number | Maximum acceptable slippage in basis points (BPS).<br /><br /> 1 BPS = 0.01%, so 300 BPS = 3% slippage. Defaults to 300 BPS (3%). |
| stopLimit | string | Minimum acceptable output amount in human-readable format (stop-limit).<br /><br /> If the estimated output falls below this value, the swap will fail. Expressed as a decimal string (e.g., `0.4` for 0.4 USDT). The value is automatically converted to base units using the tokenOut decimals. |

***

#### SwapDestinationLeg

Destination-leg transaction and token information reported by the service.

Present on SwapStatusResult once the service reports destination data. Omitted
while the destination leg is still in-flight.

```typescript theme={null}
interface SwapDestinationLeg {
  readonly txHash?: string;
  readonly token?: {
    readonly symbol?: string;
    readonly address?: string;
  };
  readonly amount?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | Amount received on the destination leg, as a human-readable decimal string (e.g. `'0.082927'`).<br /><br /> Present once the destination leg has landed and the service has reported both `amountOut` and `receivingTokenDecimals`. Omitted otherwise — never a raw base-unit value, so consumers can render `destination.amount` directly in a UI without worrying about unit conversion. |
| token | `{ readonly symbol?: string; readonly address?: string; }` | Destination-token metadata reported by the service. |
| txHash | string | Destination-chain transaction hash reported by the service. |

***

#### SwapProgress

Lifecycle snapshot for a swap.

Grouped so progress signals live in one place on both SwapResult and
SwapStatusResult.

```typescript theme={null}
interface SwapProgress {
  readonly status: SwapStatus;
  readonly substatus?: string;
  readonly substatusMessage?: string;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| status | SwapStatus | Current swap status. Only `'DONE'`, `'FAILED'`, and `'NOT_FOUND'` are terminal. `'PENDING'` means the caller should re-invoke SwapKit.getSwapStatus until a terminal status is observed. |
| substatus | string | Provider-specific status detail (e.g. `'WAIT_DESTINATION_TRANSACTION'`, `'COMPLETED'`). Surfaced as-is from the Stablecoin Service. |
| substatusMessage | string | Human-readable provider status explanation. |

***

#### SwapSourceLeg

Source-leg transaction and token information reported by the service.

Populated on SwapStatusResult from the service's `sendingTxHash`. `token` is
shape-reserved for future service support (the status endpoint does not report
source-token metadata today) so consumers can rely on a symmetric `source` /
`destination` layout.

```typescript theme={null}
interface SwapSourceLeg {
  readonly txHash?: string;
  readonly token?: {
    readonly symbol?: string;
    readonly address?: string;
  };
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| token | `{ readonly symbol?: string; readonly address?: string; }` | Source-token metadata. Shape-reserved — not populated by the current Stablecoin Service status endpoint, but exposed here so this field mirrors SwapDestinationLeg.token if/when the service starts returning it. |
| txHash | string | Source-chain transaction hash reported by the service. |

***

#### SwapStatus

All possible status values for a swap tracked by the Stablecoin Service.

`'PENDING'` means the swap is still in-flight. Callers should keep calling
SwapKit.getSwapStatus on `'PENDING'` until the status becomes terminal (see
SwapTerminalStatus).

```typescript theme={null}
type SwapStatus = SwapTerminalStatus | "PENDING";
```

***

#### SwapTerminalStatus

Terminal status values for a swap tracked by the Stablecoin Service.

`'DONE'` indicates the swap completed (including any crosschain delivery).
`'FAILED'` indicates the swap failed after on-chain submission. `'NOT_FOUND'`
indicates the service has no record of the transaction.

```typescript theme={null}
type SwapTerminalStatus = "DONE" | "FAILED" | "NOT_FOUND";
```

***

### Unified Balance

#### FeeAllocation

Per-chain breakdown of a fee amount.

```typescript theme={null}
interface FeeAllocation {
  amount: string;
  chain: Blockchain;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | string | The fee amount on this chain (human-readable decimal string). |
| chain | Blockchain | The chain to which this portion of the fee applies. |

***

#### FeeEntry

A single fee line item within an estimate.

```typescript theme={null}
interface FeeEntry {
  allocations?: FeeAllocation[];
  amount: string;
  recipientAddress?: string;
  token: string;
  type: FeeType;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| allocations | FeeAllocation\[] | Per-chain breakdown of the fee. Omitted for flat fees (e.g. forwarder). |
| amount | string | Aggregate fee amount (human-readable decimal string). |
| recipientAddress | string | When `type === 'kit'`, the address that receives the kit fee. Omitted for other fee types. |
| token | string | The token in which this fee is denominated (e.g. `'USDC'`, `'ETH'`). |
| type | FeeType | The category of this fee. |

***

#### FeeType

Fee category describing the origin of a fee line item.

* `'provider'` — Fee charged by the crosschain provider (e.g. protocol fee).
* `'gasFee'` — On-chain gas cost denominated in the transfer token (e.g. USDC).
* `'kit'` — Fee charged by the kit / developer integration.
* `'forwarder'` — Fee charged by Circle's Forwarding Service for automatic mint.

```typescript theme={null}
type FeeType = "provider" | "gasFee" | "kit" | "forwarder";
```

***

#### SupportedToken

```typescript theme={null}
type SupportedToken = (typeof SUPPORTED_TOKENS)[number];
```

***

#### SupportedTokenInput

Case-insensitive variant of SupportedToken for user-facing input.

Accepts the canonical uppercase form, fully lowercase, and title-case (e.g.
`'USDC'`, `'usdc'`, `'Usdc'`). Arbitrary mixed-case input like `'uSdC'` is
handled at runtime by the Zod schema and normalizeToken, so exhaustive
compile-time permutations are unnecessary. Avoiding a recursive
`CasePermutations` type prevents 2^N type-literal explosion as the token list
grows.

```typescript theme={null}
type SupportedTokenInput =
  | SupportedToken
  | Lowercase<SupportedToken>
  | Capitalize<Lowercase<SupportedToken>>;
```

***

#### UnifiedBalanceChain

Enumeration of blockchains that support Gateway V1 operations (deposit, spend,
balance, delegate, removeFund).

Derived from the full Blockchain enum but filtered to only include chains with
active Gateway V1 contract support. When new chains gain Gateway V1 support,
they are added to this enum.

```typescript theme={null}
enum UnifiedBalanceChain {
  Arbitrum = 'Arbitrum'
  Arbitrum_Sepolia = 'Arbitrum_Sepolia'
  Arc = 'Arc'
  Arc_Testnet = 'Arc_Testnet'
  Avalanche = 'Avalanche'
  Avalanche_Fuji = 'Avalanche_Fuji'
  Base = 'Base'
  Base_Sepolia = 'Base_Sepolia'
  Ethereum = 'Ethereum'
  Ethereum_Sepolia = 'Ethereum_Sepolia'
  HyperEVM = 'HyperEVM'
  HyperEVM_Testnet = 'HyperEVM_Testnet'
  Optimism = 'Optimism'
  Optimism_Sepolia = 'Optimism_Sepolia'
  Polygon = 'Polygon'
  Polygon_Amoy_Testnet = 'Polygon_Amoy_Testnet'
  Sei = 'Sei'
  Sei_Testnet = 'Sei_Testnet'
  Solana = 'Solana'
  Solana_Devnet = 'Solana_Devnet'
  Sonic = 'Sonic'
  Sonic_Testnet = 'Sonic_Testnet'
  Unichain = 'Unichain'
  Unichain_Sepolia = 'Unichain_Sepolia'
  World_Chain = 'World_Chain'
  World_Chain_Sepolia = 'World_Chain_Sepolia'
}
```

**Values**

`Arbitrum`, `Arbitrum_Sepolia`, `Arc`, `Arc_Testnet`, `Avalanche`,
`Avalanche_Fuji`, `Base`, `Base_Sepolia`, `Ethereum`, `Ethereum_Sepolia`,
`HyperEVM`, `HyperEVM_Testnet`, `Optimism`, `Optimism_Sepolia`, `Polygon`,
`Polygon_Amoy_Testnet`, `Sei`, `Sei_Testnet`, `Solana`, `Solana_Devnet`,
`Sonic`, `Sonic_Testnet`, `Unichain`, `Unichain_Sepolia`, `World_Chain`,
`World_Chain_Sepolia`

***

#### UnifiedBalanceChainIdentifier

Type representing valid unified-balance chain identifiers.

Constrains chain parameters to only accept chains that support Gateway V1
operations.

Accepts:

* An UnifiedBalanceChain enum value (e.g., `UnifiedBalanceChain.Ethereum`)
* A string literal matching an UnifiedBalanceChain value (e.g., `'Ethereum'`)
* A ChainDefinition object for a supported chain

```typescript theme={null}
type UnifiedBalanceChainIdentifier =
  ChainDefinition | UnifiedBalanceChain | `${UnifiedBalanceChain}`;
```

***

#### UnifiedBalanceKitConfig

Configuration options for initializing a UnifiedBalanceKit instance.

When no providers are specified, the kit uses the default Gateway v1 provider.
Any additional providers supplied via config are appended to the defaults.

```typescript theme={null}
interface UnifiedBalanceKitConfig {
  disableAnalytics?: boolean;
  disableErrorReporting?: boolean;
  excludeDefaultProviders?: boolean;
  headers?: Record<string, string>;
  providers?: TExtraProviders;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| disableAnalytics | boolean | Disable analytics telemetry (success events with `txHash`).<br /><br /> When `true`, the SDK will not POST to the telemetry endpoint after successful verb operations. Defaults to `false` (enabled). |
| disableErrorReporting | boolean | Disable error telemetry.<br /><br /> When `true`, the SDK will not POST error details to the telemetry endpoint when public methods throw. Defaults to `false` (enabled). |
| excludeDefaultProviders | boolean | Skip the built-in default providers when assembling the context.<br /><br /> By default the kit prepends the standard Gateway v1 provider so `providers` is treated as additive. Pass `true` to use only the providers supplied in UnifiedBalanceKitConfig.providers.<br /><br /> Useful when stubbing the gateway in integration tests, when running against a self-hosted gateway replacement, or any time you want full control over which provider serves a given chain. |
| headers | `Record<string, string>` | Custom HTTP headers forwarded with every Circle Gateway API request the default Gateway v1 provider makes (balances, deposits, spend estimate, transfer, forwarder status, and `/v1/info`). |
| providers | TExtraProviders | Optional array of additional Gateway providers.<br /><br /> If not provided, default providers will be initialized. |

***

### Onramp

#### OnrampDepositInfo

Deposit metadata shared by `DEPOSIT_SUBMITTED` and `DEPOSIT_SETTLED`.

```typescript theme={null}
interface OnrampDepositInfo {
  amount?: number
  orderId?: string
  paymentMethod?: LiteralUnion<'ApplePay' \| 'BankTransfer' \| 'Debit' \| 'GooglePay'>
  settlementExpected?: boolean
  tokenSymbol?: string
  transactionHash?: string
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | number | Deposit amount in the source currency. |
| orderId | string | Onramp provider order identifier. Useful for cross-referencing with the host's order ledger. |
| paymentMethod | `LiteralUnion<'ApplePay' \| 'BankTransfer' \| 'Debit' \| 'GooglePay'>` | Payment method the customer selected. |
| settlementExpected | boolean | When `true`, a follow-up `DEPOSIT_SETTLED` event may arrive later. When `false`, this is the final deposit callback for the current session. |
| tokenSymbol | string | Symbol of the token the customer will receive (e.g. `'USDC'`). |
| transactionHash | string | On-chain transaction hash of the settled deposit, when known. |

***

#### OnrampDepositNotCompletedCode

Codes the widget is documented to send on a `DEPOSIT_NOT_COMPLETED` envelope.
Widened to any string — see LiteralUnion.

```typescript theme={null}
type OnrampDepositNotCompletedCode = LiteralUnion<unknown \| unknown \| unknown \| unknown \| unknown \| unknown>
```

***

#### OnrampDepositNotCompletedEnvelope

The deposit flow ended without a settled deposit.

```typescript theme={null}
interface OnrampDepositNotCompletedEnvelope {
  code: OnrampDepositNotCompletedCode;
  event: "DEPOSIT_NOT_COMPLETED";
  payload: OnrampErrorPayload;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | OnrampDepositNotCompletedCode | Sub-type — see OnrampDepositNotCompletedCode. |
| event | `'DEPOSIT_NOT_COMPLETED'` | Discriminator: always `DEPOSIT_NOT_COMPLETED`. |
| payload | OnrampErrorPayload | Error payload (best-effort diagnostic copy + extras). |

***

#### OnrampDepositSettledEnvelope

A previously submitted deposit settled on-chain.

```typescript theme={null}
interface OnrampDepositSettledEnvelope {
  code: "DEPOSIT_SETTLED";
  event: "DEPOSIT_SETTLED";
  payload: OnrampDepositInfo;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | `'DEPOSIT_SETTLED'` | Sub-type: always `DEPOSIT_SETTLED`. |
| event | `'DEPOSIT_SETTLED'` | Discriminator: always `DEPOSIT_SETTLED`. |
| payload | OnrampDepositInfo | Deposit metadata — see OnrampDepositInfo. |

***

#### OnrampDepositSubmittedEnvelope

The customer submitted a deposit request.

```typescript theme={null}
interface OnrampDepositSubmittedEnvelope {
  code: "DEPOSIT_SUBMITTED";
  event: "DEPOSIT_SUBMITTED";
  payload: OnrampDepositInfo;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | `'DEPOSIT_SUBMITTED'` | Sub-type: always `DEPOSIT_SUBMITTED`. |
| event | `'DEPOSIT_SUBMITTED'` | Discriminator: always `DEPOSIT_SUBMITTED`. |
| payload | OnrampDepositInfo | Deposit metadata — see OnrampDepositInfo. |

***

#### OnrampEventEnvelope

Discriminated union of the onramp event envelopes the kit knows about,
discriminated on `event`.

```typescript theme={null}
type OnrampEventEnvelope =
  | OnrampInitializationErrorEnvelope
  | OnrampInitializationSuccessEnvelope
  | OnrampDepositNotCompletedEnvelope
  | OnrampDepositSubmittedEnvelope
  | OnrampDepositSettledEnvelope;
```

***

#### OnrampInitializationErrorCode

Codes the widget is documented to send on an `INITIALIZATION_ERROR` envelope.
Widened to any string — see LiteralUnion.

```typescript theme={null}
type OnrampInitializationErrorCode = LiteralUnion<unknown \| unknown>
```

***

#### OnrampInitializationErrorEnvelope

The widget reports that it could not start.

```typescript theme={null}
interface OnrampInitializationErrorEnvelope {
  code: OnrampInitializationErrorCode;
  event: "INITIALIZATION_ERROR";
  payload: OnrampErrorPayload;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | OnrampInitializationErrorCode | Sub-type — see OnrampInitializationErrorCode. |
| event | `'INITIALIZATION_ERROR'` | Discriminator: always `INITIALIZATION_ERROR`. |
| payload | OnrampErrorPayload | Error payload (best-effort diagnostic copy + extras). |

***

#### OnrampInitializationSuccessEnvelope

The widget loaded successfully and the session token was accepted.

```typescript theme={null}
interface OnrampInitializationSuccessEnvelope {
  code: "INITIALIZATION_SUCCESS";
  event: "INITIALIZATION_SUCCESS";
  payload?: Readonly<Record<string, unknown>>;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| code | `'INITIALIZATION_SUCCESS'` | Sub-type: always `INITIALIZATION_SUCCESS`. |
| event | `'INITIALIZATION_SUCCESS'` | Discriminator: always `INITIALIZATION_SUCCESS`. |
| payload | `Readonly<Record<string, unknown>>` | Optional widget-supplied payload. Forwarded untouched. |

***

#### OnrampSession

One session as returned by the Onramp session endpoint
(`POST /v1/stablecoinKits/sessions`), after the server kit unwraps the
`{ data }` envelope.

```typescript theme={null}
interface OnrampSession {
  destinationWallet?: string;
  expiresAt: string;
  sessionId: string;
  sessionToken: string;
  traceId?: string;
  widgetUrl?: string;
}
```

***

#### OnrampWidget

Handle returned by `onrampKit.mountIframe()` and the `'opened'` branch of
`onrampKit.openWindow()`.

```typescript theme={null}
interface OnrampWidget {
  readonly sessionId: string;
  readonly traceId: string | undefined;
  readonly state: OnrampWidgetLifecycle;
  on<T extends OnrampEventType>(
    event: T,
    handler: OnrampWidgetEventHandler<T>,
  ): () => void;
  on(event: "*", handler: OnrampWidgetAnyHandler): () => void;
  off<T extends OnrampEventType>(
    event: T,
    handler: OnrampWidgetEventHandler<T>,
  ): void;
  off(event: "*", handler: OnrampWidgetAnyHandler): void;
  close(): void;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| sessionId | string | Server-issued session identifier. |
| state | OnrampWidgetLifecycle | Current lifecycle state. |
| traceId | `string \| undefined` | Trace ID stamped at session creation; threaded through events. |
| close | unknown | |
| off | unknown | |
| on | unknown | |

***

#### OnrampWidgetLifecycle

Lifecycle state of an active widget.

```typescript theme={null}
type OnrampWidgetLifecycle =
  "mounting" | "ready" | "submitted" | "settled" | "closed" | "failed";
```

***

#### OnrampWindowBlockedReason

Why `onrampKit.openWindow()` could not open a usable popup.

```typescript theme={null}
type OnrampWindowBlockedReason =
  "popup_blocked" | "in_app_browser" | "pwa_standalone";
```

***

### Earn

#### EarnAssetAmount

Token amount returned by the SDK in human-readable decimal form.

```typescript theme={null}
type EarnAssetAmount = Omit<AssetAmount, "amount"> & {
  readonly amount: string;
};
```

***

#### EarnBridgeCctpStatus

CCTP attestation status for a crosschain bridge deposit.

```typescript theme={null}
interface EarnBridgeCctpStatus {
  readonly status: string;
  readonly domainId?: number | undefined;
  readonly sourceDomainId?: number | undefined;
  readonly destinationDomainId?: number | undefined;
  readonly attestationAvailable?: boolean | undefined;
  readonly [key: string]: unknown;
}
```

***

#### EarnBridgeHopStatus

Status of one hop (source relay or destination mint) of a crosschain bridge
deposit.

The `status` field is an API-defined lifecycle string (e.g. `'COMPLETE'`,
`'NOT_STARTED'`). Additive backend fields (chain, domain, relay/tx ids) are
preserved verbatim.

```typescript theme={null}
interface EarnBridgeHopStatus {
  readonly status: string;
  readonly chain?: string | undefined;
  readonly domainId?: number | undefined;
  readonly sourceDomainId?: number | undefined;
  readonly destinationDomainId?: number | undefined;
  readonly relayId?: string | undefined;
  readonly txHash?: string | undefined;
  readonly [key: string]: unknown;
}
```

***

#### EarnClaimRewardsQuoteInfo

Result of a claim rewards quote operation.

```typescript theme={null}
type EarnClaimRewardsQuoteInfo = Omit<ClaimRewardsQuoteInfo, "rewards"> & {
  readonly rewards: readonly EarnAssetAmount[];
};
```

**Properties**

| Name | Type | Description |
| - | - | - |
| rewards | readonly EarnAssetAmount\[] | Reward tokens available for claiming in human-readable decimal format. |

***

#### EarnCrossChainDepositStatus

Structured status of a crosschain Earn deposit, keyed by execId.

The top-level `status` is the overall API-defined bridge lifecycle string (e.g.
`'PENDING'`, `'ATTESTING'`, `'COMPLETE'`). The nested `source`, `cctp`, and
`destination` objects expose per-hop progress when the API returns them.

```typescript theme={null}
interface EarnCrossChainDepositStatus {
  readonly execId: string;
  readonly status: string;
  readonly source?: EarnBridgeHopStatus | undefined;
  readonly cctp?: EarnBridgeCctpStatus | undefined;
  readonly destination?: EarnBridgeHopStatus | undefined;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| cctp | `EarnBridgeCctpStatus \| undefined` | CCTP attestation status, when available. |
| destination | `EarnBridgeHopStatus \| undefined` | Destination-chain mint hop status, when available. |
| execId | string | Idempotency execution ID for the crosschain deposit. |
| source | `EarnBridgeHopStatus \| undefined` | Source-chain relay (burn) hop status, when available. |
| status | string | Overall API-defined bridge lifecycle status. |

***

#### EarnGasFeeEstimate

Estimated native gas fee for one transaction in an Earn quote.

A discriminated union on `fees`: a successful estimate carries EarnEstimatedGas
details and no `error`; a failed estimate carries `fees: null` and a sanitized
`error` message.

```typescript theme={null}
type EarnGasFeeEstimate =
  | (EarnGasFeeEstimateBase & {
      readonly fees: EstimatedGas;
      readonly error?: never;
    })
  | (EarnGasFeeEstimateBase & {
      readonly fees: null;
      readonly error: string;
    });
```

***

#### EarnGasFeeEstimateBase

Fields shared by both EarnGasFeeEstimate variants.

```typescript theme={null}
interface EarnGasFeeEstimateBase {
  readonly name: string;
  readonly token: string;
  readonly blockchain: ChainDefinition["chain"];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| blockchain | `ChainDefinition['chain']` | Blockchain where this gas fee applies. |
| name | string | The earn step being estimated, e.g. "Approve", "Deposit", "Withdraw". |
| token | string | Native token used to pay gas fees, e.g. "ETH". |

***

#### EarnVaultInfo

Vault information returned by the SDK.

Derived with a distributive `Omit` so each opportunity variant keeps its
product-specific fields and the `productType` discriminant.

```typescript theme={null}
type EarnVaultInfo = DistributiveOmit<
  EarnOpportunity,
  "totalDeposits" | "liquidity" | "liquidityProfile"
> & {
  readonly totalDeposits: string;
  readonly liquidity: string;
  readonly liquidityProfile: EarnLiquidityProfile;
};
```

**Properties**

| Name | Type | Description |
| - | - | - |
| liquidity | string | Available liquidity in the vault in human-readable decimal format. |
| liquidityProfile | EarnLiquidityProfile | Liquidity profile with amounts as human-readable decimal strings. |
| totalDeposits | string | Total value deposited in human-readable decimal format. |

***

### Borrow

#### BorrowActionBase

Common fields on every borrow action payload.

The `protocol` and `service` discriminators keep events distinguishable when
borrow operations are composed into multi-protocol flows.

```typescript theme={null}
interface BorrowActionBase {
  readonly protocol: "borrow";
  readonly service: "borrow-service";
}
```

***

#### BorrowActions

Action map for borrow step events.

Each key is a phase name and the value is the payload delivered to handlers
registered through `BorrowKit.on`. `values` carries the full BorrowStep for the
phase that fired.

```typescript theme={null}
interface BorrowActions {
  fetchParams: BorrowActionBase & {
    readonly operation: BorrowOperationName;
    readonly method: "fetchParams";
    readonly values: Extract<
      BorrowStep,
      {
        readonly name: "fetchParams";
      }
    >;
  };
  approve: BorrowActionBase & {
    readonly operation: BorrowOperationName;
    readonly method: "approve";
    readonly values: Extract<
      BorrowStep,
      {
        readonly name: "approve";
      }
    >;
  };
  setAuthorization: BorrowActionBase & {
    readonly operation: BorrowOperationName;
    readonly method: "setAuthorization";
    readonly values: Extract<
      BorrowStep,
      {
        readonly name: "setAuthorization";
      }
    >;
  };
  execute: BorrowActionBase & {
    readonly operation: BorrowOperationName;
    readonly method: "execute";
    readonly values: Extract<
      BorrowStep,
      {
        readonly name: "execute";
      }
    >;
  };
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| approve | `BorrowActionBase & { readonly operation: BorrowOperationName; readonly method: 'approve'; readonly values: Extract<BorrowStep, { readonly name: 'approve'; }>; }` | The token approval leg: collateral for `borrow`/`addCollateral`, USDC for `repay`/`closeLoan`/`withdrawCollateralRepayIfNeeded`. `closeLoan` and `withdrawCollateralRepayIfNeeded` approve slightly above the priced amount to absorb interest accrual. Skipped when `withdrawCollateralRepayIfNeeded` doesn't need a repayment. |
| execute | `BorrowActionBase & { readonly operation: BorrowOperationName; readonly method: 'execute'; readonly values: Extract<BorrowStep, { readonly name: 'execute'; }>; }` | The batch that carries `Adapter.execute`. |
| fetchParams | `BorrowActionBase & { readonly operation: BorrowOperationName; readonly method: 'fetchParams'; readonly values: Extract<BorrowStep, { readonly name: 'fetchParams'; }>; }` | The Borrow Service call that returns the signed execution. |
| setAuthorization | `BorrowActionBase & { readonly operation: BorrowOperationName; readonly method: 'setAuthorization'; readonly values: Extract<BorrowStep, { readonly name: 'setAuthorization'; }>; }` | The Morpho manager grant, and its matching revocation. |

***

#### BorrowAddCollateralQuote

```typescript theme={null}
interface BorrowAddCollateralQuote {
  readonly chain: string;
  readonly collateralAmount: BorrowAssetAmount;
  readonly fees: readonly BorrowFee[];
  readonly gasFees: readonly BorrowQuoteGasFee[];
  readonly resultingHealthFactor: number | null;
  readonly resultingLtv: number | null;
  readonly resultingBand: BorrowHealthFactorBand;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

***

#### BorrowAddCollateralResult

```typescript theme={null}
type BorrowAddCollateralResult =
  | BorrowConfirmedAddCollateralResult
  | BorrowConfirmedAddCollateralDetailsUnavailableResult
  | BorrowSubmittedAddCollateralResult;
```

***

#### BorrowAssetAmount

```typescript theme={null}
interface BorrowAssetAmount {
  readonly token: string;
  readonly tokenAddress: string;
  readonly amount: string;
  readonly decimals: number;
}
```

***

#### BorrowClaimedAmount

Reward token amount with the amount formatted as a decimal string.

```typescript theme={null}
type BorrowClaimedAmount = Omit<ClaimedAmount, "amount"> & {
  readonly amount: string;
};
```

***

#### BorrowCloseLoanQuote

```typescript theme={null}
interface BorrowCloseLoanQuote {
  readonly chain: string;
  readonly bundledRepayment: BorrowAssetAmount;
  readonly collateralAmount: BorrowAssetAmount;
  readonly fees: readonly BorrowFee[];
  readonly gasFees: readonly BorrowQuoteGasFee[];
  readonly resultingHealthFactor: number | null;
  readonly resultingLtv: number | null;
  readonly resultingBand: BorrowHealthFactorBand;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

***

#### BorrowCloseLoanResult

```typescript theme={null}
type BorrowCloseLoanResult =
  | BorrowConfirmedCloseLoanResult
  | BorrowConfirmedCloseLoanDetailsUnavailableResult
  | BorrowSubmittedCloseLoanResult;
```

***

#### BorrowExploreMarketsResult

```typescript theme={null}
interface BorrowExploreMarketsResult {
  readonly markets: readonly BorrowMarketInfo[];
  readonly pagination: BorrowPagination;
}
```

***

#### BorrowFee

```typescript theme={null}
interface BorrowFee {
  readonly type: string;
  readonly token: string;
  readonly amount: BorrowAssetAmount;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amount | BorrowAssetAmount | |
| token | string | |
| type | string | |

***

#### BorrowHealthFactorBand

```typescript theme={null}
type BorrowHealthFactorBand =
  "SAFE" | "WARN" | "URGENT" | "IMMINENT" | "LIQUIDATABLE";
```

***

#### BorrowIntegratorConfig

```typescript theme={null}
interface BorrowIntegratorConfig {
  readonly integratorId: string;
  readonly integratorFeeBps: number;
  readonly integratorFeeAddress: string | null;
  readonly createdAt: string;
  readonly updatedAt: string;
}
```

***

#### BorrowListLoansResult

```typescript theme={null}
interface BorrowListLoansResult {
  readonly loans: readonly BorrowLoan[];
  readonly pagination: BorrowPagination;
}
```

***

#### BorrowLoanDataStatus

```typescript theme={null}
type BorrowLoanDataStatus = "READY" | "PENDING";
```

***

#### BorrowMarketInfo

```typescript theme={null}
interface BorrowMarketInfo {
  readonly marketId: string;
  readonly protocol: BorrowProtocol;
  readonly chain: `${Blockchain}`;
  readonly loanAsset: BorrowMarketAsset;
  readonly collateralAsset: BorrowMarketAsset;
  readonly lltv: number | null;
  readonly borrowCap?: BorrowAssetAmount | null | undefined;
  readonly borrowAssets: BorrowAssetAmount | null;
  readonly liquidity: BorrowAssetAmount | null;
  readonly borrowApy: number | null;
  readonly utilization: number | null;
  readonly refreshedAt: string | null;
}
```

***

#### BorrowNoClaimableRewardsResult

```typescript theme={null}
interface BorrowNoClaimableRewardsResult {
  readonly status: "no_rewards";
  readonly rewards: readonly [];
}
```

***

#### BorrowOpenLoanParams

```typescript theme={null}
interface BorrowOpenLoanParams<
  TAdapterCapabilities extends AdapterCapabilities = AdapterCapabilities,
> extends BorrowParamsBase<TAdapterCapabilities> {
  readonly marketId: string;
  readonly loanId?: never;
}
```

***

#### BorrowOpenLoanQuoteParams

```typescript theme={null}
interface BorrowOpenLoanQuoteParams extends BorrowQuoteParamsBase {
  readonly walletAddress: string;
  readonly chain: ChainIdentifier;
  readonly marketId: string;
  readonly loanId?: never;
}
```

***

#### BorrowOperationName

Name of the multi-phase operation that emitted a step event.

```typescript theme={null}
type BorrowOperationName =
  "borrow" | "repay" | "addCollateral" | "closeLoan" | "withdrawCollateral";
```

***

#### BorrowRegisterWebhookResult

```typescript theme={null}
interface BorrowRegisterWebhookResult {
  readonly loanId: string;
  readonly webhookUrl: string | null;
}
```

***

#### BorrowRepayQuote

```typescript theme={null}
interface BorrowRepayQuote {
  readonly chain: string;
  readonly repayAmount: BorrowAssetAmount;
  readonly fees: readonly BorrowFee[];
  readonly gasFees: readonly BorrowQuoteGasFee[];
  readonly resultingHealthFactor: number | null;
  readonly resultingLtv: number | null;
  readonly resultingBand: BorrowHealthFactorBand;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

***

#### BorrowRepayResult

```typescript theme={null}
type BorrowRepayResult =
  | BorrowConfirmedRepayResult
  | BorrowConfirmedRepayDetailsUnavailableResult
  | BorrowSubmittedRepayResult;
```

***

#### BorrowRequiredCollateralQuote

```typescript theme={null}
interface BorrowRequiredCollateralQuote {
  readonly chain: `${Blockchain}`;
  readonly requiredCollateral: BorrowAssetAmount;
  readonly resultingHealthFactor: number | null;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

***

#### BorrowServiceConfig

Configuration for calls to the Borrow Service API.

The credential is part of the shared provider contract (mirroring
EarnServiceConfig). It is optional on `borrow` and `getBorrowQuote`, required on
`getIntegratorConfig` and `setIntegratorConfig`, and forbidden on every other
API.

```typescript theme={null}
interface BorrowServiceConfig {
  readonly apiKey?: string | undefined;
  readonly baseUrl?: string | undefined;
}
```

***

#### BorrowStepBase

Fields shared by every BorrowStep variant.

```typescript theme={null}
interface BorrowStepBase {
  readonly state: "pending" | "success" | "error";
  readonly errorMessage?: string | undefined;
  readonly error?: unknown;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| error | unknown | What caused the phase to fail, present only when `state` is `'error'`.<br /><br /> A projection of the thrown value rather than the value itself: `{ name, message }` for an `Error`, its `String()` form otherwise. The object graph a provider error carries — viem's `metaMessages`, the originating `request`, the transport URL — is dropped, and the execution signature is redacted out of what is left. Read `errorMessage` for the revert reason. |
| errorMessage | `string \| undefined` | Human-readable error message, present only when `state` is `'error'`. |
| state | `'pending' \| 'success' \| 'error'` | Lifecycle state of the phase. |

***

#### BorrowWithdrawCollateralQuote

```typescript theme={null}
interface BorrowWithdrawCollateralQuote {
  readonly chain: string;
  readonly bundledRepayment: BorrowAssetAmount;
  readonly collateralAmount: BorrowAssetAmount;
  readonly fees: readonly BorrowFee[];
  readonly gasFees: readonly BorrowQuoteGasFee[];
  readonly resultingHealthFactor: number | null;
  readonly resultingLtv: number | null;
  readonly resultingBand: BorrowHealthFactorBand;
  readonly liquidationPrice: BorrowAssetAmount | null;
}
```

***

#### BorrowWithdrawCollateralResult

```typescript theme={null}
type BorrowWithdrawCollateralResult =
  | BorrowConfirmedWithdrawCollateralResult
  | BorrowConfirmedWithdrawCollateralDetailsUnavailableResult
  | BorrowSubmittedWithdrawCollateralResult;
```

***

#### ClaimedAmount

A single claimed (or claimable) reward token amount.

```typescript theme={null}
interface ClaimedAmount {
  readonly address: string;
  readonly symbol: string;
  readonly amount: Amount;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| address | string | Reward token contract address. |
| amount | Amount | Claimed (or claimable) amount. |
| symbol | string | Reward token symbol. |

***

#### ClaimRewardsQuoteInfo

Read-only claimable-rewards quote.

Services may extend this with their own optional fields (e.g. EarnKit carries an
always-empty `gasFees` for symmetry with its other quotes); the `rewards` list
itself is contract-defined and identical everywhere.

```typescript theme={null}
interface ClaimRewardsQuoteInfo {
  readonly rewards: readonly ClaimedAmount[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| rewards | readonly ClaimedAmount\[] | Reward tokens currently available for claiming. |

***

#### ConfirmedBorrowDetailsUnavailableResult

A borrow confirmed on-chain but receipt details cannot be decoded.

```typescript theme={null}
type ConfirmedBorrowDetailsUnavailableResult =
  ConfirmedDetailsUnavailableBorrowOperationResultBase;
```

***

#### ConfirmedBorrowResult

A borrow confirmed on-chain.

```typescript theme={null}
interface ConfirmedBorrowResult extends ConfirmedBorrowOperationResultBase {
  readonly amountBorrowed: BorrowAssetAmount;
  readonly fees: readonly BorrowFee[];
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| amountBorrowed | BorrowAssetAmount | Amount borrowed, decoded from the confirmed Morpho receipt's Borrow event `assets`. This is the full draw, which the loan carries as principal; the wallet receives it net of `fees`, which are withheld from it rather than subtracted here. |
| batchId | string | Wallet-assigned batch identifier used to query submission status. |
| fees | readonly BorrowFee\[] | Fee legs the signed bundle charged at origination, paid out by the Adapter from `amountBorrowed` before the rest is swept to the wallet.<br /><br /> Each `amount` is what the receipt shows the beneficiary was paid. A leg's `type` (`circle`, `integrator`) comes from Borrow Service, the only place a beneficiary's identity exists; a leg the receipt paid out but the service did not name is reported as `'unknown'` rather than dropped. Empty means nothing was charged: a borrow-more, or an origination with no fee. |
| loanId | string | Loan the operation applies to. |
| status | `'confirmed'` | |
| txHash | string | |

***

#### ConfirmedDetailsUnavailableBorrowOperationResultBase

A batch confirmed on-chain whose receipt details could not be decoded.

The transaction succeeded and must not be retried. Every operation decodes its
confirmed amounts from the receipt, so every operation can reach this state.

```typescript theme={null}
interface ConfirmedDetailsUnavailableBorrowOperationResultBase extends BorrowOperationResultBase {
  readonly status: "confirmed-details-unavailable";
  readonly txHash: string;
  readonly error: KitError;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| batchId | string | Wallet-assigned batch identifier used to query submission status. |
| error | KitError | |
| loanId | string | Loan the operation applies to. |
| status | `'confirmed-details-unavailable'` | |
| txHash | string | |

***

#### SubmittedBorrowOperationResultBase

A submitted batch whose on-chain outcome is not yet known.

Wallets without `getCallsStatus` report no receipt even when the batch lands, so
this is returned rather than thrown to keep `batchId` available for a status
query.

```typescript theme={null}
interface SubmittedBorrowOperationResultBase extends BorrowOperationResultBase {
  readonly status: "submitted";
  readonly error?: KitError | undefined;
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| batchId | string | Wallet-assigned batch identifier used to query submission status. |
| error | `KitError \| undefined` | Post-submission confirmation failure, when the adapter supplied one. |
| loanId | string | Loan the operation applies to. |
| status | `'submitted'` | |

***

#### SubmittedBorrowResult

A submitted borrow whose on-chain outcome is not yet known.

```typescript theme={null}
type SubmittedBorrowResult = SubmittedBorrowOperationResultBase;
```

***

### Miscellaneous

#### DepositConfig

Transfer-speed configuration for a deposit operation.

```typescript theme={null}
interface DepositConfig {
  transferSpeed?: "FAST" | "STANDARD";
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| transferSpeed | `'FAST' \| 'STANDARD'` | Requested transfer speed for a crosschain fast deposit. |

***

#### DepositProgress

Relay progress for a crosschain (FAST) deposit.

Set after `depositFastCrossChain` completes the \~60-second relay wait. Always
present on the FAST path; absent on same-chain STANDARD deposits.

```typescript theme={null}
interface DepositProgress {
  status: "DONE" | "PENDING" | "FAILED";
}
```

**Properties**

| Name | Type | Description |
| - | - | - |
| status | `'DONE' \| 'PENDING' \| 'FAILED'` | Relay outcome after the burn is confirmed on the source chain.<br /><br /> - `'DONE'` — Circle's relayer minted USDC on the destination chain.<br />- `'PENDING'` — Relay timed out (\~60 s); the mint may still complete.<br />- `'FAILED'` — Relayer reported a permanent failure; manual mint may be required. |

***

## Event Types

### Bridge Events

Bridge events are emitted for each provider in the kit. Events for the built-in
CCTP provider follow its transaction steps. You can subscribe to each event
multiple times with different callbacks.

Bridge events are prefixed with `bridge.` to namespace them within AppKit:

| Event | Description |
| - | - |
| `bridge.approve` | Token approval transaction completed |
| `bridge.burn` | Source chain burn transaction completed |
| `bridge.attestation` | CCTP attestation received |
| `bridge.mint` | Destination chain mint transaction completed |
| `*` | Wildcard listener for all events |

**Usage Example**

```typescript theme={null}
import { AppKit } from "@circle-fin/app-kit";

const kit = new AppKit();

// Listen to specific bridge action
kit.on("bridge.approve", (payload) => {
  console.log("Approval transaction:", payload.values.txHash);
});

// Listen to earn deposit steps
kit.on("earn.deposit", (payload) => {
  console.log("Earn deposit step:", payload.values.state);
});

// Listen to unified balance action
kit.on("unifiedBalance.gateway.spend.succeeded", (payload) => {
  console.log("Spend succeeded:", payload.data);
});

// Listen to all actions
kit.on("*", (payload) => {
  console.log("Action:", payload);
});
```
