Thanh toánĐăng ký

Ủy Quyền Cố Định

Ủy quyền cố định cho phép người dùng phê duyệt một ví hoặc dịch vụ khác rút lên đến một số lượng token cố định. Mỗi lần chuyển thành công sẽ giảm hạn mức còn lại. Sử dụng expiryTs = 0 để không có thời hạn hết hạn.

Hướng dẫn này giữ quy trình rõ ràng. Mỗi đoạn mã sử dụng trực tiếp các hàm SDK để bạn có thể thấy tài khoản nào được tạo, chỉ thị nào được gửi, và người ký nào trả phí hoặc ủy quyền từng bước.

Cài Đặt

pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token

Tạo Ủy Quyền

Quá trình thiết lập có bốn phần:

  1. Tạo một client với người ký của người dùng và plugin subscriptions.
  2. Tạo token account của người dùng và PDA Subscription Authority.
  3. Khởi tạo Subscription Authority nếu nó chưa tồn tại.
  4. Tạo ủy quyền cố định và tạo PDA của nó cho các lần chuyển tiếp sau.
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,
});

Chuyển Từ Ủy Quyền

Người được ủy quyền ký giao dịch chuyển. SDK cần cùng một PDA ủy quyền, token account của người dùng và token account của người nhận.

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();

Thu Hồi Ủy Quyền

Người ủy quyền có thể thu hồi ủy quyền bất cứ lúc nào. Việc thu hồi sẽ đóng PDA ủy quyền và trả lại tiền rent cho người ký.

await client.subscriptions.instructions
.revokeDelegation({
authority: userSigner,
delegationAccount: delegationPda,
})
.sendTransaction();

Lưu Ý

  • Token account của người dùng phải tồn tại trước khi khởi tạo.
  • Số lượng được tính theo đơn vị cơ bản. Đối với token có 6 chữ số thập phân, 1_000_000 có nghĩa là 1 token.
  • Chỉ chạy initSubscriptionAuthority khi tài khoản Subscription Authority chưa tồn tại.
  • Người dùng ký các giao dịch thiết lập và thu hồi. Người được ủy quyền ký các giao dịch chuyển tiền.

Is this page helpful?

Mục lục

Chỉnh sửa trang