如何使用@solana/web3.js请求转账NFT
How to request transfer of NFT using @solana/web3.js
我正在开发一个网络应用程序,NFT 所有者可以在其中抵押他们的 NFT 并获得奖励。
在我的应用程序中,我需要创建从用户钱包到我的应用程序钱包的 NFT 转移请求。
代码示例:
import { Connection, PublicKey } from "@solana/web3.js";
import * as anchor from "@project-serum/anchor";
import { web3 } from "@project-serum/anchor";
import {
Token,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
const doNFTTransfer = async function (mint: string, from: Wallet, to: string) {
let connection = new Connection("https://api.devnet.solana.com");
const mintPublicKey = new web3.PublicKey(mint);// Mint is the Mint address found in the NFT metadata
const ownerPublicKey = from.publicKey;
const destPublicKey = new web3.PublicKey("MY_APPS_WALLET_ADDRESS");
const mintToken = new Token(
connection,
mintPublicKey,
TOKEN_PROGRAM_ID,
from.payer
);
// GET SOURCE ASSOCIATED ACCOUNT
const associatedSourceTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
ownerPublicKey
);
// GET DESTINATION ASSOCIATED ACCOUNT
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(
associatedDestinationTokenAddr
);
const instructions = [];
if (receiverAccount === null) {
console.log("receiver account is null!");
instructions.push(
Token.createAssociatedTokenAccountInstruction(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
ownerPublicKey
)
);
}
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
associatedSourceTokenAddr,
associatedDestinationTokenAddr,
ownerPublicKey,
[],
1
)
);
// This transaction is sending the tokens
let transaction = null;
for (let i = 0; i < instructions.length; i++) {
transaction = new web3.Transaction().add(instructions[i]);
}
if (transaction) {
let response = await from.sendTransaction(transaction, connection);
console.log("response: ", response);
} else {
console.log("Transaction error: transaction data is null");
}
};
export default doNFTTransfer;
然而当我运行代码。批准交易后提示用户接受交易 我收到以下错误。
next-dev.js?3515:32 Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]
Program log: Instruction: Transfer
Program log: Error: InvalidAccountData
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1781 of 200000 compute units
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction
我也试过交换
- mintToken.associatedProgramID 与 ASSOCIATED_TOKEN_PROGRAM_ID
- mintToken.programI 与 TOKEN_PROGRAM_ID
从@solana/spl-token
导入
有人知道我的问题是什么吗?
我认为这部分是你的问题:
// This transaction is sending the tokens
let transaction = null;
for (let i = 0; i < instructions.length; i++) {
transaction = new web3.Transaction().add(instructions[i]);
}
每次循环运行时,它都会覆盖整个事务。这意味着只会发送您进行的最后一笔交易(createTransferInstruction)。以下应该更好用!
// This transaction is sending the tokens
let transaction = new web3.Transaction();
for (let i = 0; i < instructions.length; i++) {
transaction.add(instructions[i]);
}
我正在开发一个网络应用程序,NFT 所有者可以在其中抵押他们的 NFT 并获得奖励。 在我的应用程序中,我需要创建从用户钱包到我的应用程序钱包的 NFT 转移请求。
代码示例:
import { Connection, PublicKey } from "@solana/web3.js";
import * as anchor from "@project-serum/anchor";
import { web3 } from "@project-serum/anchor";
import {
Token,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
const doNFTTransfer = async function (mint: string, from: Wallet, to: string) {
let connection = new Connection("https://api.devnet.solana.com");
const mintPublicKey = new web3.PublicKey(mint);// Mint is the Mint address found in the NFT metadata
const ownerPublicKey = from.publicKey;
const destPublicKey = new web3.PublicKey("MY_APPS_WALLET_ADDRESS");
const mintToken = new Token(
connection,
mintPublicKey,
TOKEN_PROGRAM_ID,
from.payer
);
// GET SOURCE ASSOCIATED ACCOUNT
const associatedSourceTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
ownerPublicKey
);
// GET DESTINATION ASSOCIATED ACCOUNT
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(
associatedDestinationTokenAddr
);
const instructions = [];
if (receiverAccount === null) {
console.log("receiver account is null!");
instructions.push(
Token.createAssociatedTokenAccountInstruction(
mintToken.associatedProgramId,
mintToken.programId,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
ownerPublicKey
)
);
}
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
associatedSourceTokenAddr,
associatedDestinationTokenAddr,
ownerPublicKey,
[],
1
)
);
// This transaction is sending the tokens
let transaction = null;
for (let i = 0; i < instructions.length; i++) {
transaction = new web3.Transaction().add(instructions[i]);
}
if (transaction) {
let response = await from.sendTransaction(transaction, connection);
console.log("response: ", response);
} else {
console.log("Transaction error: transaction data is null");
}
};
export default doNFTTransfer;
然而当我运行代码。批准交易后提示用户接受交易 我收到以下错误。
next-dev.js?3515:32 Transaction simulation failed: Error processing Instruction 0: invalid account data for instruction
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]
Program log: Instruction: Transfer
Program log: Error: InvalidAccountData
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1781 of 200000 compute units
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA failed: invalid account data for instruction
我也试过交换
- mintToken.associatedProgramID 与 ASSOCIATED_TOKEN_PROGRAM_ID
- mintToken.programI 与 TOKEN_PROGRAM_ID
从@solana/spl-token
导入有人知道我的问题是什么吗?
我认为这部分是你的问题:
// This transaction is sending the tokens
let transaction = null;
for (let i = 0; i < instructions.length; i++) {
transaction = new web3.Transaction().add(instructions[i]);
}
每次循环运行时,它都会覆盖整个事务。这意味着只会发送您进行的最后一笔交易(createTransferInstruction)。以下应该更好用!
// This transaction is sending the tokens
let transaction = new web3.Transaction();
for (let i = 0; i < instructions.length; i++) {
transaction.add(instructions[i]);
}