BetalingenGeavanceerde betalingen

Bestedingsmachtigingen

Solana's Token Programs ondersteunen delegatie—het verlenen van toestemming aan een ander account om tokens over te maken vanaf jouw token account tot een gespecificeerd limiet. Dit maakt gebruikssituaties mogelijk zoals geautomatiseerde betalingen, escrowdiensten en betalingsverwerking door derden zonder dat je de controle over je middelen opgeeft.

Hoe delegatie werkt

Wanneer je een gemachtigde goedkeurt, autoriseer je een specifiek account om tokens namens jou over te maken:

  • Eigenaar behoudt controle: Je bent nog steeds eigenaar van de tokens en kunt deze op elk moment overmaken of intrekken
  • Beperkte uitgaven: De gemachtigde kan alleen tot het goedgekeurde bedrag overmaken
  • Eén gemachtigde per account: Elk token account kan slechts één actieve gemachtigde hebben
  • Nieuwe goedkeuring vervangt oude: Het goedkeuren van een nieuwe gemachtigde trekt automatisch de vorige in

Delegatie is niet-custodiaal. De gemachtigde kan tokens uitgeven tot het limiet, maar kan het account niet toegang krijgen of leeghalen boven het goedgekeurde bedrag. De eigenaar kan op elk moment intrekken.

Zakelijke gebruikssituaties

GebruikssituatieHoe delegatie helpt
BetalingsverwerkersHandelaar verleent verwerker toestemming om transacties af te wikkelen
Geautomatiseerde salarisadministratieSchatkist keurt salarisadministratiedienst goed om salarissen uit te betalen
EscrowdienstenKoper delegeert aan escrowagent voor voorwaardelijke vrijgave
HandelsplatformsGebruiker keurt exchange goed om namens hen te handelen
KaartuitgifteGebruiker keurt kaartuitgever goed om aankopen af te schrijven van hun token account

Een gemachtigde goedkeuren

Geef een ander account toestemming om tokens van je account uit te geven:

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

Parameters:

  • source: Het token account dat toestemming verleent
  • delegate: Het account dat bestedingsrechten krijgt
  • owner: Huidige eigenaar van het token account (moet de transactie ondertekenen)
  • amount: Maximum aantal tokens dat de gemachtigde kan overmaken
  • decimals: Token decimalen voor validatie (voorkomt decimaalfouten)

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.

Een gemachtigde intrekken

Verwijder alle bestedingsrechten van de huidige gemachtigde:

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

Intrekken verwijdert alle machtigingen van de gemachtigde—er is geen gedeeltelijke intrekking. Als je de limiet wilt verlagen, keur dan dezelfde gemachtigde goed met een lager bedrag.

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.

Overdragen als gemachtigde

Wanneer je optreedt als gemachtigde, gebruik je een standaard overdracht maar onderteken je met het keypair van de gemachtigde in plaats van de eigenaar:

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

De overdracht slaagt als:

  • Het bronaccount voldoende saldo heeft
  • De gemachtigde de transactie ondertekent

Elke overdracht vermindert de resterende toelage. Wanneer de toelage nul bereikt, kan de gemachtigde geen tokens meer overdragen.

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.

Machtigingsstatus controleren

Vraag een token account op om de huidige gemachtigde en resterende toestemming te zien:

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.

Beveiligingsoverwegingen

Voor accounteigenaren:

  • Keur alleen vertrouwde gemachtigden goed
  • Stel de minimaal noodzakelijke bestedingslimiet in
  • Herroep machtigingen wanneer ze niet langer nodig zijn
  • Controleer je accounts op onverwachte overboekingen

Voor dienstverleners (gemachtigden):

  • Communiceer de gevraagde bestedingslimiet duidelijk naar gebruikers
  • Implementeer correct sleutelbeheer voor je gemachtigde account
  • Volg het verbruik van de toestemming om hernieuwde goedkeuring aan te vragen voordat limieten zijn uitgeput

Machtiging vs. bewaring

AspectMachtigingVolledige bewaring
Token eigendomGebruiker behoudtGebruiker draagt over aan bewaarder
BestedingscontroleBeperkt tot goedgekeurd bedragVolledige toegang tot overgeboekte middelen
HerroepingDirect, door eigenaarVereist medewerking bewaarder
RisicoblootstellingBeperkt tot goedgekeurd bedragVolledig saldo
Vereist vertrouwenBeperktHoog

Machtiging biedt een middenweg—het maakt geautomatiseerde betalingen mogelijk terwijl de risicoblootstelling beperkt blijft tot het goedgekeurde bedrag.

Gerelateerde bronnen

BronBeschrijving
Approve DelegateHoe je een ander account toestemming geeft om te besteden vanaf jouw token account.
Revoke DelegateHoe je een bestaande gemachtigde verwijdert en diens bestedingsrechten intrekt.
Transfer TokenHoe je tokens overbrengt tussen token accounts.

Is this page helpful?

Inhoudsopgave

Pagina Bewerken

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden