Bir İşlemi Geri Alma

Dört talimat, takas gerçekleştirmeden fonları iade eder: işlem açıkken Reclaim, Cancel ve Reject; işlem kapandıktan sonra gelen bir depozito için ise Recover. Hiçbiri son kullanma süresini kontrol etmez. Dondurulmuş bir escrow veya değişmiş bir mint, sondaki notlarda açıklandığı gibi yine de bir bacağı tutabilir.

TalimatİmzalayanKapsamSonrasında işlem
ReclaimDvpuser_a veya user_bİmzalayanın kendi bacağıHâlâ açık
CancelDvpTakas yetkilisiHer iki bacakKapalı
RejectDvpuser_a veya user_bHer iki bacakKapalı
RecoverDvpuser_a veya user_bİmzalayanın bacağı, kapanıştan sonraZaten kapalı

Her durumda escrow, içinde ne varsa bacağın tarafına boşaltılır: escrow A, user_a'nın mint_a için token account'ına; escrow B ise user_b'nin mint_b için token account'ına, kimin fonladığına bakılmaksızın. Memo gerektiren iade hesapları için memo program account sağlanır.

Bu sayfa önceki adımların devamıdır: işlem oluşturma adımındaki client ve imzalayanlar, bacakları fonlama adımındaki userAAtaA ve userBAtaB, işlemi sonuçlandırma adımındaki MEMO_PROGRAM_ID ve authority aynen kullanılır.

Bir bacağı geri çekme

Reclaim, imzalayanın bacağını iade eder ve işlemi açık bırakır; böylece bacak yeniden fonlanabilir. Sorun karşı tarafın bacağında olduğunda kullanın; Cancel ve Reject ise tüm işlemi kapatır.

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

İptal etme veya reddetme

Cancel takas yetkilisi tarafından, Reject ise taraflardan biri tarafından imzalanır. İkisi de her escrow'da bulunanı bacağın tarafına iade eder, kaydı ve her iki escrow'u kapatır; kapatılan hesapların rent'i imzalayana gider. İki talimat aynı hesapları alır; yalnızca imzalayan farklıdır.

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

İade hesapları (userAAtaA, userBAtaB), bakiyesi olan her bacak için mevcut olmalıdır; başlatılmamış bir iade hesabı token transferinin başarısız olmasına ve talimatın geri alınmasına yol açar. Hiç fonlanmamış bir bacak için transfer gerekmez ve eksik hesap sorun yaratmaz.

Geç gelen bir depozitoyu kurtarma

Settle, Cancel ve Reject, her iki escrow token account'ını da kapatır; bu nedenle kapalı bir escrow'a yapılan düz transfer başarısız olur. Kapanıştan sonra bir depozito ancak bir şey escrow'u önceden yeniden oluşturursa gerçekleşir; örneğin transferden önce create-idempotent associated token account talimatı içeren ve karşı taraf Reject gönderdiğinde henüz yoldaki bir fonlama işlemi. Bu durumda token'lar, işlemi artık var olmayan bir escrow'da kalır: kayıt silinmiştir, dolayısıyla Reclaim onu bulamaz; nonce tombstone'u ise aynı adreste yeni bir işlem oluşturulup depozitonun ele geçirilmesini engeller.

RecoverDvp kullanmak için bacağın tarafı özgün seed girdilerini (takas yetkilisi, her iki taraf, her iki mint, nonce) sağlar. Program kayıt adresini yeniden türetir, işlemin var olduğunun kanıtı olarak tombstone'unu şart koşar, escrow'u imzalayanın kendi token account'ına boşaltır ve kapatır; escrow rent'i imzalayana iade edilir. İmzalayanın bacağı, hangi tarafın imzaladığına göre seçilir: user_a için mint_a, user_b için mint_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]);

Kurtarma, tarafın oluşturma parametrelerini saklamasına bağlıdır. İşlemleri fonlayan bir sistem, işlem kapanana ve escrow bakiyelerinin boş olduğu doğrulanana kadar seed girdilerini her emirle birlikte saklar.

Notlar

  • Dondurulmuş bacaklar. Kapılı (gated) bir mint'te dondurulmuş bir escrow, freeze authority onu çözene kadar bu talimatların gerçekleştirdiği token transferini engeller. Bkz. genel bakış.
  • Oluşturulduktan sonra mint değişiklikleri. Geri alma yolları, programın kendi kontrollerinin kurtarmayı engellememesi için extension ve mint-authority kontrollerini atlar. Token Program'ın kendi kuralları yine de geçerlidir. Bir mint yalnızca arz sıfırken kapatılabilir; dolayısıyla escrow'da bakiye dururken değişemez, ancak geç bir depozito gelmeden önce kapatılıp NonTransferable olarak veya transfer ücretiyle yeniden oluşturulan bir mint, o depozitoyu taşınamaz veya ücretli hale getirebilir. Bu, desteklenen token'lar altında listelenen mint-authority bağımlılığıdır.

Sonraki adımlar

Is this page helpful?

İçindekiler

Sayfayı Düzenle
© 2026 Solana Vakfı. Tüm hakları saklıdır.