Das Funding ist ein einfacher TransferChecked in das Escrow des Legs. Daher kann jede Wallet und jedes Custody-System, das einen Token-Transfer senden kann, ein Leg finanzieren. Nur das Lesen des Trade-Eintrags vor dem Funding erfordert den DvP-Client. Das Programm prüft die Escrow-Guthaben erst beim Settlement; nichts prüft den Transfer, wenn er eingeht. Deshalb liest jede Partei den Trade-Eintrag, bevor sie überweist.
Diese Seite setzt Trade erstellen fort; Client und Signer werden übernommen.
Die Konditionen prüfen
Das Erstellen eines Eintrags ist permissionless, und die Escrow-Adressen werden allein aus dem Eintrag und dem Mint abgeleitet, nie aus den Konditionen. Ein Transfer in ein Escrow kann daher zu Konditionen eingehen, denen Sie nie zugestimmt haben, einschließlich Settlement-Zielen, die die Erlöse Ihrer Gegenpartei an eine dritte Adresse umleiten. Lesen Sie vor dem Funding das SwapDvp-Konto und gleichen Sie es mit dem vereinbarten Trade ab.
verifySwapDvp in TypeScript und verify::decode_swap_dvp_account in Rust bestätigen, dass das Konto dem DvP-Programm gehört, genau 458 Bytes groß ist und an der Adresse liegt, die sich aus seinen eigenen Feldern ableitet (fetchSwapDvpChecked führt nur die ersten beiden Prüfungen durch). Die einfachen Reader fetchSwapDvp und decodeSwapDvp führen keine dieser Prüfungen durch. Die Prüfungen von Parteien, Beträgen, Zeiten und Zielen führt der Aufrufer anhand des vereinbarten Trades durch.
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 agreedconst expectedExpiry = 1_798_761_600n; // as agreed, unix secondsif (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");}
Wurde der Eintrag von Ihrer Gegenpartei oder der Settlement-Autorität erstellt, vergleichen Sie jedes Feld mit den Konditionen, die Sie außerhalb des Ledgers vereinbart haben. Haben Sie ihn selbst erstellt, bestätigt dieses Lesen, dass er wie gesendet angekommen ist.
In das Escrow transferieren
Finanzieren Sie das Leg mit genau dem vereinbarten Betrag. Das Programm begrenzt das Settlement auf amount_x und gibt einen Überschuss an die Partei des Legs zurück. Ein Überschuss geht also nicht verloren, erfordert aber beim Settlement einen zweiten Transfer und kann bei manchen Transfer Hooks fehlschlagen (siehe die Hinweise unten).
Verwenden Sie TransferChecked, nicht ein ungeprüftes Transfer. Token-2022-Mints mit Erweiterungen, die vom mint account abhängen, wie Pausable, lehnen einen Transfer ab, der diesen nicht angibt. Ein Mint mit Transfer Hook benötigt zudem die Konten des Hooks, aufgelöst und angehängt, genau wie bei jedem anderen Transfer dieses Tokens.
Die Partei des Asset-Legs finanziert als userASigner signierend das 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]);
Die Partei des Cash-Legs macht dasselbe für Escrow B mit userBAtaB, mintB,
userBSigner, t.amountB und { programAddress: tokenProgramB }.
Ein Funding-Transfer, der bei confirmed
sichtbar ist, kann noch ersetzt werden. Das Programm liest den Escrow-Saldo beim Settlement onchain. Ein Settle, das gegen einen nicht gelandeten Funding-Transfer gesendet wird, schlägt daher
mit LegNotFunded fehl, und es wird nichts bewegt; die Kosten sind ein fehlgeschlagenes Settle und ein erneuter Versuch.
Betrachten Sie ein Leg erst dann als finanziert, wenn sein Transfer finalized ist.
Hinweise
- Wrapped-SOL-Legs. Das Programm liest den Saldo eines nativen Escrows nach dessen Synchronisierung, sodass lamports, die per System-Transfer an ein Wrapped-SOL-Escrow gesendet wurden, mitgezählt werden. Senden Sie niemals SOL an ein Escrow für einen anderen Mint: Das Programm kann es nicht zurückgeben, und es geht an denjenigen, der das Konto schließt.
- Gated Mints. Bei einem Mint mit Default Account State Frozen wird das Escrow eingefroren erstellt, und der Transfer schlägt fehl, bis der Emittent es freigibt oder zulässt. Die Übersicht beschreibt das Zusammenspiel mit Token ACL.
- Transfer Hooks. Finanzieren Sie Escrows mit Hook genau mit dem vereinbarten Betrag. Erzwingt ein Überschuss beim Settlement eine Rückerstattung, verwendet diese die Hook-Konten des Legs mit anderem Ziel und anderem Betrag wieder, was manche Hooks ablehnen. Die Wiederherstellung besteht aus Reclaim, erneutem Funding mit dem exakten Betrag und erneutem Settlement.
- Funding nach Ablauf. Nichts verhindert einen Transfer nach
expiry_timestamp. Er geht ein, ein Settlement ist aber nicht mehr möglich, und die Partei des Legs holt ihn mit Reclaim zurück, solange der Trade offen ist, oder mit Recover, nachdem er geschlossen wurde. Siehe Einen Trade rückabwickeln. - Wer zuerst finanziert. Das Programm legt keine Reihenfolge der beiden Legs fest. Die Reihenfolge ist Sache der Parteien; jede Seite kann ihr eigenes Leg jederzeit vor dem Settlement zurückfordern, es sei denn, eine Mint-Autorität (Freeze, Pause oder Transfer Hook) blockiert das Escrow.
Nächste Schritte
- Den Trade abwickeln: Die Settlement- Autorität tauscht beide Legs in einer Transaktion aus
- Einen Trade rückabwickeln: ein finanziertes Leg wiederherstellen, wenn der Trade nicht abgewickelt wird
Is this page helpful?