SettleDvp wordt ondertekend door de settlement authority die in het traderecord is vermeld. In
één transactie verplaatst de instructie amount_a van de assetleg naar de bestemming van de partij van de cashleg en amount_b van de cashleg naar de bestemming van de partij van de assetleg,
stort ze eventueel overschot in beide escrows terug aan de partij van die leg en sluit ze het record
en beide escrows. Als een van deze overdrachten niet kan worden voltooid, mislukt de instructie
en wordt er niets verplaatst.
Deze pagina vervolgt op een trade aanmaken
en de legs funden; de client, de ondertekenaars,
trade en de token accounts van de partijen blijven hetzelfde.
Opnieuw valideren voordat je ondertekent
De settlement authority ondertekent de transactie die beide legs verplaatst, dus ze voert dezelfde controle uit als elke partij voordat ze ondertekent: eigenaar, grootte, partijen, mints, bedragen, vervaldatum en beide bestemmingen (zie de legs funden). Het programma controleert bij de afwikkeling zelf opnieuw of elke mint nog steeds bij het token program hoort dat bij het aanmaken is vastgelegd, geen geblokkeerde extensie bevat en dezelfde mint authority heeft als toen de trade werd aangemaakt. Een mint die opnieuw is aangemaakt met een geblokkeerde extensie, een ander token program of een andere mint authority kan dus niet worden afgewikkeld.
De ontvangende accounts aanmaken
Settle schrijft naar vier token accounts die het programma niet zelf aanmaakt:
| Account | Ontvangt | Eigenaar |
|---|---|---|
userADestinationAtaB | De cashleg (amount_b) | user_a_settlement_destination |
userBDestinationAtaA | De assetleg (amount_a) | user_b_settlement_destination |
userAAtaA | Eventueel overschot op de assetleg | user_a |
userBAtaB | Eventueel overschot op de cashleg | user_b |
De overschotaccounts worden alleen gebruikt wanneer een escrow meer bevat dan het afgesproken bedrag, maar iedereen die de mint bezit kan een overschot creëren door een paar basis- eenheden naar de escrow te sturen. Als het terugbetalingsaccount niet bestaat, mislukt de hele Settle. Maak daarom alle vier idempotent aan in dezelfde transactie.
import {findAssociatedTokenPda,getCreateAssociatedTokenIdempotentInstruction,} from "@solana-program/token-2022";const destinationA = t.userASettlementDestination; // defaults to userAconst destinationB = t.userBSettlementDestination; // defaults to userBconst [userADestinationAtaB] = await findAssociatedTokenPda({mint: mintB,owner: destinationA,tokenProgram: tokenProgramB,});const [userBDestinationAtaA] = await findAssociatedTokenPda({mint: mintA,owner: destinationB,tokenProgram: tokenProgramA,});// userAAtaA and userBAtaB are from fund the legs.const createRecipientAccounts = [{ ata: userADestinationAtaB, owner: destinationA, mint: mintB, tokenProgram: tokenProgramB },{ ata: userBDestinationAtaA, owner: destinationB, mint: mintA, tokenProgram: tokenProgramA },{ ata: userAAtaA, owner: userA, mint: mintA, tokenProgram: tokenProgramA },{ ata: userBAtaB, owner: userB, mint: mintB, tokenProgram: tokenProgramB },].map(({ ata, owner, mint, tokenProgram }) =>getCreateAssociatedTokenIdempotentInstruction({payer: authoritySigner,ata,owner,mint,tokenProgram,}),);
Settle
legAExtrasCount geeft het programma aan hoeveel van de accounts die na de
vaste lijst worden toegevoegd bij de transfer hook van de assetleg horen; de rest hoort bij die van de
cashleg. Geef voor mints zonder transfer hooks nul door en voeg niets toe. Het memo
program account is vereist door de instructie en wordt alleen gebruikt voor bestemmingen
die een memo vereisen.
import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo";import { getSettleDvpInstruction } from "./dvp";const settleInstruction = getSettleDvpInstruction({settlementAuthority: authoritySigner,swapDvp,mintA,mintB,dvpAtaA: escrowA,dvpAtaB: escrowB,userADestinationAtaB,userBDestinationAtaA,userAAtaA,userBAtaB,tokenProgramA,tokenProgramB,memoProgram: MEMO_PROGRAM_ADDRESS,legAExtrasCount: 0,});const { context: settleContext } = await client.sendTransaction([...createRecipientAccounts,settleInstruction,]);const settleSignature = settleContext.signature;console.log("Submitted:", settleSignature);// sendTransaction returns at the client's commitment (confirmed by default).// Wait for finalized before recording the trade as settled.let finalized = false;for (let attempt = 0; attempt < 30 && !finalized; attempt++) {const {value: [status],} = await client.rpc.getSignatureStatuses([settleSignature]).send();if (status?.err) {throw new Error("Settle transaction failed");}finalized = status?.confirmationStatus === "finalized";if (!finalized) {await new Promise((resolve) => setTimeout(resolve, 2_000));}}if (!finalized) {// A closed record means it settled; an open one is safe to settle again.throw new Error("Settle not finalized after 60s; read the trade record");}console.log("Settled:", settleSignature);
Transfer hooks
De gegenereerde IDL vermeldt alleen de vaste accounts, dus de gegenereerde builders
kennen de hook-accounts niet. Bepaal de extra account metas van elke hook-mint op dezelfde
manier als bij een directe overdracht van dat token en voeg ze vervolgens toe aan de
instructie: eerst de accounts van de assetleg, dan die van de cashleg, waarbij
legAExtrasCount is ingesteld op het aantal in de eerste groep. Spreid in TypeScript
de bepaalde metas over de accounts-array van de instructie; gebruik in Rust
add_remaining_accounts op de builder. De limiet is 32 accounts per leg,
inclusief het hook-programma en het validatieaccount; de accountlimiet van de transactie
kan eerder gelden wanneer beide legs hooks hebben. Het programma verwijdert de signer-vlag
van elk doorgestuurd account, zodat een hook via dit pad de handtekening van de
settlement authority niet kan verkrijgen.
Het resultaat vastleggen
Beschouw de trade als afgewikkeld wanneer de Settle-transactie finalized bereikt. Het
record en beide escrows bestaan na de afwikkeling niet meer, dus een systeem dat de voorwaarden
later nodig heeft, slaat ze op vanuit de controle vóór de afwikkeling of vanuit de
aanmaaktransactie. De rent van de gesloten accounts is naar de settlement
authority gegaan.
Settle-fouten
LegNotFunded betekent dat een escrow minder bevat dan het afgesproken bedrag; DvpExpired
en SettlementTooEarly betekenen dat het tijdvenster is gemist; MintAuthorityChanged
en BlockedMintExtension betekenen dat een mint na het aanmaken is gewijzigd;
RecipientAtaMismatch betekent dat een bestemmings- of terugbetalings-token account ontbreekt of
niet langer van de verwachte eigenaar en mint is, meestal doordat de
stap voor het aanmaken van accounts hierboven is overgeslagen. In alle gevallen is er niets
verplaatst en kunnen de partijen de trade terugdraaien, afhankelijk van de authorities van de mint (zie
een trade terugdraaien).
Volgende stappen
- Een trade terugdraaien: gefinancierde legs terughalen wanneer een trade niet wordt afgewikkeld
Is this page helpful?