Hoàn tác một giao dịch

Bốn instruction hoàn trả tiền mà không tất toán: Reclaim, Cancel và Reject khi giao dịch còn mở, và Recover cho khoản nạp đến sau khi giao dịch đã đóng. Không instruction nào kiểm tra thời hạn hết hạn. Một escrow bị đóng băng hoặc một mint bị thay đổi vẫn có thể giữ lại một leg, như các lưu ý ở cuối trang mô tả.

InstructionNgười kýPhạm viGiao dịch sau đó
ReclaimDvpuser_a hoặc user_bLeg của chính người kýVẫn mở
CancelDvpsettlement authorityCả hai legĐã đóng
RejectDvpuser_a hoặc user_bCả hai legĐã đóng
RecoverDvpuser_a hoặc user_bLeg của người ký, sau khi đóngĐã đóng từ trước

Trong mọi trường hợp, escrow được rút toàn bộ số dư đang giữ về cho bên sở hữu leg: escrow A về token account của user_a cho mint_a, escrow B về token account của user_b cho mint_b, bất kể ai đã nạp tiền vào. program account memo được cung cấp cho các tài khoản hoàn tiền yêu cầu memo.

Trang này tiếp nối các bước trước: client và các signer từ tạo giao dịch, userAAtaA và userBAtaB từ nạp vốn cho các leg, cũng như MEMO_PROGRAM_ID và authority từ tất toán giao dịch được dùng tiếp ở đây.

Rút lại một leg

Reclaim hoàn trả leg của người ký và giữ giao dịch ở trạng thái mở, nên leg đó có thể được nạp lại. Hãy dùng khi vấn đề nằm ở leg của đối tác; Cancel và Reject sẽ đóng toàn bộ giao dịch.

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 hoặc Reject

Cancel do settlement authority ký còn Reject do một trong hai bên ký. Cả hai đều hoàn trả số dư mỗi escrow đang giữ về cho bên sở hữu leg, đồng thời đóng bản ghi và cả hai escrow, với rent của các tài khoản bị đóng được chuyển cho người ký. Hai instruction này nhận cùng các tài khoản; chỉ khác người ký.

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

Các tài khoản hoàn tiền (userAAtaA, userBAtaB) phải tồn tại đối với mọi leg đang có số dư; nếu tài khoản hoàn tiền chưa được khởi tạo, việc chuyển token sẽ thất bại và instruction bị hoàn nguyên. Một leg chưa từng được nạp tiền thì không cần chuyển và vẫn chấp nhận việc thiếu tài khoản.

Thu hồi khoản nạp đến muộn

Settle, Cancel và Reject đều đóng cả hai token account của escrow, nên một lệnh chuyển thông thường vào escrow đã đóng sẽ thất bại. Khoản nạp chỉ có thể đến sau khi đóng nếu escrow được tạo lại trước, ví dụ một giao dịch nạp tiền có bao gồm instruction create-idempotent associated token account đặt trước lệnh chuyển và đang được xử lý khi đối tác gửi Reject. Khi đó các token nằm trong một escrow mà giao dịch của nó không còn tồn tại: bản ghi đã mất nên Reclaim không thể tìm thấy, và nonce tombstone ngăn việc tạo giao dịch mới tại cùng địa chỉ để chiếm lấy khoản nạp.

Để dùng RecoverDvp, bên sở hữu leg cung cấp các đầu vào seed ban đầu (settlement authority, hai bên, hai mint, nonce). Chương trình suy ra lại địa chỉ bản ghi, yêu cầu tombstone của nó làm bằng chứng giao dịch từng tồn tại, rút toàn bộ escrow về token account của chính người ký rồi đóng escrow, trả rent của escrow cho người ký. Leg của người ký được xác định theo bên nào ký: mint_a cho user_a, mint_b cho 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]);

Việc thu hồi phụ thuộc vào việc bên sở hữu giữ lại các tham số tạo giao dịch. Một hệ thống nạp tiền cho các giao dịch sẽ lưu các đầu vào seed cùng với mỗi lệnh cho đến khi giao dịch đã đóng và số dư escrow đã được xác nhận là trống.

Lưu ý

  • Leg bị đóng băng. Trên một mint có kiểm soát (gated), escrow bị đóng băng sẽ chặn việc chuyển token mà các instruction này thực hiện cho đến khi freeze authority mở băng. Xem tổng quan.
  • Mint thay đổi sau khi tạo. Các luồng hoàn tác bỏ qua việc kiểm tra extension và mint authority để các kiểm tra của chương trình không chặn việc thu hồi. Các quy tắc của token program vẫn được áp dụng. Một mint chỉ có thể bị đóng khi nguồn cung bằng không, nên nó không thể thay đổi khi còn số dư trong escrow, nhưng nếu một mint được đóng và tạo lại dưới dạng NonTransferable hoặc có phí chuyển trước khi khoản nạp đến muộn xuất hiện, khoản nạp đó có thể không thể di chuyển hoặc bị tính phí. Đó là sự phụ thuộc vào mint authority được liệt kê trong phần token được hỗ trợ.

Các bước tiếp theo

Is this page helpful?

Mục lục

Chỉnh sửa trang