支付订阅
固定委托允许用户批准另一个钱包或服务提取最多固定数量的代币。每次成功转账都会减少剩余的额度。使用
expiryTs = 0 表示无过期时间。
本指南保持流程的可见性。每个代码片段直接使用 SDK 函数,以便您可以看到派生了哪个账户、发送了哪个指令,以及哪个签名者支付或授权每个步骤。
安装
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
创建委托
设置包含四个部分:
- 使用用户签名者和订阅插件创建客户端。
- 派生用户的代币账户和订阅授权 PDA。
- 如果订阅授权尚不存在,则进行初始化。
- 创建固定委托并派生其 PDA 以用于后续转账。
import { address, createClient } from '@solana/kit';import { solanaLocalRpc } from '@solana/kit-plugin-rpc';import { signer } from '@solana/kit-plugin-signer';import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';import {fetchMaybeSubscriptionAuthority,findFixedDelegationPda,findSubscriptionAuthorityPda,subscriptionsProgram,} from '@solana/subscriptions';const client = createClient().use(signer(userSigner)).use(solanaLocalRpc({ rpcUrl: 'http://127.0.0.1:8899' })).use(subscriptionsProgram());const tokenMint = address('TOKEN_MINT_ADDRESS_HERE');const delegatee = address('DELEGATEE_WALLET_ADDRESS_HERE');const nonce = 0n;const amount = 1_000_000n;const expiryTs = BigInt(Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 30);const [userAta] = await findAssociatedTokenPda({mint: tokenMint,owner: userSigner.address,tokenProgram: TOKEN_PROGRAM_ADDRESS,});const [subscriptionAuthorityPda] = await findSubscriptionAuthorityPda({user: userSigner.address,tokenMint,});const subscriptionAuthority = await fetchMaybeSubscriptionAuthority(client.rpc,subscriptionAuthorityPda,);if (!subscriptionAuthority.exists) {await client.subscriptions.instructions.initSubscriptionAuthority({tokenMint,tokenProgram: TOKEN_PROGRAM_ADDRESS,userAta,}).sendTransaction();}await client.subscriptions.instructions.createFixedDelegation({tokenMint,delegatee,nonce,amount,expiryTs,}).sendTransaction();const [delegationPda] = await findFixedDelegationPda({subscriptionAuthority: subscriptionAuthorityPda,delegator: userSigner.address,delegatee,nonce,});
从委托中转账
被委托方对转账进行签名。SDK 需要相同的委托 PDA、用户的代币账户和接收方代币账户。
const receiverAta = address('RECEIVER_TOKEN_ACCOUNT_ADDRESS_HERE');await client.subscriptions.instructions.transferFixed({delegatee: delegateeSigner,delegator: userSigner.address,delegatorAta: userAta,tokenMint,delegationPda,amount: 100_000n,receiverAta,tokenProgram: TOKEN_PROGRAM_ADDRESS,}).sendTransaction();
撤销委托
委托人可以随时撤销委托。撤销操作会关闭委托 PDA 并将其 rent 返还给签名者。
await client.subscriptions.instructions.revokeDelegation({authority: userSigner,delegationAccount: delegationPda,}).sendTransaction();
注意事项
- 用户的 token account 必须在初始化之前存在。
- 金额以基本单位表示。对于 6 位小数的代币,
1_000_000表示1个代币。 - 仅在订阅授权账户尚不存在时才运行
initSubscriptionAuthority。 - 用户对设置和撤销交易进行签名。受托人对转账进行签名。
Is this page helpful?