Ένα πρόγραμμα συνδρομής επιτρέπει σε έναν έμπορο να δημοσιεύσει όρους χρέωσης που μπορούν να αποδεχτούν οι χρήστες. Αφού ένας χρήστης εγγραφεί, ο έμπορος ή ένας εγκεκριμένος συλλέκτης μπορεί να εισπράξει έως και το ποσό του προγράμματος σε κάθε περίοδο χρέωσης.
Αυτός ο οδηγός παρουσιάζει την πλήρη ροή ως δομικά στοιχεία. Ο έμπορος δημιουργεί ένα πρόγραμμα, ο συνδρομητής το αποδέχεται και ο έμπορος ή ο συλλέκτης εισπράττει πληρωμές από το αποτελούμενο PDA συνδρομής.
Εγκατάσταση
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
Δημιουργία Προγράμματος
Ο έμπορος κατέχει το πρόγραμμα. Το PDA του προγράμματος προκύπτει από τη
διεύθυνση του εμπόρου και το 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,});
Ενημέρωση Προγράμματος
Ο έμπορος μπορεί να ενημερώσει τα μεταβλητά πεδία του προγράμματος μετά τη δημιουργία. Οι υπάρχοντες συνδρομητές διατηρούν τους όρους που αποδέχτηκαν, ενώ οι νέοι συνδρομητές αποδέχονται τους τρέχοντες όρους του προγράμματος.
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();
Εγγραφή
Ο συνδρομητής αποδέχεται τους τρέχοντες όρους του πλάνου. Το PDA της συνδρομής προκύπτει από το PDA του πλάνου και τη διεύθυνση του συνδρομητή.
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,});
Είσπραξη Πληρωμής
Ο έμπορος ή ένας εξουσιοδοτημένος χρήστης υπογράφει την είσπραξη. Όταν το πλάνο
χρησιμοποιεί λίστα επιτρεπόμενων προορισμών, ο κάτοχος του λογαριασμού token
παραλήπτη πρέπει να περιλαμβάνεται στο 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();
Ακύρωση και Ανάκληση
Η ακύρωση σηματοδοτεί το τέλος της συνδρομής. Η ανάκληση κλείνει το PDA της συνδρομής αφού παρέλθει η προθεσμία ακύρωσης. Ο συνδρομητής υπογράφει και τις δύο συναλλαγές.
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();
Σημειώσεις
- Το
amountείναι σε βασικές μονάδες. Για ένα token με 6 δεκαδικά, το5_000_000σημαίνει5tokens. - Το TypeScript SDK ανακτά τους όρους του πακέτου σε πραγματικό χρόνο κατά τη
διάρκεια του
subscribeόταν τους παραλείψετε. - Το Rust
SubscribeBuilderχρειάζεται τους αναμενόμενους όρους του πακέτου. Πρώτα ανακτήστε και αποκωδικοποιήστε τον λογαριασμό του πακέτου και στη συνέχεια περάστε αυτά τα πεδία μέσω τουSubscribeData. - Μόνο ο έμπορος ή ένα πορτοφόλι που περιλαμβάνεται στο
pullersμπορεί να εισπράξει πληρωμές. - Ο συνδρομητής υπογράφει τις συναλλαγές ρύθμισης, ακύρωσης και ανάκλησης. Ο έμπορος ή ο εγκεκριμένος εισπράκτορας υπογράφει τις συναλλαγές είσπραξης.
Is this page helpful?