Passer au contenu principal

Documentation Index

Fetch the complete documentation index at: https://docs.blockradar.co/llms.txt

Use this file to discover all available pages before exploring further.

En bref
L’API Withdraw de Blockradar vous permet d’envoyer des actifs stablecoin depuis vos portefeuilles vers des adresses blockchain externes. Elle prend en charge les retraits individuels, les retraits par lot vers plusieurs destinataires, et fournit une estimation des frais avant l’exécution.
Interface Withdraw de Blockradar

Prérequis

Avant d’utiliser l’API Withdraw, assurez-vous d’avoir :
1

Clé API

Obtenez votre clé API depuis le Tableau de bord Blockradar. Accédez à Developers pour en générer une.
2

Portefeuille créé

Créez un portefeuille via l’API Create Wallet ou depuis le tableau de bord. Vous aurez besoin du walletId pour les opérations de retrait.
3

ID d'actif

Récupérez l’assetId du token que vous souhaitez retirer depuis Assets dans le tableau de bord ou via l’API Get Assets.
4

Solde suffisant

Assurez-vous que votre portefeuille dispose d’un solde suffisant de l’actif à retirer, ainsi que du token natif (ETH, BNB, MATIC, etc.) pour couvrir les frais de réseau.

Comment ça fonctionne

L’API Withdraw envoie des actifs stablecoin depuis votre portefeuille Blockradar vers n’importe quelle adresse blockchain externe :

Retrait individuel

Envoyez des actifs à une adresse destinataire en un seul appel API.

Retrait par lot

Envoyez des actifs à plusieurs destinataires en un seul appel API, réduisant la surcharge et simplifiant les paiements en masse.

Estimation des frais

Calculez les frais de réseau avant l’exécution pour garantir un solde suffisant et afficher les coûts aux utilisateurs.

Mode Sign-Only

Signez les transactions sans les diffuser pour des cas d’usage avancés tels que la signature hors ligne ou l’envoi personnalisé.

Master Wallet vs Child Address

L’API Withdraw est disponible à deux niveaux :

Master Wallet

Retirez directement depuis votre master wallet. Idéal pour les opérations de trésorerie et la gestion centralisée des fonds.

Child Address

Retirez depuis des child addresses individuelles. Parfait pour les opérations spécifiques aux utilisateurs et la gestion ségréguée des fonds.

Endpoints

OpérationMaster WalletChild Address
WithdrawPOST /v1/wallets/{walletId}/withdrawPOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw
Frais RéseauPOST /v1/wallets/{walletId}/withdraw/network-feePOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw/network-fee
Sign-OnlyPOST /v1/wallets/{walletId}/withdraw/signPOST /v1/wallets/{walletId}/addresses/{addressId}/withdraw/sign

Retrait individuel

Envoyez des actifs à une seule adresse destinataire.

Paramètres de la requête

ParamètreTypeRequisDescription
assetIdstringOui*L’UUID de l’actif à retirer. Requis si le tableau assets n’est pas fourni.
addressstringOui*L’adresse de destination. Requise si le tableau assets n’est pas fourni.
amountstringOui*Le montant du retrait. Doit être supérieur à 0. Requis si le tableau assets n’est pas fourni.
referencestringNonVotre identifiant interne de suivi pour le retrait.
notestringNonUn message court ou une remarque interne. Non visible on-chain.
metadataobjectNonPaires clé-valeur personnalisées pour des détails supplémentaires de la transaction.
Les paramètres marqués d’un * sont requis pour les retraits individuels mais ne sont pas nécessaires si vous utilisez le tableau assets pour les retraits par lot.

Exemple de retrait individuel

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-here",
    "address": "0xRecipientAddress...",
    "amount": "100",
    "reference": "payout-12345",
    "note": "Monthly payout",
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salary"
    }
  }'

Réponse du retrait individuel

