PłatnościZaawansowane płatności

Uprawnienia do wydawania środków

Programy Tokenów Solana obsługują delegowanie — czyli przyznawanie innemu kontu uprawnienia do transferu tokenów z Twojego token account do określonego limitu. Pozwala to na realizację takich scenariuszy jak automatyczne płatności, usługi escrow czy przetwarzanie płatności przez strony trzecie, bez utraty kontroli nad własnymi środkami.

Jak działa delegowanie

Gdy zatwierdzasz delegata, upoważniasz konkretne konto do transferowania tokenów w Twoim imieniu:

  • Właściciel zachowuje kontrolę: Nadal jesteś właścicielem tokenów i możesz w każdej chwili dokonać transferu lub odwołać uprawnienia
  • Limit wydatków: Delegat może przelać tylko zatwierdzoną kwotę
  • Jeden delegat na konto: Każdy token account może mieć tylko jednego aktywnego delegata
  • Nowe zatwierdzenie zastępuje stare: Zatwierdzenie nowego delegata automatycznie cofa poprzednie uprawnienie

Delegowanie jest niepowiernicze. Delegat może wydawać tokeny tylko do ustalonego limitu, ale nie ma dostępu do środków poza zatwierdzoną kwotą. Właściciel może w każdej chwili cofnąć uprawnienia.

Przykłady zastosowań biznesowych

ZastosowanieJak pomaga delegowanie
Procesory płatnościSprzedawca przyznaje procesorowi uprawnienia do rozliczania transakcji
Automatyczna wypłata pensjiSkarbnik zatwierdza usługę kadrową do wypłaty wynagrodzeń
Usługi escrowKupujący deleguje agentowi escrow warunkowe zwolnienie środków
Platformy tradingoweUżytkownik zatwierdza giełdę do realizacji transakcji w jego imieniu
Wydawanie kartUżytkownik zatwierdza wystawcę karty do obciążania jego token account

Zatwierdzanie delegata

Przyznaj innemu kontu uprawnienia do wydawania tokenów z Twojego konta:

import { getApproveCheckedInstruction } from "@solana-program/token";
// Approve delegate to spend up to 1,000 USDC (6 decimals)
const approveInstruction = getApproveCheckedInstruction({
source: tokenAccountAddress, // Your token account
mint: usdcMintAddress, // USDC mint
delegate: delegateAddress, // Account receiving permission
owner: ownerKeypair, // You (must sign)
amount: 1_000_000_000n, // 1,000 USDC in base units
decimals: 6
});

Parametry:

  • source: token account przyznający uprawnienia
  • delegate: konto, które otrzyma uprawnienia do wydawania
  • owner: obecny właściciel token account (musi podpisać transakcję)
  • amount: maksymalna liczba tokenów, jaką delegat może przelać
  • decimals: liczba miejsc po przecinku tokena do walidacji (zapobiega błędom dziesiętnym)

Demo

Approve Delegate
// Generate keypairs for sender and delegate
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
// Demo Setup: Create client, mint account, token account, and fund with initial tokens
const { client, mint, senderAta } = await demoSetup(sender);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
// =============================================================================
// Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const signature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Approve Delegate ===");
console.log("Transaction Signature:", signature);
// Fetch token account data to show delegate is set
const tokenData = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenData.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

Odwołanie delegata

Usuń wszystkie uprawnienia do wydawania środków obecnemu delegatowi:

import { getRevokeInstruction } from "@solana-program/token";
const revokeInstruction = getRevokeInstruction({
source: tokenAccountAddress, // Your token account
owner: ownerKeypair // You (must sign)
});

Odwołanie usuwa wszystkie uprawnienia delegata — nie ma częściowego odwołania. Jeśli chcesz zmniejszyć limit, zatwierdź tego samego delegata z niższą kwotą.

Demo

Revoke Delegate
// Generate keypairs for sender and delegate
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
// Demo Setup: Create client, mint account, token account, and fund with initial tokens
const { client, mint, senderAta } = await demoSetup(sender);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
// =============================================================================
// Transaction 1: Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const approveSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Transaction 1: Approve Delegate ===");
console.log("Transaction Signature:", approveSignature);
// Fetch token account data to show delegate is set
const tokenDataAfterApprove = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenDataAfterApprove.data);
// =============================================================================
// Transaction 2: Revoke Delegate
// =============================================================================
// Create instruction to revoke delegate
const revokeInstruction = getRevokeInstruction({
source: senderAta,
owner: sender
});
// Send revoke transaction
const revokeSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [revokeInstruction]
});
console.log("\n=== Transaction 2: Revoke Delegate ===");
console.log("Transaction Signature:", revokeSignature);
// Fetch token account data to show delegate is revoked
const tokenDataAfterRevoke = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenDataAfterRevoke.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

Przelew jako delegat

Działając jako delegat, użyj standardowego przelewu, ale podpisz go keypair delegata zamiast właściciela:

Transfer as Delegate
import { getTransferCheckedInstruction } from "@solana-program/token";
const transferInstruction = getTransferCheckedInstruction({
source: ownerTokenAccount, // The account you have permission to spend from
mint: usdcMintAddress,
destination: recipientTokenAccount,
authority: delegateKeypair, // You (the delegate) sign, not the owner
amount: 100_000_000n, // 100 USDC
decimals: 6
});

Przelew zakończy się powodzeniem, jeśli:

  • Konto źródłowe ma wystarczające saldo
  • Delegat podpisze transakcję

Każdy przelew zmniejsza pozostały limit. Gdy limit osiągnie zero, delegat nie może już wykonywać przelewów tokenów.

Demo

