CreateDvp, bir takasın koşullarını kaydeder ve tarafların fonlayacağı iki escrow
hesabını oluşturur. Hiçbir token taşımaz. Herkes gönderebilir; dolayısıyla kayıt bir
karşı taraftan, yerleşim yetkilisinin operatöründen ya da üçüncü bir taraftan
gelebilir ve diğer tüm katılımcılar, saklanan koşullara dayanarak işlem yapmadan önce
bu koşulları doğrular (bkz. bacakları fonlayın).
Kod parçacıkları, ilgili hesapların ve imzalayanların görülebilmesi için yer tutucu adreslerle birlikte doğrudan oluşturulmuş (generated) istemciyi kullanır. Hedef ağ devnet'tir; program burada mainnet-beta ile aynı adreste dağıtılmıştır.
Kurulum
2 Ekim 2026 itibarıyla DvP istemcileri için yayımlanmış bir paket yoktur. İkisi de depodaki programın IDL'inden üretilir ve kaynaktan kullanılır.
git clone https://github.com/solana-foundation/dvp.gitcd dvp && git checkout df9919ed02c25a93620e7f6820107c9050ce3b92pnpm install && pnpm generate-clients && pnpm build# The client is clients/typescript/src; copy or link it into your project as ./dvppnpm add @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token-2022 @solana-program/memo
Bu sayfalar df9919e commit'ine göre yazılmıştır; TypeScript'te @solana/kit 8,
Rust'ta ise solana-* 2.x crate'leri kullanılır.
Her adım sayfasındaki kod parçacıkları birbirinin devamıdır: her sayfa, önceki
sayfalarda tanımlanan istemciyi, imzalayanları ve adresleri kullanır. payerSigner,
userASigner, userBSigner ve authoritySigner, sırasıyla rent ödeyicisi, iki taraf
ve yerleşim yetkilisi için TransactionSigner nesneleridir; örneğin
createKeyPairSignerFromBytes ile elde edilebilirler. Rust kod parçacıkları
talimatları oluşturur; imzalama ve göndermeyi çağıran tarafa bırakır.
Adresleri türetme
Takas kaydı; yerleşim yetkilisi, iki taraf, iki mint ve bir nonce üzerinden türetilen bir program-derived address'tir. Her escrow, kaydın mint'lerden biri için kullanılan associated token account'udur. Her iki türetme de ağ erişimi gerektirmez.
Her takas için rastgele 64 bitlik bir nonce kullanın. Oluşturma işlemi izne tabi
olmadığından, tahmin edilebilir bir nonce üçüncü bir tarafın takasın kullanacağı
adresi işgal etmesine yol açabilir. TypeScript'te nonce'u ve tutarları bigint
olarak geçirin; oluşturulmuş istemci number değerini reddeder.
Çalıştırmadan önce her ..._HERE yer tutucusunu gerçek bir adresle değiştirin.
address() base58'i doğrular ve yer tutucuda hata fırlatır; pubkey! ise derlenmez.
import { address, createClient } from "@solana/kit";import { solanaRpc } from "@solana/kit-plugin-rpc";import { signer } from "@solana/kit-plugin-signer";import { TOKEN_2022_PROGRAM_ADDRESS } from "@solana-program/token-2022";import { findSwapDvpEscrowAta, findSwapDvpPda } from "./dvp";const client = createClient().use(signer(payerSigner)).use(solanaRpc({rpcUrl: "https://api.devnet.solana.com",rpcSubscriptionsUrl: "wss://api.devnet.solana.com",}),);const settlementAuthority = address("SETTLEMENT_AUTHORITY_ADDRESS_HERE");const userA = address("ASSET_LEG_PARTY_ADDRESS_HERE");const userB = address("CASH_LEG_PARTY_ADDRESS_HERE");const mintA = address("ASSET_MINT_ADDRESS_HERE");const mintB = address("CASH_MINT_ADDRESS_HERE");const tokenProgramA = TOKEN_2022_PROGRAM_ADDRESS;const tokenProgramB = TOKEN_2022_PROGRAM_ADDRESS;// A fresh random nonce per trade, as a bigint.const nonce = new DataView(crypto.getRandomValues(new Uint8Array(8)).buffer,).getBigUint64(0);const [swapDvp] = await findSwapDvpPda({settlementAuthority,userA,userB,mintA,mintB,nonce,});const [escrowA] = await findSwapDvpEscrowAta({swapDvp,mint: mintA,tokenProgram: tokenProgramA,});const [escrowB] = await findSwapDvpEscrowAta({swapDvp,mint: mintB,tokenProgram: tokenProgramB,});
Koşulları kaydetme
CreateDvp; temel birimlerle iki tutarı, bir son kullanma zamanını, nonce'u ve dört
isteğe bağlı alanı alır: en fazla 64 bayttan oluşan opak bir referans, her taraf için
bir yerleşim hedefi ve en erken yerleşim zamanı (bkz. Notlar). Hedef, ilgili tarafın
gelirinin yerleşim anında ulaştığı yerdir; örneğin bir saklama kuruluşunun yatırma
cüzdanı. Varsayılan olarak tarafın kendi adresidir ve kayıt oluşturulduktan sonra
değiştirilemez. İadeler ve geri alımlar, escrow'u kim fonlamış olursa olsun, her zaman
tarafın o bacağın mint'i için kullanılan kendi token account'una gider; hiçbir zaman
bir hedefe gitmez.
Ödeyici; kayıt, nonce tombstone'u ve iki escrow için gereken rent'i karşılar.
Kapatma sırasında bu rent, ödeyiciye geri dönmez; kapatma talimatını imzalayan kişiye
gider. Tombstone hiçbir zaman kapatılmaz, bu yüzden her takas geride küçük bir kalıcı
bakiye bırakır. Ödeyicinin SOL bütçesini planlarken rent tutarlarını sabit kodlamak
yerine getMinimumBalanceForRentExemption RPC yöntemiyle türetin.
import { getCreateDvpInstruction } from "./dvp";const nowSeconds = BigInt(Math.floor(Date.now() / 1000));const createInstruction = getCreateDvpInstruction({payer: payerSigner,swapDvp,nonceTombstone: (await getProgramDerivedAddress({programAddress: DVP_SWAP_PROGRAM_PROGRAM_ADDRESS,seeds: ["nonce", getAddressEncoder().encode(swapDvp)],}))[0],settlementAuthority,userA,userB,mintA,mintB,dvpAtaA: escrowA,dvpAtaB: escrowB,tokenProgramA,tokenProgramB,amountA: 1_000_000_000n, // 1,000 units of a 6-decimal assetamountB: 998_500_000n, // 998.50 units of a 6-decimal cash tokenexpiryTimestamp: nowSeconds + 60n * 60n * 24n, // one daynonce,refString: "ORDER-2026-10-02-0001",userASettlementDestination: null, // defaults to userAuserBSettlementDestination: null, // defaults to userBearliestSettlementTimestamp: null,});const { context } = await client.sendTransaction([createInstruction]);console.log("Trade record:", swapDvp, "signature:", context.signature);
TypeScript kod parçacığı için @solana/kit içinden getProgramDerivedAddress ve
getAddressEncoder, istemciden ise DVP_SWAP_PROGRAM_PROGRAM_ADDRESS kapsamda
olmalıdır. Rust builder'ı, system program ve associated token program'ı varsayılan
değerlerinde bırakır.
Notlar
- Son kullanma zamanı. Son kullanma zamanını yalnızca Settle denetler. Reclaim, Cancel ve Reject bu zamandan sonra da çalışır; son kullanma zamanından sonra gelen bir mevduat, ilgili bacağın tarafı tarafından geri alınabilir. Son kullanma zamanı, oluşturmadan en fazla bir yıl sonrası olabilir.
- Zaman, ağ zamanıdır. Program zincir üstü saati okur; bu saat duvar saatinden bazen onlarca saniye farklı olabilir ve ileri doğru sıçrayabilir. Son kullanma zamanı ile planlanan yerleşim zamanı arasında pay bırakın, bu sınırlardan birine yakın bir zamanda fonlama veya yerleşim yapmaktan kaçının ve saniyesi saniyesine bir son tarihi zorunlu kılmak için son kullanma zamanına güvenmeyin. Program README'si yaklaşık bir dakikalık sapma payı bırakılmasını önerir.
- En erken yerleşim. İsteğe bağlıdır. Ayarlanırsa Settle bu zamandan önce reddedilir ve bu zaman son kullanma zamanından geç olamaz.
- Oluşturma anı denetimleri. Bir taraf system program'a ait bir hesap değilse
(bu, SPL Token multisig'i dışarıda bırakır) Create,
PartyNotSignerCapableile başarısız olur. Diğer hata kodları şunlardır:SettlementDestinationIsSwapDvp,SelfDvp,SameMint,ZeroAmount,SettlementAuthorityIsPartyveyaExpiryNotInFuture. Tam liste hatalar tablosunda yer alır.
Sonraki adımlar
- Bacakları fonlayın: her taraf kendi bacağını takasın escrow hesabına aktarır
Is this page helpful?