PaiementsPaiements avancés

Autorisations de dépense

Les programmes de jetons de Solana prennent en charge la délégation — accorder à un autre compte la permission de transférer des jetons depuis votre compte de jetons jusqu'à une limite spécifiée. Cela permet des cas d'usage tels que les paiements automatisés, les services de séquestre et le traitement de paiements par des tiers sans renoncer à la garde de vos fonds.

Comment fonctionne la délégation

Lorsque vous approuvez un délégué, vous autorisez un compte spécifique à transférer des jetons en votre nom :

  • Le propriétaire conserve la garde : vous possédez toujours les jetons et pouvez les transférer ou révoquer à tout moment
  • Dépense plafonnée : le délégué ne peut transférer que jusqu'au montant approuvé
  • Un seul délégué par compte : chaque compte de jetons ne peut avoir qu'un seul délégué actif
  • Une nouvelle approbation remplace l'ancienne : approuver un nouveau délégué révoque automatiquement le précédent

La délégation est non-custodiale. Le délégué peut dépenser des jetons jusqu'à la limite, mais ne peut pas accéder au compte ou le vider au-delà du montant approuvé. Le propriétaire peut révoquer à tout moment.

Cas d'usage professionnels

Cas d'usageComment la délégation aide
Processeurs de paiementLe commerçant accorde au processeur la permission de régler les transactions
Paie automatiséeLa trésorerie approuve le service de paie pour verser les salaires
Services de séquestreL'acheteur délègue à l'agent de séquestre pour une libération conditionnelle
Plateformes de tradingL'utilisateur approuve la plateforme d'échange pour exécuter des trades en son nom
Émission de cartesL'utilisateur approuve l'émetteur de carte pour débiter les achats sur son compte de jetons

Approuver un délégué

Accorder à un autre compte la permission de dépenser des jetons depuis votre compte :

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

Paramètres :

  • source : le token account accordant la permission
  • delegate : le compte qui aura la permission de dépenser
  • owner : propriétaire actuel du token account (doit signer la transaction)
  • amount : nombre maximum de jetons que le délégué peut transférer
  • decimals : décimales du jeton pour validation (évite les erreurs de décimales)

Démo

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.

Révoquer un délégué

Supprimer toutes les permissions de dépense du délégué actuel :

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

La révocation supprime toutes les permissions du délégué — il n'y a pas de révocation partielle. Si vous devez réduire la limite, approuvez le même délégué avec un montant inférieur.

Démo

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.

Transférer en tant que délégué

Lorsque vous agissez en tant que délégué, utilisez un transfert standard mais signez avec la paire de clés du délégué au lieu du propriétaire :

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

Le transfert réussira si :

  • Le compte source dispose d'un solde suffisant
  • Le délégué signe la transaction

Chaque transfert réduit l'allocation restante. Lorsque l'allocation atteint zéro, le délégué ne peut plus transférer de jetons.

Démo

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.

Vérifier le statut de délégation

Interroger un token account pour voir son délégué actuel et l'allocation restante :

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

Démo

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.

Considérations de sécurité

Pour les propriétaires de comptes :

  • N'approuvez que des délégués de confiance
  • Définissez la limite de dépense minimale nécessaire
  • Révoquez les délégations lorsqu'elles ne sont plus nécessaires
  • Surveillez vos comptes pour détecter les transferts inattendus

Pour les fournisseurs de services (délégués) :

  • Communiquez clairement la limite de dépense demandée aux utilisateurs
  • Implémentez une gestion appropriée des clés pour votre compte délégué
  • Suivez la consommation de l'allocation pour demander une nouvelle approbation avant l'épuisement des limites

Délégation vs. garde

AspectDélégationGarde complète
Propriété des tokensL'utilisateur conserveL'utilisateur transfère au dépositaire
Contrôle des dépensesPlafonné au montant approuvéAccès complet aux fonds transférés
RévocationInstantanée, par le propriétaireNécessite la coopération du dépositaire
Exposition au risqueLimitée au montant approuvéSolde entier
Confiance requiseLimitéeÉlevée

La délégation offre un juste milieu — permettant les paiements automatisés tout en limitant l'exposition au risque au montant approuvé.

Ressources associées

RessourceDescription
Approve DelegateComment accorder à un autre compte la permission de dépenser depuis votre token account.
Revoke DelegateComment supprimer un délégué existant et révoquer ses permissions de dépense.
Transfer TokenComment transférer des tokens entre token accounts.

Is this page helpful?

Table des matières

Modifier la page

Géré par

© 2026 Fondation Solana.
Tous droits réservés.
Restez connecté