Search code examples
solana

How to send USDC-SPL using @solana-labs/web3.js


I'm able to send SOL tokens using web3.js but have been unable to do so with USDC-SPL tokens. This is my current code for sending SOL tokens:

 // .......
 const connection = new Connection(network);
 const transaction = new Transaction()
  .add(
    SystemProgram.transfer({
      fromPubkey: publicKey,
      toPubkey: to,
      lamports: Number(amount) * 1000000000,
    })
  );
  const { blockhash } = await connection.getRecentBlockhash();
  transaction.recentBlockhash = blockhash;
  transaction.feePayer = publicKey;
  let signedTransaction: any = null;
  if ("solana" in window) {
    signedTransaction = await window.solana.signTransaction(transaction)
  } else if ("solflare" in window) {
    signedTransaction = await window.solflare.signTransaction(transaction);
  }
 // .......

The answers I've seen earlier are from people sending their own custom made tokens


Solution

  • All SPL tokens (including USDC token) on Solana are owned by spl-token program.

    So you can send USDC in the same way as sending your own custom made tokens by changing the token address to EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v (this is the USDC SPL token address on solana mainnet).

    For example:

    import * as web3 from "@solana/web3.js";
    import * as splToken from "@solana/spl-token";
    
    const DEMO_WALLET_SECRET_KEY = new Uint8Array([
        ...
      ]);
    
    const SOLANA_MAINNET_USDC_PUBKEY = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
    
    (async () => {
      // Connect to cluster
      var connection = new web3.Connection(web3.clusterApiUrl("devnet"));
      // Construct wallet keypairs
      var fromWallet = web3.Keypair.fromSecretKey(DEMO_WALLET_SECRET_KEY);
      var toWallet = web3.Keypair.generate();
      
      // Construct my token class
      var USDC_pubkey = new web3.PublicKey(SOLANA_MAINNET_USDC_PUBKEY);
      var USDC_Token = new splToken.Token(
        connection,
        USDC_pubkey,
        splToken.TOKEN_PROGRAM_ID,
        fromWallet
      );
      // Create associated token accounts for my token if they don't exist yet
      var fromTokenAccount = await USDC_Token.getOrCreateAssociatedAccountInfo(
        fromWallet.publicKey
      )
      var toTokenAccount = await USDC_Token.getOrCreateAssociatedAccountInfo(
        toWallet.publicKey
      )
      // Add token transfer instructions to transaction
      var transaction = new web3.Transaction()
        .add(
          splToken.Token.createTransferInstruction(
            splToken.TOKEN_PROGRAM_ID,
            fromTokenAccount.address,
            toTokenAccount.address,
            fromWallet.publicKey,
            [],
            0
          )
        );
      // Sign transaction, broadcast, and confirm
      var signature = await web3.sendAndConfirmTransaction(
        connection,
        transaction,
        [fromWallet]
      );
      console.log("SIGNATURE", signature);
      console.log("SUCCESS");
    })();