Jacky Gu

Solana开发笔记: typescript前端常用程序片段

01 Jan 2025 Share to

typescript前端常用程序片段

1- import:

import { Keypair, Connection, PublicKey, Transaction } from "@solana/web3.js";
import {
  createTransferCheckedInstruction,
  createAssociatedTokenAccountInstruction,
  getAssociatedTokenAddress,
  getOrCreateAssociatedTokenAccount,
} from "@solana/spl-token";
import {bs58} from "@coral-xyz/anchor/dist/cjs/utils/bytes";

1- 链接connection

const connection = new Connection("https://api.<network>.solana.com");

network: mainnet, devnet, localhost etc.

2- 获取账户与余额

import { LAMPORTS_PER_SOL } from "@solana/web3.js"
const myAccount = Keypair.fromSecretKey([84, 0, ... , 12, 68]);
// 获取SOL余额
const balance = await connection.getBalance(keypair.publicKey.toBase58());
return balance / LAMPORTS_PER_SOL

3- 获取或创建PDA/ATA账户

方法1: 用于确定已经建立了ATA

let ata = await getAssociatedTokenAddress(
  splTokenMint, // token mint地址
  publicKey, // 需要查询账户的公钥
  false
);

方法2:未确定ATA是否已经创建(需要发送signer,因为如果没有创建,需要创建)

  const ata = await getOrCreateAssociatedTokenAccount(
    connection,
    signer, // 发起交易的签名人
    splTokenMint, // token mint地址
    publicKey, // 需要查询账户的公钥
  );

3.5- 转账SOL(平台币)

import {
  Keypair,
  Connection,
  clusterApiUrl,
  PublicKey,
  LAMPORTS_PER_SOL,
  SystemProgram,
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";

const sendTo = async (connection: Connection, senderKeypair: Keypair, recipient: string, amount: number) => {
  const transaction = new Transaction();
  const sendSolInstruction = SystemProgram.transfer({ // Use SystemProgram.transfer to send SOL
    fromPubkey: senderKeypair.publicKey,
    toPubkey: new PublicKey(recipient),
    lamports: LAMPORTS_PER_SOL * amount,
  });
  transaction.add(sendSolInstruction);
  const signature = await sendAndConfirmTransaction(
    connection,
    transaction,
    [senderKeypair]
  );
  return signature;
}

4- 转账Token

方法1: 针对直接在前端用TokenProgram创建的Token,可以使用@solana/spl-token的transfer方法

import * as token from "@solana/spl-token";

const transferToken = async (
  connection: web3.Connection,
  tokenMintAccount: web3.PublicKey,
  sender: web3.Keypair,
  recipient: web3.PublicKey,
  amount: number
): Promise<string> => {
  // 创建目标账号的Token Account,如果已经创建,则不会再创建
  const senderTokenAccount = await token.getOrCreateAssociatedTokenAccount(
    connection,
    sender,
    tokenMintAccount,
    sender.publicKey,
  );

  // 创建接收账号的Token Account
  const recipientTokenAccount = await token.getOrCreateAssociatedTokenAccount(
    connection,
    sender,
    tokenMintAccount,
    recipient,
  );

  // 转账
  const transactionSignature = await token.transfer(
    connection,
    sender,
    senderTokenAccount.address,
    recipientTokenAccount.address,
    sender,
    amount * 10**6, // decimals = 6
  );
  return transactionSignature;
}

方法2: 针对在合约中通过cpi方式调用TokenProgram的自己开发的Token程序:

let transaction = new Transaction();
transaction.add(
  createTransferCheckedInstruction(
      new PublicKey(sourceATA), // sender的ATA
      splTokenMint,
      new PublicKey(destinationATA), // receiver的ATA
      sender.publicKey, // owner publickey
      amount, // lamports
      9       // decimals
  )
)
let tx = await connection.sendTransaction(transaction, [signer/sender])