{
  "message": "Withdrawal initiated successfully",
  "statusCode": 200,
  "data": {
    "id": "tx-uuid-123",
    "hash": "0xabc123...",
    "status": "PENDING",
    "amount": "100",
    "recipientAddress": "0xRecipientAddress...",
    "reference": "payout-12345",
    "note": "Monthly payout",
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salary"
    },
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

Retraits par lot

Envoyez des actifs à plusieurs destinataires en un seul appel API. Les retraits par lot sont exécutés séquentiellement, et chaque retrait est traité comme une transaction blockchain distincte.

Quand utiliser les retraits par lot

  • Paiements en masse : Payez plusieurs employés, fournisseurs ou partenaires en une seule fois
  • Distributions : Envoyez des actifs à plusieurs adresses
  • Transferts multi-destinataires : Envoyez des montants différents à des adresses différentes
  • Efficacité opérationnelle : Réduisez les appels API et simplifiez la logique de paiement

Paramètres de la requête par lot

Pour les retraits par lot, utilisez le tableau assets au lieu des paramètres individuels :
ParamètreTypeRequisDescription
assetsarrayOuiTableau d’objets de retrait (max 20 par lot)
Chaque élément du tableau assets :
ChampTypeRequisDescription
idstringOuiL’UUID de l’actif à retirer
addressstringOuiL’adresse de destination
amountstringOuiLe montant du retrait. Doit être supérieur à 0.
referencestringNonNote de référence optionnelle pour ce retrait
notestringNonUn message court ou une remarque interne. Non visible on-chain.
metadataobjectNonPaires clé-valeur personnalisées pour des détails supplémentaires de la transaction.

Exemple de retrait par lot

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assets": [
      {
        "id": "asset-uuid-usdc",
        "address": "0xRecipient1...",
        "amount": "100",
        "reference": "payout-001",
        "note": "January salary"
      },
      {
        "id": "asset-uuid-usdc",
        "address": "0xRecipient2...",
        "amount": "150",
        "reference": "payout-002",
        "note": "January salary"
      },
      {
        "id": "asset-uuid-usdt",
        "address": "0xRecipient3...",
        "amount": "200",
        "reference": "payout-003",
        "note": "Vendor payment"
      }
    ]
  }'

Réponse du retrait par lot

{
  "message": "Batch withdrawal initiated successfully",
  "statusCode": 200,
  "data": {
    "success": [
      {
        "index": 0,
        "id": "tx-uuid-1",
        "hash": "0xabc...",
        "status": "PENDING",
        "amount": "100",
        "recipientAddress": "0xRecipient1...",
        "reference": "payout-001"
      },
      {
        "index": 1,
        "id": "tx-uuid-2",
        "hash": "0xdef...",
        "status": "PENDING",
        "amount": "150",
        "recipientAddress": "0xRecipient2...",
        "reference": "payout-002"
      },
      {
        "index": 2,
        "id": "tx-uuid-3",
        "hash": "0xghi...",
        "status": "PENDING",
        "amount": "200",
        "recipientAddress": "0xRecipient3...",
        "reference": "payout-003"
      }
    ],
    "errors": []
  }
}

Gestion des échecs partiels

Les retraits par lot prennent en charge le succès partiel. Si certains retraits échouent, les autres seront tout de même exécutés :
const result = await batchWithdrawal.json();

// Process successful withdrawals
result.data.success.forEach(tx => {
  console.log(`✓ ${tx.reference}: ${tx.hash}`);
});

// Handle failed withdrawals
result.data.errors.forEach(error => {
  console.error(`✗ Index ${error.index}: ${error.error}`);
  // Retry logic or error reporting here
});

Règles des retraits par lot

RègleValeur
Taille maximale du lot20 retraits par requête
Taille minimale du lot1 retrait
Ordre d’exécutionSéquentiel
Gestion des erreursSuccès partiel (les échecs n’arrêtent pas les retraits suivants)

Estimation des frais réseau

Estimez toujours les frais avant d’exécuter des retraits afin de garantir un solde suffisant en token natif et d’afficher des coûts précis aux utilisateurs.

Estimation des frais individuels

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/network-fee \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-here",
    "address": "0xRecipientAddress...",
    "amount": "100"
  }'

Réponse pour les frais individuels

{
  "message": "Network fee fetched successfully",
  "statusCode": 200,
  "data": {
    "networkFee": "0.00001247904",
    "networkFeeInUSD": "0.01",
    "transactionFee": "0",
    "nativeBalance": "0.5",
    "nativeBalanceInUSD": "450.00",
    "estimatedArrivalTime": 30
  }
}

Estimation des frais par lot

Estimez les frais pour plusieurs retraits à la fois :
curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/network-fee \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assets": [
      {
        "id": "asset-uuid-1",
        "address": "0xRecipient1...",
        "amount": "100"
      },
      {
        "id": "asset-uuid-2",
        "address": "0xRecipient2...",
        "amount": "50"
      }
    ]
  }'

Réponse pour les frais par lot

{
  "message": "Network fee fetched successfully",
  "statusCode": 200,
  "data": {
    "fees": [
      {
        "index": 0,
        "assetId": "asset-uuid-1",
        "address": "0xRecipient1...",
        "amount": "100",
        "networkFee": "0.00001247904",
        "transactionFee": "0",
        "estimatedArrivalTime": 30
      },
      {
        "index": 1,
        "assetId": "asset-uuid-2",
        "address": "0xRecipient2...",
        "amount": "50",
        "networkFee": "0.00000504",
        "transactionFee": "0",
        "estimatedArrivalTime": 30
      }
    ],
    "totalNetworkFee": "0.00001751904",
    "totalNetworkFeeInUSD": "0.02",
    "totalTransactionFee": "0",
    "nativeBalance": "0.073690520542044578",
    "nativeBalanceInUSD": "66.54",
    "estimatedArrivalTime": 60,
    "errors": []
  }
}

