Finanziare le gambe

Il finanziamento è un semplice TransferChecked verso l'escrow della gamba, quindi qualsiasi wallet o sistema di custodia in grado di inviare un trasferimento di token può finanziare una gamba. Solo la lettura del record dell'operazione prima del finanziamento richiede il client DvP. Il programma controlla i saldi degli escrow solo al regolamento; nulla verifica il trasferimento quando arriva, quindi ogni parte legge il record dell'operazione prima di trasferire.

Questa pagina prosegue da crea un'operazione; il client e i firmatari restano invariati.

Verificare i termini

La creazione di un record non richiede autorizzazioni, e gli indirizzi degli escrow derivano dal record e dal mint soltanto, mai dai termini. Un trasferimento verso un escrow può quindi arrivare a fronte di termini che non hai mai concordato, incluse destinazioni di regolamento che reindirizzano i proventi della tua controparte verso un terzo indirizzo. Prima di finanziare, leggi l'account SwapDvp e confrontalo con l'operazione concordata.

verifySwapDvp in TypeScript e verify::decode_swap_dvp_account in Rust confermano che l'account appartenga al programma DvP, abbia esattamente 458 byte e si trovi all'indirizzo derivato dai propri campi (fetchSwapDvpChecked esegue solo le prime due verifiche). I lettori semplici fetchSwapDvp e decodeSwapDvp non eseguono nessuna di queste verifiche. I controlli su parti, importi, tempi e destinazioni sono eseguiti dal chiamante rispetto all'operazione concordata.

import { unwrapOption } from "@solana/kit";
import { verifySwapDvp } from "./dvp";
const trade = await verifySwapDvp(client.rpc, swapDvp);
const t = trade.data;
const expectedAmountA = 1_000_000_000n;
const expectedAmountB = 998_500_000n;
const expectedEarliestSettlement: bigint | null = null; // as agreed
const expectedExpiry = 1_798_761_600n; // as agreed, unix seconds
if (
t.userA !== userA ||
t.userB !== userB ||
t.mintA !== mintA ||
t.mintB !== mintB ||
t.settlementAuthority !== settlementAuthority ||
t.tokenProgramA !== tokenProgramA ||
t.tokenProgramB !== tokenProgramB ||
t.amountA !== expectedAmountA ||
t.amountB !== expectedAmountB ||
unwrapOption(t.earliestSettlementTimestamp) !== expectedEarliestSettlement ||
t.expiryTimestamp !== expectedExpiry ||
t.userASettlementDestination !== userA ||
t.userBSettlementDestination !== userB
) {
throw new Error("Stored terms do not match the agreed trade; do not fund");
}
if (t.expiryTimestamp <= BigInt(Math.floor(Date.now() / 1000)) + 60n) {
throw new Error("Trade expires too soon to fund safely");
}

Se il record è stato creato dalla tua controparte o dall'autorità di regolamento, confronta ogni campo con i termini concordati fuori dal ledger. Se lo hai creato tu stesso, questa lettura conferma che è arrivato come inviato.

Trasferire nell'escrow

Finanzia la gamba esattamente per l'importo concordato. Il programma limita il regolamento a amount_x e restituisce l'eventuale eccedenza alla parte della gamba, quindi un'eccedenza non va persa, ma aggiunge un secondo trasferimento al regolamento e può fallire con alcuni transfer hook (vedi le note qui sotto).

Usa TransferChecked, non un Transfer non verificato. I mint Token-2022 con estensioni che dipendono dal mint account, come Pausable, rifiutano un trasferimento che non lo fornisce, e un mint con un transfer hook richiede che gli account dell'hook siano risolti e aggiunti allo stesso modo di qualsiasi altro trasferimento di quel token.

La parte della gamba dell'asset, firmando come userASigner, finanzia l'escrow A:

import {
findAssociatedTokenPda,
getTransferCheckedInstruction,
} from "@solana-program/token-2022";
const [userAAtaA] = await findAssociatedTokenPda({
mint: mintA,
owner: userA,
tokenProgram: tokenProgramA,
});
const [userBAtaB] = await findAssociatedTokenPda({
mint: mintB,
owner: userB,
tokenProgram: tokenProgramB,
});
const fundAssetLeg = getTransferCheckedInstruction({
source: userAAtaA,
mint: mintA,
destination: escrowA,
authority: userASigner,
amount: t.amountA,
decimals: 6,
}, { programAddress: tokenProgramA });
await client.sendTransaction([fundAssetLeg]);

La parte della gamba in contanti fa lo stesso per l'escrow B con userBAtaB, mintB, userBSigner, t.amountB e { programAddress: tokenProgramB }.

Un trasferimento di finanziamento visto a confirmed può ancora essere sostituito. Il programma legge il saldo dell'escrow onchain al regolamento, quindi un Settle inviato a fronte di un trasferimento di finanziamento non andato a buon fine fallisce con LegNotFunded e nulla si muove; il costo è un Settle fallito e un nuovo tentativo. Considera una gamba finanziata quando il suo trasferimento è finalized.

Note

  • Gambe in SOL wrapped. Il programma legge il saldo di un escrow nativo dopo averlo sincronizzato, quindi i lamport inviati a un escrow wrapped-SOL tramite un trasferimento di sistema vengono conteggiati. Non inviare mai SOL a un escrow per qualsiasi altro mint: il programma non può restituirli, e vanno a chi chiude l'account.
  • Mint con restrizioni. Su un mint con Default Account State impostato su frozen, l'escrow viene creato congelato e il trasferimento fallisce finché l'emittente non lo sblocca o lo ammette. La panoramica descrive l'interazione con Token ACL.
  • Transfer hook. Finanzia gli escrow con hook esattamente per l'importo concordato. Se un'eccedenza rende necessario un rimborso al regolamento, il rimborso riutilizza gli account dell'hook della gamba con una destinazione e un importo diversi, cosa che alcuni hook rifiutano. Il rimedio è Reclaim, rifinanziare con l'importo esatto e regolare di nuovo.
  • Finanziamento oltre la scadenza. Nulla impedisce un trasferimento dopo expiry_timestamp. Arriva a destinazione, il regolamento non è più possibile e la parte della gamba lo recupera con Reclaim mentre l'operazione è aperta o con Recover dopo la sua chiusura. Vedi annullare un'operazione.
  • Chi finanzia per primo. Il programma non stabilisce una sequenza tra le due gambe. L'ordine è una questione tra le parti; ciascun lato può recuperare la propria gamba in qualsiasi momento prima del regolamento, a meno che un'autorità del mint (freeze, pause o transfer hook) non blocchi l'escrow.

Passaggi successivi

Is this page helpful?

Indice dei contenuti

Modifica pagina
© 2026 Solana Foundation. Tutti i diritti riservati.