Cuatro instrucciones devuelven fondos sin liquidar: Reclaim, Cancel y Reject mientras la operación está abierta, y Recover para un depósito que llega después de que se haya cerrado. Ninguna de ellas comprueba la expiración. Un escrow congelado o un mint modificado pueden seguir reteniendo un tramo, como describen las notas del final.
| Instrucción | Firmante | Alcance | Operación después |
|---|---|---|---|
ReclaimDvp | user_a o user_b | El tramo del propio firmante | Sigue abierta |
CancelDvp | Autoridad de liquidación | Ambos tramos | Cerrada |
RejectDvp | user_a o user_b | Ambos tramos | Cerrada |
RecoverDvp | user_a o user_b | El tramo del firmante, tras el cierre | Ya cerrada |
En cada caso, el escrow se vacía y todo lo que contiene se envía a la parte del tramo:
el escrow A a la token account de user_a para mint_a, el escrow B a la de user_b para
mint_b, sea quien sea quien lo haya financiado. Se proporciona la program account de memo
para las cuentas de reembolso que requieren un memo.
Esta página continúa a partir de los pasos anteriores: el cliente y los firmantes de
crear una operación, userAAtaA y
userBAtaB de financiar los tramos, y
MEMO_PROGRAM_ID y authority de
liquidar la operación se reutilizan.
Reclamar un tramo
Reclaim devuelve el tramo del firmante y deja la operación abierta, de modo que el tramo pueda financiarse de nuevo. Úsalo cuando el problema esté en el tramo de la contraparte; Cancel y Reject cierran la operación completa.
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]);
Cancelar o rechazar
Cancel lo firma la autoridad de liquidación y Reject cualquiera de las partes. Ambas devuelven lo que contenga cada escrow a la parte de su tramo y cierran el registro y los dos escrows, y la rent de las cuentas cerradas va al firmante. Las dos instrucciones reciben las mismas cuentas; solo cambia el firmante.
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,});
Las cuentas de reembolso (userAAtaA, userBAtaB) deben existir para cualquier tramo que tenga
saldo; una cuenta de reembolso sin inicializar hace que la transferencia de tokens falle y
revierte la instrucción. Un tramo que nunca se financió no necesita transferencia y
tolera que falte la cuenta.
Recuperar un depósito tardío
Settle, Cancel y Reject cierran ambas token accounts de escrow, por lo que una transferencia simple a un escrow cerrado falla. Un depósito solo llega después del cierre si algo recrea antes el escrow, por ejemplo una transacción de financiación que incluya una instrucción idempotente de creación de associated token account antes de la transferencia y que estuviera en curso cuando la contraparte envió Reject. Los tokens quedan entonces en un escrow cuya operación ya no existe: el registro ha desaparecido, así que Reclaim no puede encontrarlo, y el tombstone del nonce impide que se cree una nueva operación en la misma dirección y capture el depósito.
Para usar RecoverDvp, la parte del tramo proporciona los datos originales de los seed
(autoridad de liquidación, ambas partes, ambos mints, nonce). El programa vuelve a derivar
la dirección del registro, exige su tombstone como prueba de que la operación existió, vacía
el escrow hacia la token account del propio firmante y lo cierra, devolviendo la
rent del escrow al firmante. El tramo del firmante se elige según qué parte firma:
mint_a para user_a, mint_b para 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 recuperación depende de que la parte conserve los parámetros de creación. Un sistema que financia operaciones almacena los datos de los seed con cada orden hasta que la operación se haya cerrado y se haya confirmado que los saldos de los escrows están vacíos.
Notas
- Tramos congelados. En un mint con restricciones, un escrow congelado bloquea la transferencia de tokens que realizan estas instrucciones hasta que la autoridad de congelación lo descongele. Consulta la descripción general.
- Cambios en el mint tras la creación. Las rutas de deshacer omiten las comprobaciones de extensiones y de autoridad del mint para que las propias comprobaciones del programa no bloqueen una recuperación. Las reglas propias del token program siguen aplicándose. Un mint solo puede cerrarse con suministro cero, por lo que no puede cambiar mientras haya saldo en el escrow, pero un mint cerrado y recreado como NonTransferable o con una comisión de transferencia antes de que llegue un depósito tardío puede dejar ese depósito inmovible o sujeto a comisión. Esa es la dependencia de la autoridad del mint indicada en tokens compatibles.
Próximos pasos
- Programa DvP: la descripción general, los tokens compatibles y las restricciones de configuración del mint
- Entrega contra pago (DvP) mediante delegación: el mismo intercambio mediante autoridad delegada, sin un programa
Is this page helpful?