Langsung ke konten utama
Halaman ini diterjemahkan secara otomatis oleh AI. Versi bahasa Inggris adalah acuan resmi.Lihat versi bahasa Inggris →
sdk-api/rust-cpi membahas mekanika tingkat rendah untuk memanggil setiap program Raydium. Halaman ini adalah pendamping tingkat lebih tinggi: mengapa Anda akan membuat komposisi Raydium ke dalam program Anda sendiri, pola mana yang cocok untuk kasus penggunaan Anda, dan semua kode yang Anda perlukan dari awal hingga akhir.

Kapan CPI adalah alat yang tepat

Program khusus masuk akal ketika swap perlu terjadi secara atomik dengan perubahan state on-chain lainnya yang hanya program Anda yang dapat lakukan. Kasus umum:
  • Program escrow / limit-order — pengguna menyetor mint ke escrow Anda, program Anda memantau kondisi harga, dan ketika terpicu, program Anda secara atomik melakukan swap melalui Raydium dan mengkredit akun pengguna.
  • Proxy agregator — instruksi tunggal yang merutekan swap melalui Raydium + satu atau lebih DEX lain, dengan semua hop di bawah satu slippage check yang dimiliki program Anda.
  • Vault auto-compounding — deposit LP atau farm stake ke vault Anda, vault memanen reward sesuai jadwal, memasok kembali likuiditas, menerbitkan share token.
  • Vault strategi — posisi LP leverage yang menyeimbangkan ulang dengan swap melalui CLMM; liquidator yang menutup posisi dan swap kolateral dalam satu transaksi.
  • Platform token-launch dengan vesting khusus — program Anda menyimpan token vesting dan melepasnya ke pool Raydium sesuai jadwal.
Jika Anda hanya ingin mengirim swap dari kode off-chain, CPI terlalu berlebihan — gunakan SDK. CPI hanya layak dengan kompleksitasnya ketika atomisitas dengan state Anda sendiri adalah persyaratan.

Pola komposisi

Pola 1: Proxy sederhana

Program Anda menampilkan instruksi tunggal yang memvalidasi beberapa kebijakan (misalnya, pasangan mint yang disetujui, diskon biaya untuk pengguna terverifikasi) dan kemudian meneruskan ke Raydium.
State hidup di ATA pengguna. Program Anda tidak memiliki token. Jejak kepercayaan minimal.

Pola 2: Escrow

Program Anda memiliki PDA yang menyimpan input mint pengguna. Saat terpicu, PDA menandatangani CPI ke Raydium untuk swap saldo miliknya sendiri.
Detail kritis: PDA menandatangani melalui CpiContext::new_with_signer. Lihat Signer seeds.

Pola 3: Multi-hop yang dikomposisi

Program Anda mengeluarkan beberapa CPI dalam satu instruksi, menegakkan batas slippage tunggal di seluruh semuanya. Instruksi swap Raydium masing-masing memiliki minimum_amount_out mereka sendiri, tetapi Anda menetapkannya ke 0 (atau batas lantai yang sangat longgar) dan menegakkan minimum final yang ketat sendiri setelah hop terakhir.
Ini memberi Anda gerbang reverting tunggal untuk seluruh rute. Hanya gunakan pola ini ketika Anda mempercayai setiap hop untuk slippage-safe; jika tidak, biarkan setiap hop menegakkan min-nya sendiri.

Pola 4: Vault / strategi

Program Anda menyimpan token LP atau farm stake dalam PDA. Keeper (atau pengguna) memanggil compound(), yang:
  1. Memanen reward dari farm.
  2. Menukar reward untuk token pool (CPI ke CPMM atau CLMM).
  3. Menyetor hasil kembali ke LP (CPI lainnya).
  4. Melakukan stake LP baru (CPI lainnya).
Semuanya dalam satu transaksi sehingga NAV vault bergerak secara atomik. Anggaran compute budget biasanya 600k–1M CU; tabel pencarian alamat wajib.

Konstruksi daftar akun

Struct Accounts program pemanggil mencerminkan urutan akun program Raydium, tetapi sebagian besar akun sisi Raydium adalah UncheckedAccount karena Raydium memvalidasinya sendiri. Anda hanya menambahkan constraint pada akun yang Anda miliki:
Asimetri — validasi ketat pada akun Anda, UncheckedAccount pada akun Raydium — bukan kelalaian. Penerima memvalidasi miliknya sendiri; validasi ganda di pemanggil hanya membakar CU dan berisiko kehilangan sinkronisasi ketika Raydium mengirim field layout struct baru.

Panggilan CPI itu sendiri

Signer seeds PDA

CPI berhasil hanya jika PDA yang dilewatkan sebagai authority cocok dengan derivasi yang diklaim pemanggil. Keduanya harus setuju tentang:
  1. Urutan byte seed (di sini [b"escrow", user.key().as_ref()]).
  2. Bump.
  3. ID program pemanggil (program Anda, bukan Raydium).
