Skip to main content

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.

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. In this quickstart, you create a TypeScript script that uses @stellar/stellar-sdk to:
  • Create and fund a Stellar Testnet wallet
  • Establish a USDC trustline so the wallet can receive USDC
This quickstart funds the account with Friendbot’s HTTP API from your script. You can use Stellar Lab to fund on Stellar Testnet in the browser.

Prerequisites

Before you begin, ensure that you’ve:
  • Installed Node.js v22+ 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:
Shell
# 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="npx tsx 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)

This step is optional. It helps prevent missing types in your IDE or editor.
Create a tsconfig.json file:
npx tsc --init
Then, update the tsconfig.json file:
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 (Stellar’s HTTP API for submitting transactions).
main.ts
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);
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.

Step 3: Run the script

From the project directory, run:
Shell
npm run start
Your output should look similar to the following (addresses and hashes will differ):
Shell
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.
This use of a private key is simplified for demonstration purposes. In production, store and access your private key securely and never share it.