如何通过'@solana/web3.js'传输自定义令牌
How to transfer custom token by '@solana/web3.js'
我想使用 solana web3.js 发送除 sol 之外的已部署令牌,但我不知道如何发送。官方文档找了好久,没找到。如果您有这方面的任何信息,能否请您告诉我?谢谢
您需要确保为令牌程序安装 npm 绑定,您可以从下面的导入中看到
import * as web3 from "@solana/web3.js";
import * as splToken from "@solana/spl-token";
// Address: 9vpsmXhZYMpvhCKiVoX5U8b1iKpfwJaFpPEEXF7hRm9N
const DEMO_WALLET_SECRET_KEY = new Uint8Array([
37, 21, 197, 185, 105, 201, 212, 148, 164, 108, 251, 159, 174, 252, 43, 246,
225, 156, 38, 203, 99, 42, 244, 73, 252, 143, 34, 239, 15, 222, 217, 91, 132,
167, 105, 60, 17, 211, 120, 243, 197, 99, 113, 34, 76, 127, 190, 18, 91, 246,
121, 93, 189, 55, 165, 129, 196, 104, 25, 157, 209, 168, 165, 149,
]);
(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 myMint = new web3.PublicKey("My Mint Public Address");
var myToken = new splToken.Token(
connection,
myMint,
splToken.TOKEN_PROGRAM_ID,
fromWallet
);
// Create associated token accounts for my token if they don't exist yet
var fromTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
fromWallet.publicKey
)
var toTokenAccount = await myToken.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");
})();
现有答案的问题在于,它们只向您展示了如何首先创建一个新的自定义令牌,然后执行从一个钱包到另一个钱包的转移。在这里,我将展示如何使用现有的自定义令牌执行此操作。
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { web3, Wallet } from "@project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const mintToken = new Token(
connection,
mintPublicKey,
TOKEN_PROGRAM_ID,
wallet.payer // the wallet owner will pay to transfer and to create recipients associated token account if it does not yet exist.
);
const fromTokenAccount = await mintToken.getOrCreateAssociatedAccountInfo(
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions: web3.TransactionInstruction[] = [];
if (receiverAccount === null) {
instructions.push(
Token.createAssociatedTokenAccountInstruction(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
wallet.publicKey
)
)
}
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
fromTokenAccount.address,
associatedDestinationTokenAddr,
wallet.publicKey,
[],
amount
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}
请注意我们如何添加用于创建收件人自定义令牌帐户的说明(如果他们没有的话)。
@Ozymandias 回答的小更新,spl-token
库中似乎没有什么变化。
首先 Token
不存在了。并且 Token.getAssociatedTokenAddress
等少数功能似乎也被删除了。这是更新后的代码:
import * as splToken from "@solana/spl-token";
import { web3, Wallet } from "@project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const {TOKEN_PROGRAM_ID} = splToken
const fromTokenAccount = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr.address);
const instructions: web3.TransactionInstruction[] = [];
instructions.push(
splToken.createTransferInstruction(
fromTokenAccount.address,
associatedDestinationTokenAddr.address,
wallet.publicKey,
amount,
[],
TOKEN_PROGRAM_ID
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}
我想使用 solana web3.js 发送除 sol 之外的已部署令牌,但我不知道如何发送。官方文档找了好久,没找到。如果您有这方面的任何信息,能否请您告诉我?谢谢
您需要确保为令牌程序安装 npm 绑定,您可以从下面的导入中看到
import * as web3 from "@solana/web3.js";
import * as splToken from "@solana/spl-token";
// Address: 9vpsmXhZYMpvhCKiVoX5U8b1iKpfwJaFpPEEXF7hRm9N
const DEMO_WALLET_SECRET_KEY = new Uint8Array([
37, 21, 197, 185, 105, 201, 212, 148, 164, 108, 251, 159, 174, 252, 43, 246,
225, 156, 38, 203, 99, 42, 244, 73, 252, 143, 34, 239, 15, 222, 217, 91, 132,
167, 105, 60, 17, 211, 120, 243, 197, 99, 113, 34, 76, 127, 190, 18, 91, 246,
121, 93, 189, 55, 165, 129, 196, 104, 25, 157, 209, 168, 165, 149,
]);
(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 myMint = new web3.PublicKey("My Mint Public Address");
var myToken = new splToken.Token(
connection,
myMint,
splToken.TOKEN_PROGRAM_ID,
fromWallet
);
// Create associated token accounts for my token if they don't exist yet
var fromTokenAccount = await myToken.getOrCreateAssociatedAccountInfo(
fromWallet.publicKey
)
var toTokenAccount = await myToken.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");
})();
现有答案的问题在于,它们只向您展示了如何首先创建一个新的自定义令牌,然后执行从一个钱包到另一个钱包的转移。在这里,我将展示如何使用现有的自定义令牌执行此操作。
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
import { web3, Wallet } from "@project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const mintToken = new Token(
connection,
mintPublicKey,
TOKEN_PROGRAM_ID,
wallet.payer // the wallet owner will pay to transfer and to create recipients associated token account if it does not yet exist.
);
const fromTokenAccount = await mintToken.getOrCreateAssociatedAccountInfo(
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions: web3.TransactionInstruction[] = [];
if (receiverAccount === null) {
instructions.push(
Token.createAssociatedTokenAccountInstruction(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
wallet.publicKey
)
)
}
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
fromTokenAccount.address,
associatedDestinationTokenAddr,
wallet.publicKey,
[],
amount
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}
请注意我们如何添加用于创建收件人自定义令牌帐户的说明(如果他们没有的话)。
@Ozymandias 回答的小更新,spl-token
库中似乎没有什么变化。
首先 Token
不存在了。并且 Token.getAssociatedTokenAddress
等少数功能似乎也被删除了。这是更新后的代码:
import * as splToken from "@solana/spl-token";
import { web3, Wallet } from "@project-serum/anchor";
async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) {
const mintPublicKey = new web3.PublicKey(tokenMintAddress);
const {TOKEN_PROGRAM_ID} = splToken
const fromTokenAccount = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
wallet.publicKey
);
const destPublicKey = new web3.PublicKey(to);
// Get the derived address of the destination wallet which will hold the custom token
const associatedDestinationTokenAddr = await splToken.getOrCreateAssociatedTokenAccount(
connection,
wallet.payer,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr.address);
const instructions: web3.TransactionInstruction[] = [];
instructions.push(
splToken.createTransferInstruction(
fromTokenAccount.address,
associatedDestinationTokenAddr.address,
wallet.publicKey,
amount,
[],
TOKEN_PROGRAM_ID
)
);
const transaction = new web3.Transaction().add(...instructions);
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash;
const transactionSignature = await connection.sendRawTransaction(
transaction.serialize(),
{ skipPreflight: true }
);
await connection.confirmTransaction(transactionSignature);
}