PagosSuscripciones

Delegación Recurrente

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:

  1. Crear un cliente con el firmante del usuario y el plugin de suscripciones.
  2. Derivar la cuenta de tokens del usuario, el PDA de la Autoridad de Suscripción y el PDA de delegación recurrente.
  3. Inicializar la Autoridad de Suscripción si aún no existe.
  4. 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

  • amountPerPeriod está en unidades base. Para un token de 6 decimales, 1_000_000 significa 1 token.
  • El programa rechaza transferencias que excedan la asignación restante del período actual.
  • Una vez que comienza el siguiente período, el monto retirado se reinicia.
  • El usuario firma las transacciones de configuración y revocación. El delegatario firma las transferencias.

Is this page helpful?

Tabla de Contenidos

Editar Página