Overzicht
Opnemen vanuit Private Channels is een proces in twee stappen. Eerst verbrandt de gebruiker
hun kanaalzijdig tokensaldo door WithdrawFunds aan te roepen op het Withdraw
Program. Vervolgens roept een operator ReleaseFunds aan op het Escrow Program (devnet,
in deze walkthrough) met een geldig Sparse Merkle Tree-uitsluitingsbewijs om de
fondsen vrij te geven. Het SMT-bewijs zorgt ervoor dat elke opname-nonce slechts één keer kan worden gebruikt,
waardoor dubbele uitgaven worden voorkomen.
Stap 1: Opname initiëren op het kanaal
Roep WithdrawFunds aan op het Withdraw Program om uw kanaalzijdig saldo te verbranden.
Gebruik de Async-variant, die de tokenAccount PDA automatisch afleidt en de
aanbevolen vorm is voor productiegebruik:
import { getWithdrawFundsInstructionAsync } from "../private-channel-withdraw-program/clients/typescript/src/generated";import {createSolanaRpc,address,pipe,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstruction,signAndSendTransactionMessageWithSigners,assertIsTransactionMessageWithSingleSendingSigner,getBase58Decoder} from "@solana/kit";// Point to the gateway, not a public Solana RPCconst privateChannelRpc = createSolanaRpc("http://localhost:8899");const withdrawIx = await getWithdrawFundsInstructionAsync({user: userSigner,mint: address(mintAddress),amount: 1_000_000n, // 1 USDC (6 decimals)destination: null // null = release to signer's devnet wallet});const { value: latestBlockhash } = await privateChannelRpc.getLatestBlockhash({ commitment: "confirmed" }).send();// Sent to the Private Channels gateway (not Solana RPC directly), which// expects the legacy transaction format - do not switch this to version 0.const transactionMessage = pipe(createTransactionMessage({ version: "legacy" }),(m) => setTransactionMessageFeePayerSigner(userSigner, m),(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),(m) => appendTransactionMessageInstruction(withdrawIx, m));assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);const signatureBytes =await signAndSendTransactionMessageWithSigners(transactionMessage);const signature = getBase58Decoder().decode(signatureBytes);console.log("Withdrawal initiated:", signature);
- Withdraw Program ID:
J231K9UEpS4y4KAPwGc4gsMNCjKFRMYcQBcjVW7vBhVi - Dien deze transactie in bij de gateway (
http://localhost:8899), niet bij een openbare Solana RPC - Als
destinationis opgegeven, gaan vrijgegeven fondsen naar die wallet in plaats van naar die van de ondertekenaar
Wat u kunt verwachten
Er zijn geen verdere acties vereist na het aanroepen van WithdrawFunds. De operator-
services verwerken de afwikkeling automatisch:
indexer-private-channelpeilt het kanaal elke 1 seconde op verbrandingsgebeurtenissen en schrijft een record voor een openstaande opname wanneer die van u wordt gedetecteerdoperator-private-channelpeilt de database elke 1 seconde op openstaande records en dientReleaseFundsin bij het Escrow Program op Solana devnet met het vereiste SMT-uitsluitingsbewijs; het peilt voor devnet-bevestiging tot 5 keer met intervallen van 400 ms alvorens opnieuw te proberen
Fondsen verschijnen doorgaans binnen enkele seconden in uw devnet-wallet onder normale omstandigheden.
Hoe de operator afwikkelt (referentie)
Na de kanaalzijdige verbranding moet een ingerichte operator ReleaseFunds aanroepen op
het Escrow Program met een geldig SMT-uitsluitingsbewijs; de operator kan geen fondsen
vrijgeven zonder te bewijzen dat de opname-nonce nog niet eerder is gebruikt. Deze stap
wordt automatisch afgehandeld door operator-private-channel; u hoeft dit zelf niet aan te roepen.
De operator verstrekt:
amount: moet overeenkomen met het verbrande bedraguser: ontvangende wallet op devnetnew_withdrawal_root: bijgewerkte SMT-root na deze opnametransaction_nonce: unieke nonce voor dit bladsibling_proofs: 512 bytes (16 x 32-byte broer/zus-hashes voor het boomsbewijs)
Verifiëren
Controleer uw devnet-tokensaldo nadat de operatoraanroep is bevestigd:
spl-token balance <MINT_ADDRESS> --owner <YOUR_WALLET>
Of via RPC:
import { createSolanaRpc, address } from "@solana/kit";import { findAssociatedTokenPda } from "@solana-program/token";const TOKEN_PROGRAM_ADDRESS = address("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");// Query devnet directly; ReleaseFunds settles here, not through the gatewayconst rpc = createSolanaRpc("https://api.devnet.solana.com");const [yourDevnetAta] = await findAssociatedTokenPda({mint: address(mintAddress),owner: address(userSigner.address),tokenProgram: TOKEN_PROGRAM_ADDRESS});const balance = await rpc.getTokenAccountBalance(yourDevnetAta).send();console.log(balance.value.uiAmountString);
U heeft de Quickstart voltooid
U heeft de volledige Private Channels-cyclus op devnet uitgevoerd: SPL-tokens gestort in de escrow, een off-chain overdracht verzonden via de gateway en fondsen teruggetrokken naar uw devnet-wallet.
Levenscyclus van het kanaal
Begrijp deelnemers en de volledige stroom van storting tot opname in detail.
Authenticatie & Rollen
Voeg JWT-authenticatie toe aan uw integratie.
Referentie voor het vrijgeven van fondsen
Volledige ReleaseFunds-instructiereferentie voor operatortooling.
Sparse Merkle Tree
Begrijp hoe opnamebewijzen dubbele uitgaven voorkomen.
Is this page helpful?