Champs de la réponse de frais

ChampDescription
networkFeeFrais de gas en unités de token natif (retrait individuel)
networkFeeInUSDFrais de gas convertis en USD (retrait individuel)
feesTableau des estimations individuelles de frais (retrait par lot)
totalNetworkFeeSomme de tous les frais réseau (retrait par lot)
totalNetworkFeeInUSDTotal des frais réseau en USD (retrait par lot)
transactionFeeFrais de transaction de la plateforme (le cas échéant)
nativeBalanceSolde actuel du token natif
nativeBalanceInUSDSolde du token natif en USD
estimatedArrivalTimeTemps de confirmation estimé en secondes
errorsTableau des estimations échouées (retrait par lot)

Mode Sign-Only

Signez des transactions sans les diffuser sur la blockchain. Utile pour :
  • Signature hors ligne : Préparez les transactions pour un envoi ultérieur
  • Flux multi-signatures : Collectez les signatures avant l’envoi
  • Inspection de transaction : Vérifiez les détails de la transaction avant de la diffuser

Exemple de Sign-Only

curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/withdraw/sign \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-here",
    "address": "0xRecipientAddress...",
    "amount": "100"
  }'

Réponse Sign-Only

{
  "message": "Transaction signed successfully",
  "statusCode": 200,
  "data": {
    "id": "tx-uuid-123",
    "signedTransaction": "0xf86c...",
    "status": "SIGNED",
    "amount": "100",
    "recipientAddress": "0xRecipientAddress...",
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

Retraits depuis une Child Address

Retirez depuis des child addresses individuelles plutôt que depuis la master wallet :
curl --request POST \
  --url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/withdraw \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <api-key>' \
  --data '{
    "assetId": "asset-uuid-here",
    "address": "0xRecipientAddress...",
    "amount": "50",
    "reference": "user-withdrawal-123"
  }'
Les retraits depuis une child address prennent également en charge les opérations par lot via le tableau assets, en suivant le même format que les retraits par lot depuis la master wallet.

Événements de Webhook

Surveillez l’achèvement des retraits via les webhooks :
ÉvénementDescription
withdraw.successRetrait terminé et confirmé sur la blockchain
withdraw.failedLe retrait n’a pas pu être exécuté
withdraw.cancelledLe retrait a été annulé avant son achèvement

Payload du Webhook

{
  "event": "withdraw.success",
  "data": {
    "id": "081d6315-159f-4c38-b02a-c4708836c5bd",
    "reference": "payout-12345",
    "senderAddress": "0x947514e4B803e312C312da0F1B41fEDdbe15ae7a",
    "recipientAddress": "0x2455eC6700092991Ce0782365A89d5Cd89c8Fa22",
    "amount": "100",
    "amountPaid": "100",
    "fee": null,
    "currency": "USD",
    "blockNumber": 6928833,
    "hash": "0x5fcb7dd11cbb5a6d64da08cf7e0d63c1a1e7b9d1b89e3e8d1c6a5f4b3a2c1d0e",
    "status": "SUCCESS",
    "type": "WITHDRAW",
    "note": "Monthly payout",
    "asset": {
      "id": "asset-uuid",
      "name": "USD Coin",
      "symbol": "USDC",
      "decimals": 6
    },
    "wallet": {
      "id": "wallet-uuid",
      "name": "Main Treasury"
    },
    "blockchain": {
      "id": "blockchain-uuid",
      "name": "ethereum",
      "network": "mainnet"
    },
    "metadata": {
      "userId": "user_abc123",
      "payoutType": "salary"
    },
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-15T10:31:00Z"
  }
}

Exemple de flux complet

Voici une implémentation complète du flux : estimation des frais → confirmation de l’utilisateur → retrait :
async function processWithdrawal(walletId, assetId, recipientAddress, amount) {
  const apiKey = process.env.BLOCKRADAR_API_KEY;
  const baseUrl = 'https://api.blockradar.co/v1';

  // Step 1: Estimate network fee
  const feeResponse = await fetch(
    `${baseUrl}/wallets/${walletId}/withdraw/network-fee`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        assetId,
        address: recipientAddress,
        amount
      })
    }
  ).then(r => r.json());

  // Step 2: Check if we have enough native balance for gas
  const fee = feeResponse.data;
  if (parseFloat(fee.nativeBalance) < parseFloat(fee.networkFee)) {
    throw new Error(`Insufficient gas: need ${fee.networkFee}, have ${fee.nativeBalance}`);
  }

  // Step 3: Display fee to user (in your UI)
  console.log(`Network fee: ${fee.networkFee} (≈$${fee.networkFeeInUSD})`);
  console.log(`Estimated time: ${fee.estimatedArrivalTime}s`);

  // Step 4: Execute withdrawal (after user confirmation)
  const withdrawal = await fetch(
    `${baseUrl}/wallets/${walletId}/withdraw`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey
      },
      body: JSON.stringify({
        assetId,
        address: recipientAddress,
        amount,
        reference: `withdraw-${Date.now()}`
      })
    }
  ).then(r => r.json());

  console.log('Withdrawal initiated:', withdrawal.data.id);
  console.log('Transaction hash:', withdrawal.data.hash);

  // Step 5: Listen for webhook to confirm completion
  return withdrawal.data;
}

