المدفوعاتالاشتراكات

التفويض الثابت

يتيح التفويض الثابت للمستخدم الموافقة على محفظة أو خدمة أخرى لسحب مبلغ محدد من الرموز. كل عملية تحويل ناجحة تقلل من الرصيد المتبقي المسموح به. استخدم expiryTs = 0 لعدم وجود تاريخ انتهاء صلاحية.

يحافظ هذا الدليل على وضوح سير العمل. يستخدم كل مقتطف وظائف SDK مباشرة حتى تتمكن من رؤية أي حساب تم اشتقاقه، وأي تعليمات تم إرسالها، وأي موقّع يدفع أو يصرح بكل خطوة.

التثبيت

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

إنشاء التفويض

يتكون الإعداد من أربعة أجزاء:

  1. إنشاء عميل باستخدام الموقّع للمستخدم وإضافة الاشتراكات.
  2. اشتقاق token account الخاص بالمستخدم ونقطة وصول سلطة الاشتراك (Subscription Authority PDA).
  3. تهيئة سلطة الاشتراك إذا لم تكن موجودة بعد.
  4. إنشاء التفويض الثابت واشتقاق نقطة الوصول الخاصة به (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 إلى نفس نقطة وصول التفويض (delegation PDA)، وtoken account الخاص بالمستخدم، وtoken account الخاص بالمستقبِل.

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 الخاص بالتفويض وإرجاع الإيجار الخاص به إلى الموقّع.

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

ملاحظات

  • يجب أن يكون token account الخاص بالمستخدم موجودًا قبل التهيئة.
  • المبالغ بالوحدات الأساسية. بالنسبة لرمز مزود بـ 6 منازل عشرية، يعني 1_000_000 رمزًا واحدًا بقيمة 1.
  • شغّل initSubscriptionAuthority فقط عندما لا يكون حساب Subscription Authority موجودًا مسبقًا.
  • expiryTs هو حدٌّ صارم: بمجرد انقضائه، تفشل عمليات التحويل ويمكن للجهة الراعية استرداد rent. ولا توجد فترة سماح لوقت الإنفاق.
  • يوقّع المستخدم على معاملات الإعداد والإلغاء. ويوقّع المفوَّض إليه على معاملات التحويل.

Is this page helpful?

جدول المحتويات

تعديل الصفحة