PagosSuscripciones
Una delegación recurrente permite que un usuario autorice a otra billetera o servicio a retirar hasta un límite que se reinicia en cada período.
Esta guía mantiene visibles las partes móviles. Primero derivas las cuentas, inicializas la Autoridad de Suscripción si es necesario, creas la delegación recurrente y luego usas ese PDA de delegación para las transferencias.
Instalación
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
Crear la Delegación
La configuración tiene cuatro partes:
- Crear un cliente con el firmante del usuario y el plugin de suscripciones.
- Derivar la cuenta de tokens del usuario, el PDA de la Autoridad de Suscripción y el PDA de delegación recurrente.
- Inicializar la Autoridad de Suscripción si aún no existe.
- Crear la delegación recurrente con el monto del período, la duración del período, la hora de inicio y la expiración.
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,findRecurringDelegationPda,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 now = BigInt(Math.floor(Date.now() / 1000));const nonce = 0n;const amountPerPeriod = 1_000_000n;const periodLengthS = 86_400n;const startTs = now;const expiryTs = now + periodLengthS * 30n;const [userAta] = await findAssociatedTokenPda({mint: tokenMint,owner: userSigner.address,tokenProgram: TOKEN_PROGRAM_ADDRESS,});const [subscriptionAuthorityPda] = await findSubscriptionAuthorityPda({user: userSigner.address,tokenMint,});const [delegationPda] = await findRecurringDelegationPda({subscriptionAuthority: subscriptionAuthorityPda,delegator: userSigner.address,delegatee,nonce,});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.createRecurringDelegation({tokenMint,delegatee,nonce,amountPerPeriod,periodLengthS,startTs,expiryTs,}).sendTransaction();
Transferir desde la Delegación
El delegado firma cada transferencia. El programa verifica el período actual y rechaza las transferencias que excedan el límite restante del período.
const receiverAta = address('RECEIVER_TOKEN_ACCOUNT_ADDRESS_HERE');await client.subscriptions.instructions.transferRecurring({delegatee: delegateeSigner,delegator: userSigner.address,delegatorAta: userAta,tokenMint,delegationPda,amount: 100_000n,receiverAta,tokenProgram: TOKEN_PROGRAM_ADDRESS,}).sendTransaction();
Revocar la Delegación
El delegador puede revocar la delegación recurrente en cualquier momento. Revocar cierra la PDA de delegación y devuelve su alquiler al firmante.
await client.subscriptions.instructions.revokeDelegation({authority: userSigner,delegationAccount: delegationPda,}).sendTransaction();
Notas
amountPerPeriodestá en unidades base. Para un token de 6 decimales,1_000_000significa1token.- El programa rechaza las transferencias que superan la asignación restante del período actual.
- Una vez que comienza el siguiente período, el monto extraído se reinicia.
expiryTses un límite absoluto: una vez que se supera, las transferencias fallan y el patrocinador puede recuperar rent. No hay período de gracia de gasto.- Establece
startTsen0para iniciar la delegación cuando la transacción se confirme en la cadena en lugar de en un momento fijo. Esto amplía la ventana para que el usuario firme y se incorpore. Al hacer esto,expiryTsdebe ser distinto de cero: una delegación de inicio en confirmación tampoco puede configurarse para que nunca expire. - El usuario firma las transacciones de configuración y revocación. El delegado firma las transferencias.
Is this page helpful?