Finanzia le leg

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

Questa pagina prosegue da creare uno scambio; il client e i firmatari vengono riutilizzati.

Verifica i termini

La creazione di un record è permissionless, e gli indirizzi di escrow derivano dal solo record e dal mint, mai dai termini. Un trasferimento verso un escrow può quindi arrivare a fronte di termini che non hai mai concordato, comprese destinazioni di regolamento che reindirizzano i proventi della tua controparte a un terzo indirizzo. Prima di finanziare, leggi l'account SwapDvp e confrontalo con lo scambio concordato.

verifySwapDvp in TypeScript e verify::decode_swap_dvp_account in Rust confermano che l'account appartiene al programma DvP, è esattamente di 458 byte e si trova all'indirizzo derivato dai suoi stessi 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, tempistiche e destinazioni vengono eseguiti dal chiamante rispetto allo scambio concordato.

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.

Trasferisci nell'escrow

Finanzia la leg esattamente con l'importo concordato. Il programma limita il regolamento a amount_x e restituisce l'eventuale eccedenza alla parte della leg, quindi l'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 leg 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 leg in contanti fa lo stesso per l'escrow B con userBAtaB, mintB, userBSigner, t.amountB e { programAddress: tokenProgramB }.

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

Note

  • Leg in SOL wrapped. Il programma legge il saldo di un escrow nativo dopo averlo sincronizzato, quindi i lamport inviati a un escrow di SOL wrapped tramite un trasferimento di sistema vengono conteggiati. Non inviare mai SOL a un escrow di un 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 con l'importo concordato. Se un'eccedenza rende necessario un rimborso al regolamento, il rimborso riutilizza gli account dell'hook della leg con una destinazione e un importo diversi, cosa che alcuni hook rifiutano. Il recupero consiste in Reclaim, nuovo finanziamento con l'importo esatto e nuovo regolamento.
  • Finanziamento dopo la scadenza. Nulla impedisce un trasferimento dopo expiry_timestamp. Il trasferimento arriva, il regolamento non è più possibile e la parte della leg lo recupera con Reclaim finché lo scambio è aperto o con Recover dopo la sua chiusura. Vedi annullare uno scambio.
  • Chi finanzia per primo. Il programma non stabilisce una sequenza tra le due leg. L'ordine è una questione tra le parti; ciascun lato può recuperare la propria leg in qualsiasi momento prima del regolamento, a meno che una mint authority (freeze, pause o transfer hook) non blocchi l'escrow.

Prossimi passi

  • Regola lo scambio: l'autorità di regolamento scambia entrambe le leg in un'unica transazione
  • Annulla uno scambio: recuperare una leg finanziata quando lo scambio non viene regolato

Is this page helpful?

Indice dei contenuti

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