Dénouer un trade

Quatre instructions restituent les fonds sans règlement : Reclaim, Cancel et Reject tant que le trade est ouvert, et Recover pour un dépôt arrivé après sa clôture. Aucune d'elles ne vérifie l'expiration. Un escrow gelé ou un mint modifié peut quand même bloquer une leg, comme le décrivent les notes en fin de page.

InstructionSignatairePortéeÉtat du trade ensuite
ReclaimDvpuser_a ou user_bLa leg du signataireToujours ouvert
CancelDvpAutorité de règlementLes deux legsClôturé
RejectDvpuser_a ou user_bLes deux legsClôturé
RecoverDvpuser_a ou user_bLa leg du signataire, après la clôtureDéjà clôturé

Dans chaque cas, l'escrow est vidé de tout ce qu'il contient au profit de la partie de la leg : l'escrow A vers le token account de user_a pour mint_a, l'escrow B vers celui de user_b pour mint_b, quel que soit celui qui l'a alimenté. Le program account Memo est fourni pour les comptes de remboursement qui exigent un mémo.

Cette page fait suite aux étapes précédentes : le client et les signataires de création d'un trade, userAAtaA et userBAtaB de l'alimentation des legs, ainsi que MEMO_PROGRAM_ID et authority du règlement du trade, sont repris tels quels.

Reprendre une leg

Reclaim restitue la leg du signataire et laisse le trade ouvert, de sorte que la leg puisse être alimentée à nouveau. Utilisez-la lorsque le problème vient de la leg de la contrepartie ; Cancel et Reject clôturent l'ensemble du trade.

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]);

Annuler ou rejeter

Cancel est signé par l'autorité de règlement et Reject par l'une ou l'autre des parties. Les deux restituent à la partie de chaque leg ce que contient son escrow, puis clôturent l'enregistrement et les deux escrows, le rent des comptes clôturés revenant au signataire. Les deux instructions prennent les mêmes comptes ; seul le signataire diffère.

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,
});

Les comptes de remboursement (userAAtaA, userBAtaB) doivent exister pour toute leg qui détient un solde ; un compte de remboursement non initialisé fait échouer le transfert de tokens et annule l'instruction. Une leg qui n'a jamais été alimentée n'a besoin d'aucun transfert et tolère l'absence de compte.

Récupérer un dépôt tardif

Settle, Cancel et Reject clôturent tous deux les token accounts d'escrow, de sorte qu'un simple transfert vers un escrow clôturé échoue. Un dépôt n'arrive après la clôture que si quelque chose recrée d'abord l'escrow, par exemple une transaction d'alimentation qui inclut une instruction create-idempotent associated token account avant le transfert et qui était en cours lorsque la contrepartie a envoyé Reject. Les tokens se trouvent alors dans un escrow dont le trade n'existe plus : l'enregistrement a disparu, donc Reclaim ne peut pas le trouver, et la tombstone du nonce empêche qu'un nouveau trade soit créé à la même adresse et s'approprie le dépôt.

Pour utiliser RecoverDvp, la partie de la leg fournit les entrées d'origine du seed (autorité de règlement, les deux parties, les deux mints, nonce). Le programme dérive à nouveau l'adresse de l'enregistrement, exige sa tombstone comme preuve de l'existence du trade, vide l'escrow vers le token account du signataire, puis le clôture, en restituant le rent de l'escrow au signataire. La leg du signataire est déterminée par la partie qui signe : mint_a pour user_a, mint_b pour 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]);

La récupération dépend du fait que la partie conserve les paramètres de création. Un système qui alimente des trades stocke les entrées du seed avec chaque ordre jusqu'à la clôture du trade et la confirmation que les soldes des escrows sont vides.

Notes

  • Legs gelées. Sur un mint à accès contrôlé, un escrow gelé bloque le transfert de tokens qu'effectuent ces instructions jusqu'à ce que l'autorité de gel le dégèle. Voir la vue d'ensemble.
  • Modifications du mint après la création. Les chemins de dénouement ignorent les vérifications des extensions et de la mint authority afin que les contrôles propres au programme ne bloquent pas une récupération. Les règles propres au token program continuent de s'appliquer. Un mint ne peut être clôturé qu'à offre nulle, il ne peut donc pas changer tant qu'un solde se trouve dans l'escrow, mais un mint clôturé puis recréé en NonTransferable ou avec des frais de transfert avant l'arrivée d'un dépôt tardif peut rendre ce dépôt impossible à déplacer ou soumis à des frais. C'est la dépendance à la mint authority indiquée dans les tokens pris en charge.

Étapes suivantes

Is this page helpful?

Table des matières

Modifier la page
© 2026 Fondation Solana. Tous droits réservés.