Cofnięcie transakcji

Cztery instrukcje zwracają środki bez rozliczenia: Reclaim, Cancel i Reject, gdy transakcja jest otwarta, oraz Recover dla depozytu, który wpłynął po jej zamknięciu. Żadna z nich nie sprawdza terminu ważności. Zamrożony escrow lub zmieniony mint nadal może zablokować nogę, jak opisano w uwagach na końcu.

InstrukcjaPodpisującyZakresTransakcja po wykonaniu
ReclaimDvpuser_a lub user_bWłasna noga podpisującegoNadal otwarta
CancelDvpAutorytet rozliczeniowyObie nogiZamknięta
RejectDvpuser_a lub user_bObie nogiZamknięta
RecoverDvpuser_a lub user_bNoga podpisującego, po zamknięciuJuż zamknięta

W każdym przypadku z escrow zostaje wypłacone wszystko, co zawiera, na rzecz strony danej nogi: escrow A trafia na token account użytkownika user_a dla mint_a, a escrow B na token account użytkownika user_b dla mint_b, niezależnie od tego, kto go zasilił. Memo program account jest przekazywany dla kont zwrotu, które wymagają memo.

Ta strona jest kontynuacją wcześniejszych kroków: klient i podpisujący z tworzenia transakcji, userAAtaA i userBAtaB z zasilania nóg oraz MEMO_PROGRAM_ID i authority z rozliczania transakcji są przenoszone dalej.

Odzyskanie nogi

Reclaim zwraca nogę podpisującego i pozostawia transakcję otwartą, dzięki czemu nogę można zasilić ponownie. Użyj go, gdy problem dotyczy nogi kontrahenta; Cancel i Reject zamykają całą transakcję.

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

Anulowanie lub odrzucenie

Cancel jest podpisywany przez autorytet rozliczeniowy, a Reject przez dowolną ze stron. Obie instrukcje zwracają stronie danej nogi wszystko, co zawiera odpowiedni escrow, oraz zamykają rekord i oba escrow, a rent z zamkniętych kont trafia do podpisującego. Obie instrukcje przyjmują te same konta; różni się tylko podpisujący.

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

Konta zwrotu (userAAtaA, userBAtaB) muszą istnieć dla każdej nogi, która zawiera saldo; niezainicjowane konto zwrotu powoduje niepowodzenie transferu tokenów i cofnięcie instrukcji. Noga, która nigdy nie została zasilona, nie wymaga transferu i toleruje brakujące konto.

Odzyskanie spóźnionego depozytu

Settle, Cancel i Reject zamykają oba escrow token account, więc zwykły transfer do zamkniętego escrow kończy się niepowodzeniem. Depozyt może wpłynąć po zamknięciu tylko wtedy, gdy coś najpierw odtworzy escrow, na przykład transakcja zasilająca, która przed transferem zawiera instrukcję create-idempotent associated token account i była w trakcie przetwarzania, gdy kontrahent wysłał Reject. Tokeny trafiają wtedy do escrow, którego transakcja już nie istnieje: rekord zniknął, więc Reclaim nie może go znaleźć, a tombstone nonce'a uniemożliwia utworzenie nowej transakcji pod tym samym adresem i przechwycenie depozytu.

Aby użyć RecoverDvp, strona danej nogi podaje oryginalne dane wejściowe seed (autorytet rozliczeniowy, obie strony, oba mint, nonce). Program ponownie wyprowadza adres rekordu, wymaga jego tombstone jako dowodu istnienia transakcji, opróżnia escrow na własny token account podpisującego i zamyka go, zwracając rent z escrow podpisującemu. Noga podpisującego jest wybierana przez to, która strona podpisuje: mint_a dla user_a, mint_b dla 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]);

Odzyskanie zależy od tego, czy strona zachowa parametry utworzenia. System, który zasila transakcje, przechowuje dane wejściowe seed przy każdym zleceniu do momentu zamknięcia transakcji i potwierdzenia, że salda escrow są puste.

Uwagi

  • Zamrożone nogi. W przypadku mint z ograniczeniami zamrożony escrow blokuje transfer tokenów wykonywany przez te instrukcje, dopóki freeze authority go nie odmrozi. Zobacz przegląd.
  • Zmiany mint po utworzeniu. Ścieżki cofania pomijają kontrole rozszerzeń i mint authority, aby kontrole samego programu nie blokowały odzyskania. Nadal obowiązują reguły samego Token Program. Mint można zamknąć tylko przy zerowej podaży, więc nie może się zmienić, gdy w escrow znajduje się saldo, ale mint zamknięty i odtworzony jako NonTransferable lub z opłatą za transfer, zanim wpłynie spóźniony depozyt, może sprawić, że tego depozytu nie będzie można przenieść lub będzie obciążony opłatą. To zależność od mint authority wymieniona w sekcji obsługiwane tokeny.

Kolejne kroki

Is this page helpful?

Spis treści

Edytuj stronę