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.
| Instruction | Signataire | Portée | État du trade ensuite |
|---|---|---|---|
ReclaimDvp | user_a ou user_b | La leg du signataire | Toujours ouvert |
CancelDvp | Autorité de règlement | Les deux legs | Clôturé |
RejectDvp | user_a ou user_b | Les deux legs | Clôturé |
RecoverDvp | user_a ou user_b | La leg du signataire, après la clôture | Dé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
- Programme DvP : la vue d'ensemble, les tokens pris en charge et les contraintes de configuration du mint
- Delivery vs Payment (DvP) par délégation : le même échange via une autorité déléguée, sans programme
Is this page helpful?