Quatre instructions restituent les fonds sans règlement : Reclaim, Cancel et Reject tant que l'échange est ouvert, et Recover pour un dépôt qui arrive après sa clôture. Aucune ne vérifie l'expiration. Un escrow gelé ou un mint modifié peut encore bloquer un volet, comme le décrivent les notes en fin de page.
| Instruction | Signataire | Portée | État de l'échange ensuite |
|---|---|---|---|
ReclaimDvp | user_a ou user_b | Le volet du signataire | Toujours ouvert |
CancelDvp | Autorité de règlement | Les deux volets | Clôturé |
RejectDvp | user_a ou user_b | Les deux volets | Clôturé |
RecoverDvp | user_a ou user_b | Le volet du signataire, après la clôture | Déjà clôturé |
Dans chaque cas, l'escrow est vidé de son contenu au profit de la partie du volet :
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 financé. 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 issus de
la création d'un échange, userAAtaA et
userBAtaB issus de l'approvisionnement des volets, ainsi que
MEMO_PROGRAM_ID et authority issus du
règlement de l'échange sont repris.
Réclamer un volet
Reclaim restitue le volet du signataire et laisse l'échange ouvert, de sorte que le volet puisse être financé à nouveau. Utilisez-le lorsque le problème vient du volet de la contrepartie ; Cancel et Reject clôturent l'échange entier.
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 ou Reject
Cancel est signé par l'autorité de règlement et Reject par l'une ou l'autre des parties. Les deux restituent le contenu de chaque escrow à la partie du volet et ferment l'enregistrement et les deux escrows, la rent des comptes fermé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 tout volet qui contient
un solde ; un compte de remboursement non initialisé fait échouer le transfert de tokens et
annule l'instruction. Un volet qui n'a jamais été financé n'exige aucun transfert et
tolère un compte manquant.
Récupérer un dépôt tardif
Settle, Cancel et Reject ferment tous les deux token accounts d'escrow, si bien qu'un simple transfert vers un escrow fermé é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 de financement qui inclut une instruction create-idempotent d'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 l'échange n'existe plus : l'enregistrement a disparu, donc Reclaim ne peut pas le trouver, et la pierre tombale du nonce empêche la création d'un nouvel échange à la même adresse qui capterait le dépôt.
Pour utiliser RecoverDvp, la partie du volet fournit les entrées de seed d'origine
(autorité de règlement, les deux parties, les deux mints, nonce). Le programme redérive
l'adresse de l'enregistrement, exige sa pierre tombale comme preuve que l'échange a existé, vide
l'escrow vers le token account du signataire, puis le ferme, en restituant la
rent de l'escrow au signataire. Le volet du signataire est déterminé 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 finance des échanges stocke les entrées de seed avec chaque ordre jusqu'à la clôture de l'échange et la confirmation que les soldes des escrows sont vides.
Notes
- Volets gelés. Sur un mint soumis à restrictions, un escrow gelé bloque le transfert de tokens qu'effectuent ces instructions jusqu'à ce que l'autorité de gel le dégèle. Voir l'aperçu.
- Modifications du mint après la création. Les chemins d'annulation ignorent les vérifications d'extensions et d'autorité du mint afin que les vérifications 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 fermé qu'à offre nulle, il ne peut donc pas changer tant qu'un solde reste dans l'escrow, mais un mint fermé 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 à l'autorité du mint mentionnée dans les tokens pris en charge.
Étapes suivantes
- Programme DvP : l'aperçu, les tokens pris en charge et les contraintes de configuration du mint
- Livraison contre paiement (DvP) par délégation : le même échange via une autorité déléguée, sans programme
Is this page helpful?