Quattro istruzioni restituiscono i fondi senza eseguire il regolamento: Reclaim, Cancel e Reject mentre lo scambio è aperto, e Recover per un deposito che arriva dopo la chiusura. Nessuna di esse controlla la scadenza. Un escrow congelato o un mint modificato possono comunque bloccare una leg, come descritto nelle note finali.
| Istruzione | Firmatario | Ambito | Stato dello scambio dopo |
|---|---|---|---|
ReclaimDvp | user_a o user_b | La leg del firmatario | Ancora aperto |
CancelDvp | Autorità di regolamento | Entrambe le leg | Chiuso |
RejectDvp | user_a o user_b | Entrambe le leg | Chiuso |
RecoverDvp | user_a o user_b | La leg del firmatario, dopo la chiusura | Già chiuso |
In ogni caso l'escrow viene svuotato di tutto ciò che contiene a favore della parte della leg:
l'escrow A verso il token account di user_a per mint_a, l'escrow B verso quello di user_b per
mint_b, indipendentemente da chi lo ha finanziato. Il program account memo viene fornito per gli account di rimborso
che richiedono un memo.
Questa pagina prosegue dai passaggi precedenti: il client e i firmatari di
crea uno scambio, userAAtaA e
userBAtaB da finanzia le leg, e
MEMO_PROGRAM_ID e authority da
regola lo scambio restano validi.
Recuperare una leg
Reclaim restituisce la leg del firmatario e lascia aperto lo scambio, così la leg può essere finanziata di nuovo. Usalo quando il problema riguarda la leg della controparte; Cancel e Reject chiudono l'intero scambio.
import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo";import { getReclaimDvpInstruction } from "./dvp";// The asset-leg party takes its asset back.const reclaimInstruction = getReclaimDvpInstruction({signer: userASigner,swapDvp,mint: mintA,dvpSourceAta: escrowA,signerDestAta: userAAtaA,tokenProgram: tokenProgramA,memoProgram: MEMO_PROGRAM_ADDRESS,});await client.sendTransaction([reclaimInstruction]);
Annullare o rifiutare
Cancel è firmata dall'autorità di regolamento e Reject da una qualsiasi delle parti. Entrambe rimborsano alla parte della leg tutto ciò che ogni escrow contiene e chiudono il record e entrambi gli escrow, con la rent degli account chiusi che va al firmatario. Le due istruzioni usano gli stessi account; cambia solo il firmatario.
import { getCancelDvpInstruction, getRejectDvpInstruction } from "./dvp";const unwindAccounts = {swapDvp,mintA,mintB,dvpAtaA: escrowA,dvpAtaB: escrowB,userAAtaA,userBAtaB,tokenProgramA,tokenProgramB,memoProgram: MEMO_PROGRAM_ADDRESS,legAExtrasCount: 0,};// Signed by the settlement authority:const cancelInstruction = getCancelDvpInstruction({settlementAuthority: authoritySigner,...unwindAccounts,});// Or signed by either party:const rejectInstruction = getRejectDvpInstruction({signer: userBSigner,...unwindAccounts,});
Gli account di rimborso (userAAtaA, userBAtaB) devono esistere per ogni leg che contiene
un saldo; un account di rimborso non inizializzato fa fallire il trasferimento di token e
annulla l'istruzione. Una leg mai finanziata non richiede alcun trasferimento e
tollera un account mancante.
Recuperare un deposito tardivo
Settle, Cancel e Reject chiudono entrambi i token account di escrow, quindi un semplice trasferimento verso un escrow chiuso fallisce. Un deposito arriva dopo la chiusura solo se qualcosa ricrea prima l'escrow, ad esempio una transazione di finanziamento che includa un'istruzione create-idempotent associated token account prima del trasferimento e che fosse in corso quando la controparte ha inviato Reject. I token restano quindi in un escrow il cui scambio non esiste più: il record non c'è più, quindi Reclaim non può trovarlo, e il tombstone del nonce impedisce di creare un nuovo scambio allo stesso indirizzo e di intercettare il deposito.
Per usare RecoverDvp, la parte della leg fornisce gli input originali del seed
(settlement authority, entrambe le parti, entrambi i mint, nonce). Il programma ricalcola
l'indirizzo del record, richiede il relativo tombstone come prova che lo scambio sia esistito, svuota
l'escrow nel token account del firmatario e lo chiude, restituendo la
rent dell'escrow al firmatario. La leg del firmatario è determinata da quale parte firma:
mint_a per user_a, mint_b per user_b.
import { getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";import { DVP_SWAP_PROGRAM_PROGRAM_ADDRESS, getRecoverDvpInstruction } from "./dvp";const [nonceTombstone] = await getProgramDerivedAddress({programAddress: DVP_SWAP_PROGRAM_PROGRAM_ADDRESS,seeds: ["nonce", getAddressEncoder().encode(swapDvp)],});const recoverInstruction = getRecoverDvpInstruction({signer: userASigner,swapDvp,nonceTombstone,mint: mintA,dvpEscrowAta: escrowA,signerDestAta: userAAtaA,tokenProgram: tokenProgramA,memoProgram: MEMO_PROGRAM_ADDRESS,settlementAuthority,userA,userB,mintA,mintB,nonce,});await client.sendTransaction([recoverInstruction]);
Il recupero dipende dal fatto che la parte conservi i parametri di creazione. Un sistema che finanzia gli scambi memorizza gli input del seed con ogni ordine finché lo scambio non è stato chiuso e i saldi degli escrow non sono stati confermati vuoti.
Note
- Leg congelate. Su un mint con restrizioni (gated), un escrow congelato blocca il trasferimento di token che queste istruzioni eseguono finché la freeze authority non lo sblocca. Vedi la panoramica.
- Modifiche al mint dopo la creazione. I percorsi di annullamento saltano i controlli sulle estensioni e sulla mint authority, così i controlli del programma non bloccano un recupero. Le regole del token program continuano comunque ad applicarsi. Un mint può essere chiuso solo con supply pari a zero, quindi non può cambiare mentre un saldo si trova in escrow, ma un mint chiuso e ricreato come NonTransferable o con una commissione di trasferimento prima dell'arrivo di un deposito tardivo può rendere quel deposito immovibile o soggetto a commissione. È la dipendenza dalla mint authority elencata in token supportati.
Prossimi passi
- Programma DvP: la panoramica, i token supportati e i vincoli di configurazione del mint
- Delivery vs Payment (DvP) con delega: lo stesso scambio tramite autorità delegata, senza un programma
Is this page helpful?