Skip to main content
A spend pulls USDC from the balances you have deposited on supported blockchains. Choose one of these approaches to control which blockchains supply the USDC:
  • Automatic routing: Specify a total spend amount and let App Kit choose which blockchains to draw from based on your confirmed balances.
  • Explicit amounts: Set how much USDC comes from each source blockchain yourself.

Prerequisites

Before you begin, ensure that you’ve: These are required so any example below runs with a valid kit and adapter.

App Kit allocates for you

App Kit chooses how to fund the spend from your confirmed balances. The kit prefers the destination blockchain first, then pulls from your other blockchains from highest balance to lowest. Ethereum mainnet is the exception: it is always last, including when it is the spend destination. Pass amount, from with only an adapter (no allocations), and to. This example spends 2.00 USDC with automatic routing:
TypeScript
import { AppKit } from "@circle-fin/app-kit";
import { createViemAdapterFromPrivateKey } from "@circle-fin/adapter-viem-v2";

const kit = new AppKit();

const adapter = createViemAdapterFromPrivateKey({
  privateKey: process.env.EVM_PRIVATE_KEY as string,
});

const result = await kit.unifiedBalance.spend({
  amount: "2.00",
  from: { adapter },
  to: {
    adapter,
    chain: "Arc_Testnet",
    recipientAddress: "0xRecipientAddress",
  },
});

Explicit per-chain allocations

List each blockchain and how much USDC to draw in from.allocations. Each entry contains an amount and chain. When you use allocations, their amounts must add up to the top-level amount. This example spends 2.00 USDC (1.00 USDC from Arc Testnet and 1.00 USDC from Base Sepolia) delivered to the recipient on Arc Testnet:
TypeScript
import { AppKit } from "@circle-fin/app-kit";
import { createViemAdapterFromPrivateKey } from "@circle-fin/adapter-viem-v2";

const kit = new AppKit();

const adapter = createViemAdapterFromPrivateKey({
  privateKey: process.env.EVM_PRIVATE_KEY as string,
});

const result = await kit.unifiedBalance.spend({
  amount: "2.00",
  from: {
    adapter,
    allocations: [
      { amount: "1.00", chain: "Arc_Testnet" },
      { amount: "1.00", chain: "Base_Sepolia" },
    ],
  },
  to: {
    adapter,
    chain: "Arc_Testnet",
    recipientAddress: "0xRecipientAddress",
  },
});
You can pass multiple adapters in from when you need separate sources (for example EVM and Solana). Each source uses the same shape: adapter and optional allocations. The top-level amount must still match the sum of all allocation amounts you provide.

Validation rules

  • Amount: The top-level amount is always required. It is the total USDC for the spend.
  • Sums: If you pass allocations, the kit checks that they sum to amount. If they do not match, you get a clear error with both values.
  • Consistency: Either every from entry specifies allocations, or none do. Mixing sources with allocations and sources without is not supported. If you need a computed split first, use estimateSpend, then pass the returned allocations into spend.
  • Retry: Retrying only the mint step after a failure uses a separate retrySpend flow and parameters, not a partial spend call.