Skip to main content
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 you have:
  • Installed Node.js v18 or later
  • Set up a terminal and code editor for running commands and editing files

Step 1: Set up the project

1.1. Create a project directory

Run the following commands to create and initialize your project:
Shell
mkdir xlm-usdc-trustline
cd xlm-usdc-trustline
npm init -y
You should have a new project folder, a package.json from npm init, and be in that directory for the next command.

1.2. Install dependencies

Run the following command to install the required libraries:
Shell
npm install @stellar/stellar-sdk typescript ts-node
Your folder now includes node_modules and the dependencies are recorded in package.json (and package-lock.json if npm created one).

Step 2: Configure the TypeScript project

2.1. Update the package.json file

Open package.json and:
  • Remove the "type": "commonjs" line if npm added it.
  • Add or update the start script to run ts-node main.ts.
Your file should look similar to:
package.json
{
  "name": "xlm-usdc-trustline",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "ts-node main.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@stellar/stellar-sdk": "^13.1.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.8.3"
  }
}

2.2. Add a tsconfig.json file

Create tsconfig.json with the following configuration:
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "lib": ["ES2020"],
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./"
  },
  "include": ["*.ts"],
  "exclude": ["node_modules"]
}
With both files in place, npm start can run TypeScript with ts-node once you add main.ts.

Step 3: 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);
Save the file as main.ts in the project root so npm start can find it.
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 4: Run the application

From the project directory, run:
Shell
npm 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.