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

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. 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. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# Quickstart: Set up a USDC trustline on Stellar

> Fund a wallet on Stellar Testnet and open a USDC trustline so the account can hold USDC.

On Stellar, an account must add a USDC trustline before it can hold USDC. This
is an explicit opt-in that authorizes the account to hold a specific asset. For
more details, see Stellar's
[trustline documentation](https://developers.stellar.org/docs/learn/fundamentals/stellar-data-structures/accounts#trustlines).

In this quickstart, you create a TypeScript script that uses
[`@stellar/stellar-sdk`](https://github.com/stellar/js-stellar-sdk) to:

* Create and fund a Stellar Testnet wallet
* Establish a USDC trustline so the wallet can receive USDC

<Note>
  This quickstart funds the account with Friendbot's HTTP API from your script.
  You can use [Stellar Lab](https://lab.stellar.org/account/fund) to fund on
  Stellar Testnet in the browser.
</Note>

## Prerequisites

Before you begin, ensure that you've:

* Installed [Node.js v22.6+](https://nodejs.org/) or later
* Set up a terminal and code editor for running commands and editing files

## Step 1. Set up the project

This step shows you how to prepare your project and environment.

### 1.1. Create the project and install dependencies

Create a new directory and install the required dependencies:

```bash Shell theme={null}
# Set up your directory and initialize a Node.js project
mkdir xlm-usdc-trustline
cd xlm-usdc-trustline
npm init -y

# Set up module type and start command
npm pkg set type=module
npm pkg set scripts.start="node main.ts"

# Install runtime dependencies
npm install @stellar/stellar-sdk typescript

# Install dev dependencies
npm install --save-dev @types/node
```

### 1.2. Configure TypeScript (optional)

<Tip>
  This step is optional. It helps prevent missing types in your IDE or editor.
</Tip>

Create a `tsconfig.json` file:

```shell theme={null}
npx tsc --init
```

Then, update the `tsconfig.json` file:

```shell theme={null}
cat <<'EOF' > tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "types": ["node"]
  }
}
EOF
```

## Step 2: Create the trustline script

Add `main.ts` at the project root. The script generates a keypair, requests test
XLM from Friendbot (Stellar's faucet), submits a `changeTrust` for testnet USDC,
and posts the transaction to
[Horizon](https://developers.stellar.org/docs/data/apis/horizon) (Stellar's HTTP
API for submitting transactions).

```typescript main.ts theme={null}
import {
  Horizon,
  Keypair,
  TransactionBuilder,
  Operation,
  Asset,
  Networks,
  BASE_FEE,
} from "@stellar/stellar-sdk";

const HORIZON_TESTNET_URL = "https://horizon-testnet.stellar.org";
const FRIENDBOT_URL = "https://friendbot.stellar.org";
const USDC_ISSUER = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5";
const USDC_CODE = "USDC";
const TX_EXPLORER_BASE = "https://stellar.expert/explorer/testnet/tx";

async function main() {
  const server = new Horizon.Server(HORIZON_TESTNET_URL);

  console.log("Creating and funding a user wallet...");
  const keypair = Keypair.random();
  const publicKey = keypair.publicKey();
  const secretKey = keypair.secret();

  const friendbotResponse = await fetch(`${FRIENDBOT_URL}?addr=${publicKey}`);
  if (!friendbotResponse.ok) {
    throw new Error(
      `Friendbot funding failed: ${friendbotResponse.status} ${friendbotResponse.statusText}`,
    );
  }

  console.log("======= User wallet details =======");
  console.log("Address:", publicKey);
  console.log("Secret key:", secretKey);
  console.log("NOTE: DO NOT SHARE THE SECRET KEY WITH ANYONE!");
  console.log("===================================");
  console.log("");

  console.log("Creating a trustline for USDC...");
  const account = await server.loadAccount(publicKey);
  const usdcAsset = new Asset(USDC_CODE, USDC_ISSUER);

  const transaction = new TransactionBuilder(account, {
    fee: BASE_FEE,
    networkPassphrase: Networks.TESTNET,
  })
    .addOperation(Operation.changeTrust({ asset: usdcAsset }))
    .setTimeout(30)
    .build();

  transaction.sign(keypair);
  const response = await server.submitTransaction(transaction);

  if (!response.successful) {
    throw new Error(`Transaction failed: ${JSON.stringify(response)}`);
  }

  console.log(`Transaction succeeded: ${TX_EXPLORER_BASE}/${response.hash}`);

  console.log("Trustline established. This account can now receive USDC.");
}

main().catch(console.error);
```

<Info>
  Common errors you might encounter:

  * **`Friendbot funding failed: 400`**: The Friendbot rate limit was exceeded.
    Wait a few seconds and try again.
  * **`Transaction failed`**: The account may not be funded, or the USDC issuer
    address may be incorrect. Verify the `USDC_ISSUER` constant matches the
    [Stellar Testnet USDC issuer](/stablecoins/usdc-contract-addresses).
</Info>

## Step 3: Run the script

From the project directory, run:

```bash Shell theme={null}
npm run start
```

Your output should look similar to the following (addresses and hashes will
differ):

```bash Shell theme={null}
Creating and funding a user wallet...
======= User wallet details =======
Address: GCDE7JAXEY6Z2L6H4H5Z6Y7X8Y9Z0A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6
Secret key: SABCDEFGHIJKLMNOPQRSTUVWXYZ234567890ABCDEFGHIJKLMNOPQRSTUVW
NOTE: DO NOT SHARE THE SECRET KEY WITH ANYONE!
===================================

Creating a trustline for USDC...
Transaction succeeded: https://stellar.expert/explorer/testnet/tx/abc123def456...
Trustline established. This account can now receive USDC.
```

<Warning>
  This example uses one or more private keys for local testing. In production,
  use a secure key management solution and never expose or share private keys.
</Warning>
