Luo kauppa

CreateDvp tallentaa kaupan ehdot ja luo kaksi escrow-tiliä, jotka osapuolet rahoittavat. Se ei siirrä tokeneita. Kuka tahansa voi lähettää sen, joten tietue voi tulla vastapuolelta, selvitysviranomaisen operaattorilta tai ulkopuoliselta, ja jokainen muu osallistuja tarkistaa tallennetut ehdot ennen kuin toimii niiden pohjalta (ks. osuuksien rahoitus).

Esimerkit käyttävät generoitua clientia suoraan ja paikkamerkkiosoitteita, jotta mukana olevat tilit ja allekirjoittajat näkyvät selvästi. Ne kohdistuvat devnetiin, jossa ohjelma on otettu käyttöön samassa osoitteessa kuin mainnet-betassa.

Asennus

DvP-clienteille ei ole julkaistu pakettia 2. lokakuuta 2026 mennessä. Molemmat generoidaan ohjelman IDL:stä repositoriossa, ja niitä käytetään lähdekoodista.

git clone https://github.com/solana-foundation/dvp.git
cd dvp && git checkout df9919ed02c25a93620e7f6820107c9050ce3b92
pnpm install && pnpm generate-clients && pnpm build
# The client is clients/typescript/src; copy or link it into your project as ./dvp
pnpm add @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token-2022 @solana-program/memo

Nämä sivut on kirjoitettu commitin df9919e pohjalta käyttäen @solana/kit 8:aa TypeScriptissä ja solana-* 2.x -crateja Rustissa.

Jokaisen vaihesivun esimerkit jatkavat edellisistä: kukin sivu käyttää aiemmilla sivuilla määriteltyjä clientia, allekirjoittajia ja osoitteita. payerSigner, userASigner, userBSigner ja authoritySigner ovat TransactionSigner-olioita rent-maksajalle, kahdelle osapuolelle ja selvitysviranomaiselle, esimerkiksi funktiolla createKeyPairSignerFromBytes luotuina. Rust-esimerkit rakentavat instruktiot ja jättävät allekirjoittamisen ja lähettämisen kutsujalle.

Johda osoitteet

Kauppatietue on Program Derived Address, joka johdetaan selvitysviranomaisesta, kahdesta osapuolesta, kahdesta mintistä ja nonce-arvosta. Kukin escrow on tietueen associated token account toiselle mintille. Kumpikin johdanta toimii ilman verkkoyhteyttä.

Käytä jokaiselle kaupalle satunnaista 64-bittistä nonce-arvoa. Koska luonti on lupaa vaatimatonta, ennustettava nonce antaa ulkopuoliselle mahdollisuuden varata osoitteen, jota kauppa olisi käyttänyt. Anna nonce ja määrät TypeScriptissä bigint-tyyppisinä; generoitu client hylkää number-arvon.

Korvaa jokainen ..._HERE-paikkamerkki oikealla osoitteella ennen ajamista. address() validoi base58-muodon ja heittää virheen paikkamerkistä, ja pubkey! ei käänny.

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

Tallenna ehdot

CreateDvp ottaa vastaan kaksi määrää perusyksiköissä, erääntymisajan, nonce-arvon ja neljä valinnaista kenttää: enintään 64 tavun mittaisen läpinäkymättömän viitteen, kummallekin puolelle selvityksen kohteen sekä aikaisimman selvitysajan (ks. Huomioita). Kohde on paikka, johon kyseisen osapuolen tuotot päätyvät selvityksessä, esimerkiksi säilytysyhteisön talletuslompakko; oletuksena se on osapuolen oma osoite, ja se lukitaan, kun tietue on luotu. Hyvitykset ja palautukset menevät aina osapuolen omalle token accountille kyseisen osuuden mintin osalta, ei koskaan kohteeseen, riippumatta siitä, kuka escrow'n rahoitti.

Maksaja rahoittaa tietueen, nonce-hautakiven ja molempien escrow-tilien rent-maksun. Sulkemisen yhteydessä kyseinen rent menee sulkevan instruktion allekirjoittajalle, ei takaisin maksajalle. Hautakiveä ei koskaan suljeta, joten jokainen kauppa jättää jälkeensä pienen pysyvän saldon. Kun budjetoit maksajan SOL-määrää, johda rent-määrät RPC-metodilla getMinimumBalanceForRentExemption sen sijaan, että kovakoodaisit ne.

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 asset
amountB: 998_500_000n, // 998.50 units of a 6-decimal cash token
expiryTimestamp: nowSeconds + 60n * 60n * 24n, // one day
nonce,
refString: "ORDER-2026-10-02-0001",
userASettlementDestination: null, // defaults to userA
userBSettlementDestination: null, // defaults to userB
earliestSettlementTimestamp: null,
});
const { context } = await client.sendTransaction([createInstruction]);
console.log("Trade record:", swapDvp, "signature:", context.signature);

TypeScript-esimerkki tarvitsee getProgramDerivedAddress- ja getAddressEncoder- funktiot paketista @solana/kit sekä DVP_SWAP_PROGRAM_PROGRAM_ADDRESS-vakion clientista näkyvyysalueellaan. Rust-builder jättää System Programin ja Associated Token Programin oletusarvoihinsa.

Huomioita

  • Erääntyminen. Vain Settle tarkistaa erääntymisajan. Reclaim, Cancel ja Reject toimivat sen jälkeenkin, ja erääntymisen jälkeen saapuneen talletuksen voi palauttaa kyseisen osuuden osapuoli. Erääntymisaika voi olla enintään yksi vuosi luomishetkestä.
  • Aika on verkon aikaa. Ohjelma lukee onchain-kellon, joka voi poiketa seinäkellon ajasta, ajoittain kymmenillä sekunneilla, ja voi hypätä eteenpäin. Jätä erääntymisajan ja aiotun selvitysajan väliin marginaali, vältä rahoitusta tai selvitystä kummankaan rajan lähellä äläkä luota erääntymisaikaan sekuntitarkan määräajan valvonnassa. Ohjelman README ehdottaa noin minuutin ajautuman huomioimista.
  • Aikaisin selvitys. Valinnainen. Jos asetettu, Settle hylätään ennen sitä, eikä se saa olla erääntymisaikaa myöhäisempi.
  • Luontihetken tarkistukset. Create epäonnistuu virheeseen PartyNotSignerCapable, jos osapuoli ei ole System Programin omistama tili (tämä sulkee pois SPL Token -multisigin), tai virheisiin SettlementDestinationIsSwapDvp, SelfDvp, SameMint, ZeroAmount, SettlementAuthorityIsParty tai ExpiryNotInFuture. Täydellinen luettelo on virhetaulukossa.

Seuraavat vaiheet

  • Rahoita osuudet: kumpikin osapuoli siirtää osuutensa kaupan escrow-tilille

Is this page helpful?

Sisällysluettelo

Muokkaa sivua
© 2026 Solana Foundation. Kaikki oikeudet pidätetään.