// Usage
processWithdrawal(
  'wallet-uuid',
  'asset-uuid-usdc',
  '0xRecipientAddress...',
  '100'
);

Réponses d’erreur

{
  "message": "Insufficient balance for withdrawal",
  "statusCode": 400,
  "error": "INSUFFICIENT_BALANCE",
  "data": {
    "required": "100",
    "available": "50.25",
    "asset": "USDC"
  }
}
{
  "message": "Insufficient native token balance for gas",
  "statusCode": 400,
  "error": "INSUFFICIENT_GAS",
  "data": {
    "required": "0.005",
    "available": "0.001",
    "token": "ETH"
  }
}
{
  "message": "Invalid recipient address",
  "statusCode": 400,
  "error": "INVALID_ADDRESS",
  "data": {
    "address": "invalid_address_here"
  }
}
{
  "message": "Asset not found",
  "statusCode": 404,
  "error": "ASSET_NOT_FOUND",
  "data": {
    "assetId": "invalid-asset-uuid"
  }
}
{
  "message": "Amount must be greater than 0",
  "statusCode": 400,
  "error": "INVALID_AMOUNT",
  "data": {
    "amount": "0"
  }
}
{
  "message": "Batch size exceeds maximum limit",
  "statusCode": 400,
  "error": "BATCH_SIZE_EXCEEDED",
  "data": {
    "maximum": 20,
    "provided": 25
  }
}

Bonnes pratiques

Sécurité

  • Validez les adresses : Vérifiez toujours les adresses des destinataires avant d’initier les retraits
  • Utilisez des références : Suivez les retraits avec des identifiants de référence uniques pour la réconciliation
  • Mettez en place des webhooks : Écoutez les événements withdraw.success et withdraw.failed pour confirmer le statut
  • Vérifiez l’AML : Blockradar filtre automatiquement les adresses ; examinez toute transaction signalée

Gestion des frais

  • Estimez avant l’exécution : Appelez toujours l’endpoint network-fee avant les retraits
  • Surveillez le solde natif : Assurez-vous d’avoir suffisamment d’ETH/BNB/MATIC pour les frais de gas
  • Utilisez les lots pour plus d’efficacité : Regroupez plusieurs retraits pour réduire les appels API et la charge opérationnelle

Gestion des erreurs

  • Gérez les échecs partiels : Dans les retraits par lot, vérifiez à la fois les tableaux success et errors
  • Mettez en place des nouvelles tentatives : Utilisez un backoff exponentiel pour les défaillances transitoires
  • Journalisez toutes les transactions : Stockez les identifiants et hashes de transactions pour le débogage et la réconciliation

Performance

  • Utilisez des tailles de lot appropriées : Des lots plus grands réduisent les appels API mais augmentent le temps de chaque requête
  • Mettez en cache les IDs d’actifs : Stockez les IDs d’actifs localement pour éviter les recherches répétées
  • Mettez en place une limitation de débit : Respectez les limites de débit de l’API pour éviter le throttling

Référence API

Endpoints Master Wallet

EndpointDescription
WithdrawExécuter un retrait individuel ou par lot
Network FeeEstimer les frais de retrait
Sign-OnlySigner sans diffuser

Endpoints Child Address

EndpointDescription
WithdrawExécuter un retrait individuel ou par lot
Network FeeEstimer les frais de retrait
Sign-OnlySigner sans diffuser

Support

L’API Withdraw fournit une interface flexible pour envoyer des actifs stablecoin vers des adresses externes. Commencez par les retraits individuels et l’estimation des frais, puis intégrez les opérations par lot pour les paiements en masse à mesure que vos besoins grandissent.