Transfer as Delegate
// Generate keypairs for sender, delegate, and recipient
const sender = (await generateKeypair()).signer;
const delegate = (await generateKeypair()).signer;
const recipient = (await generateKeypair()).signer;
console.log("Sender Address:", sender.address);
console.log("Delegate Address:", delegate.address);
console.log("Recipient Address:", recipient.address);
// Demo Setup: Create client, mint account, token accounts, and fund with initial tokens
const { client, mint, senderAta, recipientAta } = await demoSetup(
sender,
delegate,
recipient
);
console.log("\nMint Address:", mint.address);
console.log("Sender ATA:", senderAta);
console.log("Recipient ATA:", recipientAta);
// =============================================================================
// Transaction 1: Approve Delegate
// =============================================================================
// Create instruction to approve delegate
const approveInstruction = getApproveCheckedInstruction({
source: senderAta,
mint: mint.address,
delegate: delegate.address,
owner: sender,
amount: 1_000_000n, // 1.0 tokens with 6 decimals
decimals: 6
});
// Send approve transaction
const approveSignature = await client.transaction.prepareAndSend({
authority: sender,
instructions: [approveInstruction]
});
console.log("\n=== Transaction 1: Approve Delegate ===");
console.log("Delegate Address:", delegate.address);
console.log("Transaction Signature:", approveSignature);
// =============================================================================
// Fetch Token Account Data to Demonstrate Delegate is Set
// =============================================================================
const tokenAccountData = await fetchToken(client.runtime.rpc, senderAta);
console.log("\nSender Token Account Data:", tokenAccountData.data);
// =============================================================================
// Transaction 2: Transfer Using Delegate
// =============================================================================
// Create instruction to transfer tokens using delegate
// Note: delegate is the authority here, not the owner
const transferInstruction = getTransferCheckedInstruction({
source: senderAta,
mint: mint.address,
destination: recipientAta,
authority: delegate, // Delegate signs this transaction
amount: 500_000n, // 0.5 tokens with 6 decimals
decimals: 6
});
// Send transfer transaction
// Delegate pays for the transaction and authorizes the transfer (sender not needed)
const transferSignature = await client.transaction.prepareAndSend({
authority: delegate, // Delegate pays fee and signs
instructions: [transferInstruction]
});
// =============================================================================
// Fetch Final Token Account Balances
// =============================================================================
const finalSenderToken = await fetchToken(client.runtime.rpc, senderAta);
const finalRecipientToken = await fetchToken(client.runtime.rpc, recipientAta);
console.log("\n=== Transaction 2: Transfer Using Delegate ===");
console.log("Transaction Signature:", transferSignature);
console.log("\nSender Token Account Data:", finalSenderToken.data);
console.log("\nRecipient Token Account Data:", finalRecipientToken.data);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

Sprawdzanie statusu delegacji

Sprawdź token account, aby zobaczyć obecnego delegata i pozostały limit:

import { fetchToken } from "@solana-program/token";
const tokenAccount = await fetchToken(rpc, tokenAccountAddress);
if (tokenAccount.data.delegate) {
console.log("Delegate:", tokenAccount.data.delegate);
console.log("Remaining allowance:", tokenAccount.data.delegatedAmount);
} else {
console.log("No delegate set");
}

Demo

Check Delegation Status
// Demo Setup: Create client, mint, two token accounts (one with delegate, one without)
const { client, ataWithDelegate, ataWithoutDelegate } = await demoSetup();
// =============================================================================
// Fetch Token Accounts
// =============================================================================
// Fetch token account with delegate
const tokenWithDelegate = await fetchToken(client.runtime.rpc, ataWithDelegate);
console.log("Token Account with Delegate:", tokenWithDelegate);
// Fetch token account without delegate
const tokenWithoutDelegate = await fetchToken(
client.runtime.rpc,
ataWithoutDelegate
);
console.log("\nToken Account without Delegate:", tokenWithoutDelegate);
// =============================================================================
// Demo Setup Helper Function
// =============================================================================
Console
Click to execute the code.

Wskazówki dotyczące bezpieczeństwa

Dla właścicieli kont:

  • Zatwierdzaj tylko zaufanych delegatów
  • Ustaw minimalny niezbędny limit wydatków
  • Cofnij delegacje, gdy nie są już potrzebne
  • Monitoruj swoje konta pod kątem nieoczekiwanych transferów

Dla dostawców usług (delegatów):

  • Jasno komunikuj użytkownikom żądany limit wydatków
  • Wdrażaj odpowiednie zarządzanie kluczami dla swojego konta delegata
  • Monitoruj wykorzystanie limitu, aby poprosić o ponowną akceptację zanim limit się wyczerpie

Delegacja a powiernictwo

AspektDelegacjaPełne powiernictwo
Własność tokenaUżytkownik zachowujeUżytkownik przekazuje powiernikowi
Kontrola wydatkówOgraniczona do zatwierdzonej kwotyPełny dostęp do przekazanych środków
OdwołanieNatychmiastowe, przez właścicielaWymaga współpracy powiernika
Ekspozycja na ryzykoOgraniczona do zatwierdzonej kwotyCałe saldo
Wymagane zaufanieOgraniczoneWysokie

Delegacja to rozwiązanie pośrednie — umożliwia automatyczne płatności, jednocześnie ograniczając ekspozycję na ryzyko do zatwierdzonej kwoty.

Powiązane zasoby

ZasóbOpis
Zatwierdź delegataJak przyznać innemu kontu uprawnienia do wydawania z twojego token account.
Cofnij delegataJak usunąć istniejącego delegata i cofnąć jego uprawnienia do wydawania.
Przelej tokenJak przelać tokeny między token account.

Is this page helpful?

Spis treści

Edytuj stronę

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco