ПлатежиПодписки

Периодическое делегирование

Периодическое делегирование позволяет пользователю одобрить другому кошельку или сервису снятие средств до определённого лимита, который сбрасывается каждый период.

Это руководство демонстрирует все составляющие процесса. Сначала вы создаёте аккаунты, затем инициализируете Subscription Authority при необходимости, создаёте периодическое делегирование, после чего используете этот PDA делегирования для переводов.

Установка

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

Создание делегирования

Настройка состоит из четырёх частей:

  1. Создание клиента с подписантом пользователя и плагином подписок.
  2. Получение token account пользователя, PDA Subscription Authority и PDA периодического делегирования.
  3. Инициализация Subscription Authority, если она ещё не существует.
  4. Создание периодического делегирования с указанием суммы периода, длительности периода, времени начала и срока действия.
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();

Перевод средств из делегирования

Делегат подписывает каждый перевод. Программа проверяет текущий период и отклоняет переводы, которые превысят оставшийся лимит периода.

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();

Отзыв делегирования

Делегирующий может отозвать повторяющееся делегирование в любое время. Отзыв закрывает PDA делегирования и возвращает его rent подписанту.

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

Примечания

  • amountPerPeriod указывается в базовых единицах. Для токена с 6 десятичными знаками 1_000_000 означает 1 токен.
  • Программа отклоняет переводы, которые превышают оставшийся лимит текущего периода.
  • После начала следующего периода снятая сумма сбрасывается.
  • Пользователь подписывает транзакции настройки и отзыва. Уполномоченный подписывает переводы.

Is this page helpful?

Содержание

Редактировать страницу