> ## 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.

# Quickstart: Transfer USDC on Aptos

> Send USDC between accounts on Aptos Testnet using the Aptos TypeScript SDK.

USDC on Aptos is a fungible asset issued by Circle. Transferring USDC between
Aptos accounts moves the asset between primary fungible stores. The
[`@aptos-labs/ts-sdk`](https://github.com/aptos-labs/aptos-ts-sdk) script you
build in this guide will:

* Load your sender wallet from a private key
* Check your testnet USDC balance
* Transfer USDC to a recipient address you set in the script

## Prerequisites

Before you begin, ensure that you've:

* Installed [Node.js v22.6+](https://nodejs.org/)
* Set up a terminal and code editor for running commands and editing files
* Created an Aptos Testnet wallet with the private key available
  * Funded with testnet APT (for transaction fees) from the
    [Aptos Faucet](https://aptos.dev/en/network/faucet)
  * Funded with testnet USDC from the [Circle Faucet](https://faucet.circle.com)

## Contract addresses

You need the following Aptos Testnet USDC fungible asset metadata address:

* Testnet:
  [`0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832`](https://explorer.aptoslabs.com/fungible_asset/0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832?network=testnet)

## Step 1: Set up the project

### 1.1. Create the project and install dependencies

Create a new directory, setup a Node.js project, and install the required
dependencies:

```bash Shell theme={null}
mkdir aptos-usdc-transfer
cd aptos-usdc-transfer
npm init -y
npm pkg set type=module
npm pkg set scripts.start="node --env-file=.env main.ts"
npm install @aptos-labs/ts-sdk
npm install --save-dev typescript @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
```

### 1.3. Configure environment variables

Create a `.env` file in your project directory and add your sender's private
key. Use either an AIP-80 formatted key (`ed25519-priv-0x...`) or a raw hex
private key from your wallet export.

```text .env theme={null}
APTOS_PRIVATE_KEY=YOUR_SENDER_PRIVATE_KEY
```

<Tip>
  Open `.env` in your editor rather than writing values with shell commands, and
  add `.env` to your `.gitignore`. This prevents credentials from leaking into
  your shell history or version control.
</Tip>

<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>

## Step 2: Create the transfer script

Add `main.ts` at the project root. The script:

1. Loads your existing sender wallet from the environment variable
2. Reads the sender's USDC balance
3. Builds a fungible asset transfer to your recipient address
4. Signs, submits, and waits for the transaction

Replace `0xYOUR_RECIPIENT_ADDRESS` with the Aptos address that should receive
the USDC.

```typescript main.ts theme={null}
import {
  Account,
  Aptos,
  AptosConfig,
  Ed25519PrivateKey,
  Network,
} from "@aptos-labs/ts-sdk";

// Testnet USDC fungible-asset metadata address
const USDC_METADATA =
  "0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832";
const USDC_DECIMALS = 6;
const TRANSFER_AMOUNT = 1 * 10 ** USDC_DECIMALS; // 1 USDC in base units
const RECIPIENT_ADDRESS = "0xYOUR_RECIPIENT_ADDRESS";
const EXPLORER_TX = "https://explorer.aptoslabs.com/txn";

const aptos = new Aptos(new AptosConfig({ network: Network.TESTNET }));

if (!process.env.APTOS_PRIVATE_KEY) {
  throw new Error("Set APTOS_PRIVATE_KEY in .env");
}

// 1. Load sender from the private key
const sender = Account.fromPrivateKey({
  privateKey: new Ed25519PrivateKey(process.env.APTOS_PRIVATE_KEY),
});

console.log("Sender:", sender.accountAddress.toString());
console.log("Recipient:", RECIPIENT_ADDRESS);

// 2. Read sender USDC balance (base units)
const balance = await aptos.getBalance({
  accountAddress: sender.accountAddress,
  asset: USDC_METADATA,
});
console.log("USDC balance:", balance / 10 ** USDC_DECIMALS);

if (balance < TRANSFER_AMOUNT) {
  throw new Error("Insufficient USDC (fund via https://faucet.circle.com)");
}

// 3. Build FA transfer (primary store → primary store)
const transaction = await aptos.transferFungibleAsset({
  sender,
  fungibleAssetMetadataAddress: USDC_METADATA,
  recipient: RECIPIENT_ADDRESS,
  amount: TRANSFER_AMOUNT,
});

// 4. Sign, submit, wait
const pending = await aptos.signAndSubmitTransaction({
  signer: sender,
  transaction,
});
const committed = await aptos.waitForTransaction({
  transactionHash: pending.hash,
});

if (!committed.success) {
  throw new Error(`Transaction failed: ${committed.hash}`);
}

console.log(
  `Transfer confirmed: ${EXPLORER_TX}/${committed.hash}?network=testnet`,
);
```

## 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}
Sender: 0xce1d...8936
Recipient: 0xd180...5e10
USDC balance: 20
Transfer confirmed: https://explorer.aptoslabs.com/txn/0xb28e...ca15?network=testnet
```

Open the explorer URL from the `Transfer confirmed:` line to view the
transaction on Aptos Testnet.

<Info>
  Common errors you might encounter:

  * **`Set APTOS_PRIVATE_KEY in .env`**: The private key is missing. Add
    `APTOS_PRIVATE_KEY` to `.env` and run with `npm run start` (which loads the
    file via `--env-file`).
  * **`Insufficient USDC`**: The sender does not have enough testnet USDC. Fund
    the wallet from the [Circle Faucet](https://faucet.circle.com) before running
    the script.
  * **Transaction failure / out of gas**: The sender needs testnet APT for fees.
    Request APT from the [Aptos Faucet](https://aptos.dev/en/network/faucet).
</Info>