Raydium tidak peduli siapa authority-nya — ia hanya peduli bahwa signature authority mencakup transaksi dan bahwa ATA input dimiliki oleh authority tersebut. Validasi terjadi di anchor_spl::token::transfer: field authority ATA harus sama dengan signer. Bug umum: melewatkan user sebagai authority (dan transfer dari escrow_input_ata yang dimiliki oleh PDA escrow). Program SPL Token menolak dengan owner mismatch. Selalu buat field authority cocok dengan pemilik ATA.

Remaining accounts

Beberapa instruksi Raydium menerima daftar akun dengan panjang variabel yang ditambahkan setelah yang tetap — remaining accounts.
  • CLMM SwapV2: 1–8 akun TickArrayState untuk tick array yang mungkin dilalui swap, dalam arah swap.
  • Farm v6 Deposit / Harvest / Withdraw: pasangan (reward_vault, user_reward_ata), satu pasang per slot reward yang aktif.
  • Token-2022 transfer-hook mints: program transfer-hook ditambah akun apa pun yang diperlukan hook.
Helper CPI Anchor tidak melakukan type-check remaining accounts. Lewatkan melalui:
Urutan penting. Untuk CLMM:
Untuk farm v6 harvest:
Program pemanggil Anda harus melewatkan remaining accounts yang diterimanya dari klien tanpa perubahan. Jangan coba filter atau urutkan ulang.

Compute budget untuk panggilan yang dikomposisi

CPI biaya ~1.500 CU untuk call frame itu sendiri; penggunaan CU callee stack di atas. Anggaran kasar per CPI Raydium: Tambahkan ~1.500 untuk setiap CPI frame dan ~20.000 untuk overhead program Anda sendiri. Auto-compounder yang melakukan harvest → swap A → swap B → deposit LP → stake LP dengan mudah mencapai 700k CU. Selalu set ComputeBudgetProgram::set_compute_unit_limit yang eksplisit:
Ceiling CU default 200k akan diam-diam habis jauh sebelum panggilan yang dikomposisi selesai.

Propagasi error

Program Raydium mengembalikan error Anchor dengan kode stabil. Program pemanggil Anda melihatnya sebagai Err(ProgramError::Custom(code)). Bubble through secara default:
Atau intercept untuk kode spesifik:
Mapping kode error ke makna stabil sesuai kebijakan IDL (sdk-api/anchor-idl); kode baru append di akhir, kode yang ada tidak pernah berubah makna.

Contoh lengkap: escrow limit-order

Alur:
  1. open_order — pengguna menyetor amount_in dari input_mint ke PDA escrow; record target min_amount_out dan expiry.
  2. execute_order — siapa saja (keeper) memanggil dengan akun pool saat ini. Program memeriksa quote saat ini ≥ min_amount_out, kemudian CPI Raydium swap dan menyimpan output di escrow.
  3. claim — pengguna menarik output mint dari escrow.
Keeper membayar biaya transaksi (mereka mendapatkan biaya keeper di tempat lain — tidak ditampilkan). PDA escrow menandatangani CPI. Baik check slippage sisi Raydium dan check delta escrow sendiri menegakkan lantai — berlapis.

Pengujian

Menarik program Raydium ke validator lokal untuk integration test (dari Anchor.toml):
Clone akun pool state juga sehingga test Anda dapat benar-benar menjalankan swap; anchor test mengambilnya dari mainnet saat startup. Lihat sdk-api/rust-cpi.

Jebakan spesifik komposisi

Reentrancy

Solana tidak memiliki reentrancy sejati — CPI tidak dapat memanggil kembali ke program asal dalam invocation yang sama. Tetapi Anda masih dapat membangun diri Anda ke reentrancy logis: CPI yang membaca state Anda, kemudian kode Anda membacanya lagi mengasumsikan CPI tidak mengubahnya. Untuk Raydium, CPI tidak menyentuh state Anda, jadi ini adalah kekhawatiran yang kurang dari misalnya konteks flash-loan. Tetapi jika Anda membuat komposisi Raydium dengan protokol lending, sadari.

Account mutability drift

Jika program Anda melewatkan akun sebagai mut tetapi Raydium mengharapkannya read-only (atau sebaliknya), runtime menolak invocation dengan InvalidAccountData. Selalu periksa mutability yang diharapkan instruksi Raydium di IDL; anchor_cp_swap::cpi::accounts::Swap menegakkannya melalui tipe fieldnya.

Field program Token-2022

Input dan output mints mungkin di bawah program token yang berbeda — satu SPL Token, satu Token-2022. CPI memiliki field input_token_program dan output_token_program terpisah karena alasan ini. Selalu periksa field owner setiap mint dan rutekan program yang benar ke setiap slot.

Versioned transactions

Tx yang dikomposisi yang melakukan 2+ CPI Raydium plus pembuatan ATA jarang sesuai dalam transaksi legacy (v0-without-LUT). Gunakan V0 dengan address lookup tables; tarik LUT publik Raydium melalui raydium.getRaydiumLutAddresses().

Pointer

Sumber: