Genel Bakış
Private Channels'tan para çekme iki adımlı bir işlemdir. İlk olarak, kullanıcı Withdraw Program üzerinde WithdrawFunds çağırarak kanal tarafındaki token bakiyesini yakar. İkinci olarak, bir operatör fonları serbest bırakmak için Escrow Program üzerinde (bu kılavuzda devnet) geçerli bir Sparse Merkle Tree dışlama kanıtıyla ReleaseFunds çağırır. SMT kanıtı, her para çekme nonce'ının yalnızca bir kez kullanılabilmesini sağlayarak çift harcamayı önler.
Adım 1: Kanalda Para Çekmeyi Başlat
Kanal tarafındaki bakiyenizi yakmak için Withdraw Program üzerinde WithdrawFunds çağırın.
tokenAccount PDA'sını otomatik türeten ve üretim kullanımı için önerilen form olan Async varyantını kullanın:
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 - Bu işlemi genel bir Solana RPC'ye değil, ağ geçidine (
http://localhost:8899) gönderin destinationbelirtilirse, serbest bırakılan fonlar imzalayanın cüzdanı yerine o cüzdana gönderilir
Ne Beklenmeli
WithdrawFunds çağrıldıktan sonra başka bir işlem yapmanıza gerek yoktur. Operatör servisleri uzlaşmayı otomatik olarak gerçekleştirir:
indexer-private-channel, yakma olayları için kanalı her 1 saniyede bir yoklar ve sizin olayınız tespit edildiğinde bekleyen bir para çekme kaydı yazaroperator-private-channel, bekleyen kayıtlar için veritabanını her 1 saniyede bir yoklar ve gerekli SMT dışlama kanıtıyla Solana devnet üzerindeki Escrow Program'aReleaseFundsgönderir; yeniden denemeden önce 400 ms aralıklarla en fazla 5 kez devnet onayı için yoklama yapar
Fonlar normal koşullar altında genellikle birkaç saniye içinde devnet cüzdanınızda görünür.
Operatör Uzlaşması Nasıl Gerçekleşir (Referans)
Kanal tarafındaki yakma işleminden sonra, sağlanmış bir operatörün geçerli bir SMT dışlama kanıtıyla Escrow Program üzerinde ReleaseFunds çağırması gerekir; operatör, para çekme nonce'ının daha önce kullanılmadığını kanıtlamadan fonları serbest bırakamaz. Bu adım operator-private-channel tarafından otomatik olarak gerçekleştirilir; kendiniz çağırmanıza gerek yoktur.
Operatör şunları sağlar:
amount: yakılan miktarla eşleşmelidiruser: devnet üzerindeki alıcı cüzdannew_withdrawal_root: bu para çekiminden sonra güncellenmiş SMT kökütransaction_nonce: bu yaprak için benzersiz noncesibling_proofs: 512 bayt (ağaç kanıtı için 16 x 32 baytlık kardeş hash'ler)
Doğrulama
Operatör çağrısı onaylandıktan sonra devnet token bakiyenizi kontrol edin:
spl-token balance <MINT_ADDRESS> --owner <YOUR_WALLET>
Ya da RPC aracılığıyla:
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);
Hızlı Başlangıcı Tamamladınız
Devnet üzerinde tam Private Channels döngüsünü çalıştırdınız: SPL tokenları escrow'a yatırdınız, ağ geçidi üzerinden zincir dışı bir transfer gönderdинiz ve fonları devnet cüzdanınıza geri çektiniz.
Kanal Yaşam Döngüsü
Katılımcıları ve yatırımdan para çekmeye kadar olan tam akışı derinlemesine anlayın.
Kimlik Doğrulama ve Roller
Entegrasyonunuza JWT kimlik doğrulaması ekleyin.
Fon Serbest Bırakma Referansı
Operatör araçları için tam ReleaseFunds talimat referansı.
Sparse Merkle Tree
Para çekme kanıtlarının çift harcamayı nasıl önlediğini anlayın.
Is this page helpful?