Gói đăng ký cho phép người bán công bố các điều khoản thanh toán mà người dùng có thể chấp nhận. Sau khi người dùng đăng ký, người bán hoặc bên được ủy quyền có thể thu tiền lên đến số tiền trong gói cho mỗi kỳ thanh toán.
Hướng dẫn này trình bày toàn bộ quy trình dưới dạng các khối xây dựng. Người bán tạo gói, người đăng ký chấp nhận gói đó, và người bán hoặc bên được ủy quyền thu tiền từ PDA đăng ký được tạo ra.
Cài Đặt
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
Tạo Gói
Người bán sở hữu gói. PDA của gói được tạo từ địa chỉ người bán và planId.
import { address, createClient } from '@solana/kit';import { solanaLocalRpc } from '@solana/kit-plugin-rpc';import { signer } from '@solana/kit-plugin-signer';import { findPlanPda, subscriptionsProgram } from '@solana/subscriptions';const merchantClient = createClient().use(signer(merchantSigner)).use(solanaLocalRpc({ rpcUrl: 'http://127.0.0.1:8899' })).use(subscriptionsProgram());const planId = 1n;const tokenMint = address('TOKEN_MINT_ADDRESS_HERE');const amount = 5_000_000n;const periodHours = 720n;const metadataUri = 'https://example.com/plan.json';const destinations = [merchantSigner.address];const pullers = [address('PULLER_WALLET_ADDRESS_HERE')];await merchantClient.subscriptions.instructions.createPlan({planId,mint: tokenMint,amount,periodHours,endTs: 0n,destinations,pullers,metadataUri,}).sendTransaction();const [planPda] = await findPlanPda({owner: merchantSigner.address,planId,});
Cập Nhật Gói
Người bán có thể cập nhật các trường có thể thay đổi của gói sau khi tạo. Những người đăng ký hiện tại vẫn giữ nguyên các điều khoản họ đã chấp nhận, trong khi người đăng ký mới sẽ chấp nhận các điều khoản hiện tại của gói.
import { PlanStatus } from '@solana/subscriptions';const updatedMetadataUri = 'https://example.com/updated-plan.json';const updatedPullers = [address('NEW_PULLER_WALLET_ADDRESS_HERE')];await merchantClient.subscriptions.instructions.updatePlan({owner: merchantSigner,planPda,status: PlanStatus.Active,endTs: 0n,pullers: updatedPullers,metadataUri: updatedMetadataUri,}).sendTransaction();
Đăng ký
Người đăng ký chấp nhận các điều khoản của gói hiện tại. PDA đăng ký được tạo ra từ PDA gói và địa chỉ người đăng ký.
import { 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,findSubscriptionAuthorityPda,findSubscriptionDelegationPda,subscriptionsProgram,} from '@solana/subscriptions';const subscriberClient = createClient().use(signer(subscriberSigner)).use(solanaLocalRpc({ rpcUrl: 'http://127.0.0.1:8899' })).use(subscriptionsProgram());const [subscriberAta] = await findAssociatedTokenPda({mint: tokenMint,owner: subscriberSigner.address,tokenProgram: TOKEN_PROGRAM_ADDRESS,});const [subscriptionAuthorityPda] = await findSubscriptionAuthorityPda({user: subscriberSigner.address,tokenMint,});const subscriptionAuthority = await fetchMaybeSubscriptionAuthority(subscriberClient.rpc,subscriptionAuthorityPda,);if (!subscriptionAuthority.exists) {await subscriberClient.subscriptions.instructions.initSubscriptionAuthority({tokenMint,tokenProgram: TOKEN_PROGRAM_ADDRESS,userAta: subscriberAta,}).sendTransaction();}await subscriberClient.subscriptions.instructions.subscribe({merchant: merchantSigner.address,planId,tokenMint,}).sendTransaction();const [subscriptionPda] = await findSubscriptionDelegationPda({planPda,subscriber: subscriberSigner.address,});
Thu tiền thanh toán
Người bán hoặc người rút tiền được phép ký xác nhận việc thu tiền. Khi gói sử
dụng danh sách đích cho phép, chủ sở hữu của token account nhận phải được liệt
kê trong destinations.
const receiverAta = address('MERCHANT_TOKEN_ACCOUNT_ADDRESS_HERE');await merchantClient.subscriptions.instructions.transferSubscription({caller: merchantOrPullerSigner,delegator: subscriberSigner.address,tokenMint,subscriptionPda,planPda,amount: 200_000n,receiverAta,tokenProgram: TOKEN_PROGRAM_ADDRESS,}).sendTransaction();
Hủy và Thu hồi
Hủy bỏ đánh dấu đăng ký là kết thúc. Thu hồi đóng PDA đăng ký sau khi thời hạn hủy đã trôi qua. Người đăng ký ký cả hai giao dịch.
await subscriberClient.subscriptions.instructions.cancelSubscription({subscriber: subscriberSigner,planPda,subscriptionPda,}).sendTransaction();// Run this after the cancelled subscription's expiresAtTs has elapsed.await subscriberClient.subscriptions.instructions.revokeSubscription({authority: subscriberSigner,planPda,subscriptionPda,}).sendTransaction();
Ghi chú
amountđược tính theo đơn vị cơ bản. Đối với token có 6 chữ số thập phân,5_000_000có nghĩa là5token.- TypeScript SDK tự động lấy các điều khoản gói hiện tại trong quá trình
subscribekhi bạn không cung cấp chúng. - Rust
SubscribeBuildercần các điều khoản gói dự kiến. Hãy lấy và giải mã tài khoản gói trước, sau đó truyền các trường đó quaSubscribeData. - Chỉ người bán hoặc ví được liệt kê trong
pullersmới có thể thu thanh toán. - Người đăng ký ký các giao dịch thiết lập, hủy và thu hồi. Người bán hoặc bên được phê duyệt ký các giao dịch thu tiền.
Is this page helpful?