Skip to main content
Token utilities provide helper functions for working with SPL tokens, including getting associated token addresses, creating token accounts, and handling SOL vs token distinctions.

Import

import {
  getTokenAddress,
  getTokenAddressForDepositAndWithdraw,
  getTokenAccount,
  createTokenAccountIx,
  TOKEN_PROGRAM_ID,
  createTransferCheckedInstruction
} from '@drift-labs/common';

Functions

getTokenAddress

Get the associated token address for a given mint and user.
mintAddress
string
required
The SPL token mint address
userPubKey
string
required
The user’s wallet public key
tokenAddress
Promise<PublicKey>
The associated token account address
import { getTokenAddress } from '@drift-labs/common';

const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const userWallet = 'YourWalletPublicKey...';

const tokenAddress = await getTokenAddress(usdcMint, userWallet);
console.log('Token Address:', tokenAddress.toString());

getTokenAddressForDepositAndWithdraw

Get the associated token address for deposits and withdrawals. For SOL, returns the user’s wallet address instead of a token account.
mintAddress
PublicKey
required
The SPL token mint address
authorityPubKey
PublicKey
required
The authority’s public key (usually the user’s wallet)
tokenProgram
PublicKey
default:"TOKEN_PROGRAM_ID"
The token program ID (use TOKEN_2022_PROGRAM_ID for Token-2022 tokens)
tokenAddress
Promise<PublicKey>
The token account address, or wallet address for SOL
import { getTokenAddressForDepositAndWithdraw } from '@drift-labs/common';
import { PublicKey } from '@solana/web3.js';
import { WRAPPED_SOL_MINT } from '@drift-labs/sdk';

const userWallet = new PublicKey('YourWalletPublicKey...');

// For SOL deposits/withdrawals, returns the wallet address
const solAddress = await getTokenAddressForDepositAndWithdraw(
  WRAPPED_SOL_MINT,
  userWallet
);
console.log('SOL Address:', solAddress.toString()); // Same as userWallet

// For other tokens, returns the associated token account
const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
const usdcAddress = await getTokenAddressForDepositAndWithdraw(
  usdcMint,
  userWallet
);
console.log('USDC Token Account:', usdcAddress.toString());

getTokenAccount

Get the token account for a given mint and user, including account data.
connection
Connection
required
Solana RPC connection
mintAddress
string
required
The SPL token mint address
userPubKey
string
required
The user’s wallet public key
pubkey
PublicKey
The token account public key
account
AccountInfo<ParsedAccountData>
The token account data
import { getTokenAccount } from '@drift-labs/common';
import { Connection } from '@solana/web3.js';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const usdcMint = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const userWallet = 'YourWalletPublicKey...';

const tokenAccount = await getTokenAccount(
  connection,
  usdcMint,
  userWallet
);

console.log('Token Account:', tokenAccount.pubkey.toString());
console.log('Account Data:', tokenAccount.account.data);

createTokenAccountIx

Create a transaction instruction to create an associated token account.
owner
PublicKey
required
The owner of the token account
mintAddress
PublicKey
required
The SPL token mint address
payer
PublicKey
The payer for the account creation (defaults to owner)
instruction
Promise<TransactionInstruction>
Transaction instruction to create the associated token account
import { createTokenAccountIx } from '@drift-labs/common';
import { PublicKey, Transaction } from '@solana/web3.js';

const owner = new PublicKey('OwnerPublicKey...');
const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

// Create instruction
const createIx = await createTokenAccountIx(owner, usdcMint);

// Add to transaction
const tx = new Transaction().add(createIx);

// Or specify different payer
const payer = new PublicKey('PayerPublicKey...');
const createIxWithPayer = await createTokenAccountIx(
  owner,
  usdcMint,
  payer
);

Re-exported SPL Token Functions

The following functions are re-exported from @solana/spl-token for convenience:

TOKEN_PROGRAM_ID

import { TOKEN_PROGRAM_ID } from '@drift-labs/common';

console.log(TOKEN_PROGRAM_ID.toString());
// TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

createTransferCheckedInstruction

Create a transfer instruction with token amount verification.
import { createTransferCheckedInstruction, TOKEN_PROGRAM_ID } from '@drift-labs/common';
import { PublicKey } from '@solana/web3.js';

const source = new PublicKey('SourceTokenAccount...');
const mint = new PublicKey('MintAddress...');
const destination = new PublicKey('DestinationTokenAccount...');
const owner = new PublicKey('OwnerPublicKey...');

const transferIx = createTransferCheckedInstruction(
  source,
  mint,
  destination,
  owner,
  1000000, // amount (in token's smallest unit)
  6 // decimals
);

Complete Examples

Deposit Tokens to Drift

import {
  getTokenAddressForDepositAndWithdraw,
  createTokenAccountIx,
} from '@drift-labs/common';
import { PublicKey, Connection, Transaction } from '@solana/web3.js';
import { DriftClient } from '@drift-labs/sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const userWallet = new PublicKey('YourWalletPublicKey...');
const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

// Get or create token account
const tokenAddress = await getTokenAddressForDepositAndWithdraw(
  usdcMint,
  userWallet
);

// Check if account exists, if not create it
const accountInfo = await connection.getAccountInfo(tokenAddress);
if (!accountInfo) {
  const createIx = await createTokenAccountIx(userWallet, usdcMint);
  const tx = new Transaction().add(createIx);
  // ... sign and send transaction
}

// Proceed with deposit
const driftClient = new DriftClient({...});
const depositAmount = 1000 * 1e6; // 1000 USDC
await driftClient.deposit(
  depositAmount,
  0, // market index
  tokenAddress
);

Handle SOL vs SPL Tokens

import { getTokenAddressForDepositAndWithdraw } from '@drift-labs/common';
import { PublicKey } from '@solana/web3.js';
import { WRAPPED_SOL_MINT } from '@drift-labs/sdk';

async function getDepositAddress(
  mint: PublicKey,
  wallet: PublicKey
): Promise<PublicKey> {
  // This function handles both SOL and SPL tokens automatically
  const address = await getTokenAddressForDepositAndWithdraw(mint, wallet);
  
  if (mint.equals(WRAPPED_SOL_MINT)) {
    console.log('Using SOL - wallet address:', address.toString());
  } else {
    console.log('Using SPL token - ATA address:', address.toString());
  }
  
  return address;
}

const wallet = new PublicKey('YourWalletPublicKey...');

// For SOL deposits
const solAddress = await getDepositAddress(WRAPPED_SOL_MINT, wallet);

// For USDC deposits
const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
const usdcAddress = await getDepositAddress(usdcMint, wallet);

Working with Token-2022 Tokens

import { getTokenAddressForDepositAndWithdraw } from '@drift-labs/common';
import { PublicKey } from '@solana/web3.js';
import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';

const token2022Mint = new PublicKey('Token2022MintAddress...');
const userWallet = new PublicKey('YourWalletPublicKey...');

// Use TOKEN_2022_PROGRAM_ID for Token-2022 tokens
const tokenAddress = await getTokenAddressForDepositAndWithdraw(
  token2022Mint,
  userWallet,
  TOKEN_2022_PROGRAM_ID
);

console.log('Token-2022 Account:', tokenAddress.toString());
import { WRAPPED_SOL_MINT } from '@drift-labs/sdk';

// Native SOL mint address
console.log(WRAPPED_SOL_MINT.toString());
// So11111111111111111111111111111111111111112

Source Code

Location: ~/workspace/source/common-ts/src/utils/token.ts

Build docs developers (and LLMs) love