SettleDvp ditandatangani oleh otoritas penyelesaian yang tercantum dalam catatan trade. Dalam
satu transaksi, instruksi ini memindahkan amount_a dari leg aset ke tujuan
pihak leg kas dan amount_b dari leg kas ke tujuan pihak leg aset,
mengembalikan kelebihan dana di escrow mana pun kepada pihak dari leg tersebut, lalu menutup catatan
dan kedua escrow. Jika salah satu transfer tersebut tidak dapat diselesaikan, instruksi
gagal dan tidak ada yang berpindah.
Halaman ini melanjutkan dari membuat trade
dan mendanai leg; klien, penanda tangan,
trade, dan token account milik para pihak tetap digunakan.
Validasi ulang sebelum menandatangani
Otoritas penyelesaian menandatangani transaksi yang memindahkan kedua leg, sehingga ia melakukan pembacaan yang sama seperti setiap pihak sebelum menandatangani: pemilik, ukuran, pihak, mint, jumlah, masa berlaku, dan kedua tujuan (lihat mendanai leg). Program itu sendiri memeriksa ulang saat penyelesaian bahwa setiap mint masih termasuk dalam token program yang dicatat saat pembuatan, tidak membawa ekstensi yang diblokir, dan memiliki mint authority yang sama seperti saat trade dibuat, sehingga mint yang dibuat ulang dengan ekstensi yang diblokir, token program yang berbeda, atau mint authority yang berbeda tidak dapat diselesaikan.
Membuat akun penerima
Settle menulis ke empat token account yang tidak dibuat oleh program:
| Akun | Menerima | Pemilik |
|---|---|---|
userADestinationAtaB | Leg kas (amount_b) | user_a_settlement_destination |
userBDestinationAtaA | Leg aset (amount_a) | user_b_settlement_destination |
userAAtaA | Kelebihan dana pada leg aset | user_a |
userBAtaB | Kelebihan dana pada leg kas | user_b |
Akun kelebihan dana hanya digunakan ketika escrow menyimpan lebih dari jumlah yang disepakati, tetapi siapa pun yang memegang mint dapat menciptakan kelebihan dengan mengirim beberapa unit dasar ke escrow. Jika akun pengembalian dana tidak ada, seluruh Settle gagal, jadi buat keempatnya secara idempoten dalam transaksi yang sama.
import {findAssociatedTokenPda,getCreateAssociatedTokenIdempotentInstruction,} from "@solana-program/token-2022";const destinationA = t.userASettlementDestination; // defaults to userAconst destinationB = t.userBSettlementDestination; // defaults to userBconst [userADestinationAtaB] = await findAssociatedTokenPda({mint: mintB,owner: destinationA,tokenProgram: tokenProgramB,});const [userBDestinationAtaA] = await findAssociatedTokenPda({mint: mintA,owner: destinationB,tokenProgram: tokenProgramA,});// userAAtaA and userBAtaB are from fund the legs.const createRecipientAccounts = [{ ata: userADestinationAtaB, owner: destinationA, mint: mintB, tokenProgram: tokenProgramB },{ ata: userBDestinationAtaA, owner: destinationB, mint: mintA, tokenProgram: tokenProgramA },{ ata: userAAtaA, owner: userA, mint: mintA, tokenProgram: tokenProgramA },{ ata: userBAtaB, owner: userB, mint: mintB, tokenProgram: tokenProgramB },].map(({ ata, owner, mint, tokenProgram }) =>getCreateAssociatedTokenIdempotentInstruction({payer: authoritySigner,ata,owner,mint,tokenProgram,}),);
Settle
legAExtrasCount memberi tahu program berapa banyak akun yang ditambahkan setelah
daftar tetap yang termasuk dalam transfer hook leg aset; sisanya masuk ke
leg kas. Untuk mint tanpa transfer hook, berikan nol dan jangan tambahkan apa pun. Program account
memo diwajibkan oleh instruksi dan hanya digunakan untuk tujuan
yang memerlukan memo.
import { MEMO_PROGRAM_ADDRESS } from "@solana-program/memo";import { getSettleDvpInstruction } from "./dvp";const settleInstruction = getSettleDvpInstruction({settlementAuthority: authoritySigner,swapDvp,mintA,mintB,dvpAtaA: escrowA,dvpAtaB: escrowB,userADestinationAtaB,userBDestinationAtaA,userAAtaA,userBAtaB,tokenProgramA,tokenProgramB,memoProgram: MEMO_PROGRAM_ADDRESS,legAExtrasCount: 0,});const { context: settleContext } = await client.sendTransaction([...createRecipientAccounts,settleInstruction,]);const settleSignature = settleContext.signature;console.log("Submitted:", settleSignature);// sendTransaction returns at the client's commitment (confirmed by default).// Wait for finalized before recording the trade as settled.let finalized = false;for (let attempt = 0; attempt < 30 && !finalized; attempt++) {const {value: [status],} = await client.rpc.getSignatureStatuses([settleSignature]).send();if (status?.err) {throw new Error("Settle transaction failed");}finalized = status?.confirmationStatus === "finalized";if (!finalized) {await new Promise((resolve) => setTimeout(resolve, 2_000));}}if (!finalized) {// A closed record means it settled; an open one is safe to settle again.throw new Error("Settle not finalized after 60s; read the trade record");}console.log("Settled:", settleSignature);
Transfer hook
IDL yang dihasilkan hanya mencantumkan akun tetap, sehingga builder yang dihasilkan tidak
mengetahui akun hook. Resolusikan extra account meta dari setiap hook mint dengan
cara yang sama seperti untuk transfer langsung token tersebut, lalu tambahkan ke
instruksi: akun leg aset terlebih dahulu, kemudian leg kas, dengan
legAExtrasCount diatur ke jumlah pada kelompok pertama. Di TypeScript, sebarkan (spread)
meta yang telah diresolusi ke array accounts milik instruksi; di Rust, gunakan
add_remaining_accounts pada builder. Batasnya adalah 32 akun per leg,
termasuk program hook dan akun validasi; batas akun transaksi
dapat tercapai lebih dulu ketika kedua leg membawa hook. Program menghapus flag signer
dari setiap akun yang diteruskan, sehingga hook tidak dapat memperoleh
tanda tangan otoritas penyelesaian melalui jalur ini.
Mencatat hasil
Anggap trade telah selesai ketika transaksi Settle mencapai finalized. Catatan
dan kedua escrow tidak lagi ada setelah penyelesaian, sehingga sistem yang membutuhkan
ketentuannya di kemudian hari menyimpannya dari pembacaan sebelum penyelesaian atau dari transaksi
pembuatan. rent dari akun yang ditutup telah diberikan kepada otoritas
penyelesaian.
Error Settle
LegNotFunded berarti escrow menyimpan kurang dari jumlah yang disepakati; DvpExpired
dan SettlementTooEarly berarti jendela waktu terlewat; MintAuthorityChanged
dan BlockedMintExtension berarti mint berubah setelah pembuatan;
RecipientAtaMismatch berarti token account tujuan atau pengembalian dana tidak ada atau
tidak lagi dimiliki oleh pemilik dan mint yang diharapkan, biasanya karena langkah
pembuatan akun di atas dilewati. Dalam setiap kasus, tidak ada yang berpindah, dan
para pihak dapat membatalkan, tergantung pada otoritas mint (lihat
membatalkan trade).
Langkah berikutnya
- Membatalkan trade: memulihkan leg yang sudah didanai ketika trade tidak diselesaikan
Is this page helpful?