使用 Token.createTransferInstruction 转账 NFT
我们有一项转移 SOL 和 SOL 的交易;从钱包所有者到我们钱包的 NFT。 该交易包含简单的指令:
- Token.createAssociatedTokenAccountInstruction
有条件的,取决于目的地(我们的钱包) - Token.createTransferInstruction 从所有者的代币账户转账到我们的代币账户。
- 系统程序传输 SOL 传输。
这是转移代码(spl-token v0.1.8)
let createTransferInstructions = async function (mint, from, to, cluster) {
let connection = new Connection(cluster, "confirmed")
const mintPublicKey = new PublicKey(mint);
const ownerPublicKey = new PublicKey(from);
const destPublicKey = new PublicKey(to);
// GET SOURCE ASSOCIATED ACCOUNT
const associatedSourceTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
ownerPublicKey
);
// GET DESTINATION ASSOCIATED ACCOUNT
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions = [];
if (receiverAccount === null)
instructions.push(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
ownerPublicKey
)
)
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
associatedSourceTokenAddr,
associatedDestinationTokenAddr,
ownerPublicKey,
[],
1
)
);
return instructions;
}
这是交易代码:
var transaction = new this.solana.Transaction({
feePayer: new this.solana.PublicKey(from),
recentBlockhash: await blockhashObj.blockhash
});
for (let transferInstruction of transferInstructions) {
transaction.add(transferInstruction);
}
transaction.add(this.solana.SystemProgram.transfer({
fromPubkey: new this.solana.PublicKey(this.provider.publicKey),
toPubkey: new this.solana.PublicKey(farm.address),
lamports: 10000000
}));
所有者必须使用他们的钱包(phantom、solflare 等..)验证交易
对于大多数 NFT 来说,一切都运转良好。
一些 NFT 所有者抱怨无法在钱包上验证交易,错误消息表明交易无法确认。
然而,NFT 可以使用钱包界面成功转移,可以在市场上列出等。即使 NFT 转移到另一个钱包,上述交易也可以完美运行。
我想知道这是否与关联的令牌帐户有任何关系? 如果是这样,解决办法是什么?
We have a transaction that transfers SOL & an NFT from the wallet's owner to our wallet.
The transaction contains simple instructions:
- Token.createAssociatedTokenAccountInstruction
Conditionnal, depending on the destination (our wallet) - Token.createTransferInstruction
Transfers from the owner's token account to our token account. - SystemProgram.transfer
SOL transfer.
Here is the transfer code (spl-token v0.1.8)
let createTransferInstructions = async function (mint, from, to, cluster) {
let connection = new Connection(cluster, "confirmed")
const mintPublicKey = new PublicKey(mint);
const ownerPublicKey = new PublicKey(from);
const destPublicKey = new PublicKey(to);
// GET SOURCE ASSOCIATED ACCOUNT
const associatedSourceTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
ownerPublicKey
);
// GET DESTINATION ASSOCIATED ACCOUNT
const associatedDestinationTokenAddr = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
destPublicKey
);
const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
const instructions = [];
if (receiverAccount === null)
instructions.push(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mintPublicKey,
associatedDestinationTokenAddr,
destPublicKey,
ownerPublicKey
)
)
instructions.push(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
associatedSourceTokenAddr,
associatedDestinationTokenAddr,
ownerPublicKey,
[],
1
)
);
return instructions;
}
Here is the transaction code:
var transaction = new this.solana.Transaction({
feePayer: new this.solana.PublicKey(from),
recentBlockhash: await blockhashObj.blockhash
});
for (let transferInstruction of transferInstructions) {
transaction.add(transferInstruction);
}
transaction.add(this.solana.SystemProgram.transfer({
fromPubkey: new this.solana.PublicKey(this.provider.publicKey),
toPubkey: new this.solana.PublicKey(farm.address),
lamports: 10000000
}));
The owners have to validate the transaction with their wallets (phantom, solflare etc..)
And everything works great, for most NFTs.
Some NFT owners are complaining about not being able to validate the transaction on the wallet, an error message indicates that the transaction can't be confirmed.
However, the NFT can be transferred successfully using the wallet's interface, can be listed on marketplaces etc. Even when the NFT is transferred to another wallet, the transaction above works perfectly.
I'm wondering if this has anything to do with the associated token account?
If so, what is the solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论