결제구독
반복 위임을 사용하면 사용자가 다른 지갑이나 서비스가 매 기간마다 재설정되는 한도까지 인출할 수 있도록 승인할 수 있습니다.
이 가이드는 구성 요소들을 명확하게 유지합니다. 먼저 계정을 파생하고, 필요한 경우 구독 권한을 초기화한 다음, 반복 위임을 생성하고, 해당 위임 PDA를 전송에 사용합니다.
설치
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
위임 생성
설정은 네 단계로 구성됩니다:
- 사용자 서명자와 구독 플러그인으로 클라이언트를 생성합니다.
- 사용자의 토큰 계정, 구독 권한 PDA, 반복 위임 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,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토큰을 의미합니다.- 프로그램은 현재 기간의 잔여 허용량을 초과하는 전송을 거부합니다.
- 다음 기간이 시작되면 인출된 금액이 초기화됩니다.
expiryTs는 강제 종료 시점입니다. 이 시점이 지나면 전송이 실패하고 스폰서는 rent를 회수할 수 있습니다. 지출 시간 유예 기간은 없습니다.startTs를0로 설정하면 고정된 시간이 아닌 트랜잭션이 체인에 기록되는 시점에 위임이 시작됩니다. 이렇게 하면 사용자가 서명하고 온보딩할 수 있는 시간이 늘어납니다. 이 방식을 사용할 경우,expiryTs는 반드시 0이 아닌 값이어야 합니다 — 착륙 시 시작되는 위임은 만료되지 않도록 설정할 수 없습니다.- 사용자는 설정 및 취소 트랜잭션에 서명합니다. 피위임자는 전송에 서명합니다.
Is this page helpful?