결제구독

반복 위임

반복 위임을 사용하면 사용자가 다른 지갑이나 서비스가 매 기간마다 재설정되는 한도까지 인출할 수 있도록 승인할 수 있습니다.

이 가이드는 구성 요소들을 명확하게 유지합니다. 먼저 계정을 파생하고, 필요한 경우 구독 권한을 초기화한 다음, 반복 위임을 생성하고, 해당 위임 PDA를 전송에 사용합니다.

설치

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

위임 생성

설정은 네 단계로 구성됩니다:

  1. 사용자 서명자와 구독 플러그인으로 클라이언트를 생성합니다.
  2. 사용자의 토큰 계정, 구독 권한 PDA, 반복 위임 PDA를 파생합니다.
  3. 구독 권한이 아직 존재하지 않는 경우 초기화합니다.
  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_0001 토큰을 의미합니다.
  • 프로그램은 현재 기간의 잔여 허용량을 초과하는 전송을 거부합니다.
  • 다음 기간이 시작되면 인출된 금액이 초기화됩니다.
  • expiryTs 는 강제 종료 시점입니다. 이 시점이 지나면 전송이 실패하고 스폰서는 rent를 회수할 수 있습니다. 지출 시간 유예 기간은 없습니다.
  • startTs0 로 설정하면 고정된 시간이 아닌 트랜잭션이 체인에 기록되는 시점에 위임이 시작됩니다. 이렇게 하면 사용자가 서명하고 온보딩할 수 있는 시간이 늘어납니다. 이 방식을 사용할 경우, expiryTs 는 반드시 0이 아닌 값이어야 합니다 — 착륙 시 시작되는 위임은 만료되지 않도록 설정할 수 없습니다.
  • 사용자는 설정 및 취소 트랜잭션에 서명합니다. 피위임자는 전송에 서명합니다.

Is this page helpful?

목차

페이지 편집