Annullare uno scambio

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 verifica la scadenza. Un escrow congelato o un mint modificato possono comunque bloccare una leg, come descritto nelle note finali.

IstruzioneFirmatarioAmbitoStato successivo dello scambio
ReclaimDvpuser_a o user_bLa leg del firmatarioAncora aperto
CancelDvpAuthority di regolamentoEntrambe le legChiuso
RejectDvpuser_a o user_bEntrambe le legChiuso
RecoverDvpuser_a o user_bLa leg del firmatario, dopo la chiusuraGià 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 abbia 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 creare uno scambio, userAAtaA e userBAtaB di finanziare le leg, e MEMO_PROGRAM_ID e authority di regolare lo scambio restano validi.

Recuperare una leg con Reclaim

Reclaim restituisce la leg del firmatario e lascia lo scambio aperto, 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]);

Cancel o Reject

Cancel viene firmato dalla settlement authority e Reject da una qualsiasi delle due parti. Entrambi rimborsano quanto contenuto in ciascun escrow alla parte della leg e chiudono il record e entrambi gli escrow, con il rent degli account chiusi che va al firmatario. Le due istruzioni richiedono 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 contenga un saldo; un account di rimborso non inizializzato fa fallire il trasferimento dei token e annulla l'istruzione. Una leg che non è mai stata 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 a destinazione dopo la chiusura solo se qualcosa ricrea prima l'escrow, ad esempio una transazione di finanziamento che includa un'istruzione create-idempotent per l'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 riesce a trovarlo, e il tombstone del nonce impedisce che un nuovo scambio venga creato allo stesso indirizzo e si appropri del 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 verso il token account del firmatario e lo chiude, restituendo il rent dell'escrow al firmatario. La leg del firmatario viene scelta in base alla parte che 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 insieme a ciascun ordine fino alla chiusura dello scambio e alla conferma che i saldi degli escrow sono vuoti.

Note

  • Leg congelate. Su un mint con restrizioni, un escrow congelato blocca il trasferimento dei token eseguito da queste istruzioni finché la freeze authority non lo sblocca. Consulta la panoramica.
  • Modifiche al mint dopo la creazione. I percorsi di annullamento saltano i controlli sulle estensioni e sulla mint authority, in modo che i controlli del programma stesso non blocchino 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 nell'escrow, ma un mint chiuso e ricreato come NonTransferable o con una commissione di trasferimento prima che un deposito tardivo arrivi può rendere quel deposito non spostabile o soggetto a commissioni. È la dipendenza dalla mint authority elencata in token supportati.

Prossimi passi

Is this page helpful?

Indice dei contenuti

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