Liberar Fundos

Chamado por um operador provisionado para liberar tokens em escrow para a carteira Mainnet de um usuário, condicionado a uma prova de exclusão válida de Sparse Merkle Tree para o nonce de saque.

O programa de escrow está migrando deste design de Sparse Merkle Tree para um bitmap de nonce on-chain (rastreado upstream). Esta página está correta em relação ao programa de escrow atual e será revisada assim que essa mudança for implementada.

Contas

ContaGravávelAssinanteDescrição
payer✓✓Pagador de taxa
operator✓Assinante operador
instance✓PDA da instância de escrow (raiz atualizada on-chain)
operator_pdaPDA do operador comprovando que o assinante está provisionado
mintMint de token SPL
allowed_mintPDA AllowedMint - valida que o mint é permitido nesta instância
user_ata✓associated token account do destinatário (destino)
instance_ata✓associated token account do escrow (origem)
token_programSPL Token Program
associated_token_programAssociated Token Program
event_authorityPDA de autoridade de evento para CPI EmitEvent
private_channel_escrow_programPrograma de Escrow (auto-referência para CPI)

Parâmetros

ParâmetroTipoDescrição
amountu64Quantidade de tokens a liberar
userPubkeyCarteira destinatária na Mainnet
new_withdrawal_root[u8; 32]Raiz SMT atualizada após incluir o nonce deste saque
transaction_nonceu64Nonce único que identifica a folha deste saque na SMT
sibling_proofs[u8; 512]16 hashes irmãos (32 bytes cada) para a prova de exclusão SMT

Retornos

Retorna um TransactionBuilder que pode ser usado para construir e enviar a transação.

Exemplo

import { getReleaseFundsInstruction } from "../private-channel-escrow-program/clients/typescript/src/generated";
const releaseIx = getReleaseFundsInstruction({
payer: operatorPayerSigner,
operator: operatorSigner,
instance: instancePda,
operatorPda: operatorPdaAddress,
mint: mintAddress,
allowedMint: allowedMintPda,
userAta: userAtaAddress,
instanceAta: instanceAtaAddress,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
eventAuthority: eventAuthorityPda,
privateChannelEscrowProgram: ESCROW_PROGRAM_ID,
amount: 1_000_000n,
user: recipientPublicKey,
newWithdrawalRoot: newSmtRoot, // [u8; 32]
transactionNonce: withdrawalNonce, // u64
siblingProofs: proofBytes // Uint8Array(512)
});

Notas Importantes

  • O chamador deve ser um operador provisionado: operator_pda deve existir (criado por AddOperator); um PDA inválido lança InvalidOperatorPda
  • sibling_proofs tem exatamente 512 bytes (16 × hashes de 32 bytes, correspondendo à altura da árvore SMT de 16)
  • new_withdrawal_root é a raiz SMT atualizada após incluir o nonce deste saque. Calcule off-chain antes de chamar
  • transaction_nonce deve ser válido para Instance.current_tree_index; um nonce inválido lança InvalidTransactionNonceForCurrentTreeIndex
  • O programa primeiro executa verify_smt_exclusion_proof, provando que o nonce NÃO existe ainda em relação à raiz atual, depois executa separadamente verify_smt_inclusion_proof provando que o nonce EXISTE na new_withdrawal_root fornecida pelo chamador. Qualquer verificação que falhe lança InvalidSmtProof
  • Somente após ambas as verificações serem aprovadas é que Instance.withdrawal_transactions_root é atualizado atomicamente; o nonce não pode ser reutilizado
  • Emite um evento via CPI EmitEvent

Is this page helpful?

Índice

Editar Página
© 2026 Fundação Solana. Todos os direitos reservados.