Skip to main content
Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.Xem bản tiếng Anh →
Biểu ngữ phiên bản. Tất cả các ví dụ TypeScript nhắm tới @raydium-io/raydium-sdk-v2@0.2.64-alpha; chúng được thực thi lần cuối với 0.2.42-alpha (2026-04) và chữ ký gọi của chúng được kiểm tra lại với mã nguồn 0.2.64-alpha vào ngày 2026-09-09, trên Solana mainnet-beta. Bộ xương CPI Rust ở cuối nhắm tới raydium-clmm trên master, cố định Anchor =0.32.1 — không phải 1.0.2 mà trang CPMM sử dụng; hai cái này không thể cùng tồn tại trong một crate. ID chương trình đến từ reference/program-addresses thông qua SDK.

Thiết lập

Mỗi ví dụ trên trang này phản ánh một tệp trong raydium-sdk-V2-demo/src/clmm; liên kết GitHub nằm bên cạnh mỗi phần. Bootstrap tuân theo config.ts.template của kho demo (nguồn) — disableFeatureCheck: true là cài đặt được khuyến nghị cho bất kỳ tích hợp không tầm thường nào:

Tạo pool CLMM

Nguồn: src/clmm/createPool.ts
SDK:
  • Sắp xếp mint1/mint2 theo thứ tự byte trước khi dẫn xuất.
  • Tính sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Tạo các tài khoản observation và tick_array_bitmap_extension.
  • Trả phí tạo pool được xác định bởi ammConfig.

Mở vị trí trong khoảng được chọn

Nguồn: src/clmm/createPosition.ts
SDK tính toán tick array nào mà khoảng chạm tới và chuyển chúng dưới dạng tài khoản. Nó không cần phải gói bất kỳ lệnh init nào — không có lệnh init-tick-array; OpenPosition* tự cấp phát tick array bị thiếu, với chi phí của người trả tiền.

Tăng thanh khoản trên vị trí hiện có

Nguồn: src/clmm/increaseLiquidity.ts

Giảm thanh khoản (và thu thập phí cùng lúc)

Nguồn: src/clmm/decreaseLiquidity.ts và src/clmm/closePosition.ts
Để chỉ thu thập phí và phần thưởng, gọi decreaseLiquidity với liquidity = new BN(0). Tác dụng phụ của lệnh là giải quyết token_fees_owed_{0,1} và reward_amount_owed và chuyển chúng ra — đây là cách duy nhất để thu thập bất kỳ cái nào. Để đóng vị trí hoàn toàn sau khi xóa thanh khoản và phí, hãy chuyển ownerInfo: { closePosition: true } trên lệnh gọi decreaseLiquidity cuối cùng. SDK nối thêm ClosePosition và đốt NFT.
Các vị trí phát hành bị hạn chế yêu cầu trình xây dựng đóng tương thích. Các vị trí này có tài khoản token NFT bị đóng băng. ClosePosition phải nối ID pool của vị trí dưới dạng tài khoản còn lại đầu tiên để CLMM có thể rã đông tài khoản trước khi đốt nó. Nhánh nguồn chương trình không bao gồm thay đổi SDK. Xác nhận rằng phiên bản SDK của bạn hỗ trợ rõ ràng đường dẫn đóng bị đóng băng trước khi bật tạo vị trí phát hành bị hạn chế.
Đối với máy khách Anchor trực tiếp, giữ các tài khoản được khai báo không thay đổi và nối thêm pool:
Bạn có thể chuyển poolId trên mỗi lần đóng. CLMM chỉ đọc nó khi positionNftAccount bị đóng băng, điều này giữ một đường dẫn máy khách tương thích với các vị trí cũ và mới.

Thu thập phần thưởng

Nguồn: src/clmm/harvestAllRewards.ts
harvestAllRewards đi qua mỗi vị trí trên mỗi pool được chuyển vào, ghép các lệnh gọi DecreaseLiquidity không thanh khoản giải quyết phí và phần thưởng (cộng với bất kỳ UpdateRewardInfos), và chia chúng thành các giao dịch nếu cần.

Swap

Nguồn: src/clmm/swap.ts
Mô phỏng đi qua bản đồ tick ngoài chuỗi với logic giống như chương trình trên chuỗi và trả về số lượng ra (amountCalculated) cộng với danh sách tài khoản chính xác mà swap sẽ chạm tới (accounts). Luôn chuyển remainingAccounts mà mô phỏng trả về: quá ít và swap sẽ hoàn nguyên giữa chừng với NotEnoughTickArrayAccount; những cái cũ chỉ lãng phí tính toán.
PoolUtils.computeAmountOutFormat vẫn tồn tại, nhưng nó cần ComputeClmmPoolInfo ( computePoolInfo từ getPoolInfoFromRpc, không phải đối tượng pool API) cộng với hai đối số bắt buộc khác — tickarrayBitmapExtension và blockTimestamp — và không có phương thức raydium.clmm.fetchTickArrays (fetchTickArrays là hàm tự do; các trợ giúp cấp mô-đun là PoolUtils.fetchMultiplePoolTickArrays và tickData / tickArrays được trả về bởi getPoolInfoFromRpc).

Tạo pool CLMM có thể tùy chỉnh

createCustomizablePool là điểm vào công khai các công tắc phí động và phí một phía tại thời điểm tạo pool. Nó lấy hình dạng của createPool cộng với hai bổ sung:
Không có cờ enableDynamicFee và không có tham số dynamicFeeConfigId, và không có startTime. Cung cấp dynamicFeeConfig là những gì bật phí động — bỏ qua nó và bạn nhận được pool phí tĩnh, không có lỗi. Lưu ý rằng các thành viên enum SDK là TokenOnlyA / TokenOnlyB, trong khi enum Rust trên chuỗi đánh vần chúng Token0Only / Token1Only; các giá trị số khớp (FromInput = 0).
createPool tiếp tục hoạt động cho đường dẫn phí mặc định, không có phí động. Sử dụng createCustomizablePool bất cứ khi nào bạn cần một trong hai công tắc. Xem products/clmm/instructions để biết danh sách tài khoản trên chuỗi.

Lệnh giới hạn

Lệnh giới hạn đỗ đầu vào của người dùng tại một tick duy nhất và được điền FIFO khi swap vượt qua tick đó. Đầu ra được đẩy tới ATA của chủ sở hữu tại thời điểm giải quyết; chủ sở hữu không cần phải trực tuyến để được điền.

Mở lệnh giới hạn

SDK dẫn xuất PDA LimitOrderState từ (owner, nonce PDA, order nonce), tăng LimitOrderNonce cho mỗi ví, và chèn lệnh vào nhóm FIFO tại tick đó.

Tăng / giảm lệnh mở

decreaseLimitOrder chỉ có thể loại bỏ từ phần chưa điền của lệnh; phần đã điền bị khóa cho đến khi giải quyết. Cả hai lệnh đều hoàn nguyên với InvalidOrderPhase nếu lệnh đã được điền hoàn toàn.

Giải quyết lệnh đã điền

settleLimitOrder đọc unfilled_ratio_x64 của lệnh so với trình theo dõi nhóm, tính toán đầu ra đã điền, và chuyển nó tới ATA của chủ sở hữu. Chủ sở hữu có thể gọi cái này chính họ; limit_order_admin (một người giữ hoạt động ngoài chuỗi) cũng có thể gọi nó thay mặt chủ sở hữu — đầu ra vẫn đi tới chủ sở hữu. Để đóng các lệnh đã giải quyết hoàn toàn để khôi phục tiền thuê, hãy sử dụng closeLimitOrder (đơn) hoặc closeAllLimitOrder (hàng loạt). Để giải quyết nhiều cái cùng lúc, settleAllLimitOrder đóng gói bao nhiêu lệnh gọi SettleLimitOrder vừa vào tx v0.

Liệt kê các lệnh đỗ của ví (ngoài chuỗi)

Điểm cuối lệnh hoạt động trả về cả lệnh chưa điền và lệnh được điền một phần trong một tải trọng (totalAmount / filledAmount / pendingSettle phân biệt các giai đoạn). Để lịch sử lệnh đóng sử dụng /limit-order/history/order/list-by-user?wallet=… (cho mỗi ví, phân trang theo nextPageId); để nhật ký sự kiện đầy đủ của một lệnh cụ thể sử dụng /limit-order/history/event/list-by-pda?pda=….

Bộ xương CPI Rust

Thứ tự tài khoản còn lại cho SwapV2:
Nếu swap không bao giờ cần phần mở rộng, bỏ qua nó; nếu không, nó là tài khoản còn lại đầu tiên.

Những cạm bẫy phổ biến

  • Điểm cuối tick không cách đều → TickAndSpacingNotMatch. Luôn snap qua TickUtil.getPriceAndTick (TickUtil số ít).
  • Không đủ tick array được cung cấp trong SwapV2 → NotEnoughTickArrayAccount. Lấy danh sách từ swapInternal(...).accounts.
  • Vị trí phạm vi đầy đủ mà không có phần mở rộng bitmap → PDA phần mở rộng phải có thể ghi; SDK xử lý điều này tự động.
  • Nhầm lẫn sqrt_price_x64 với price → một sự nhầm lẫn hệ số-2 ở đây đặc biệt đau đớn. Khi nghi ngờ, hãy để SDK tính toán nó từ giá có thể đọc được của con người.
  • Thu thập phần thưởng quá sớm → mỗi lần thu thập là DecreaseLiquidity không thanh khoản và tốn một giao dịch. Ghép qua harvestAllRewards trên nhiều vị trí, và nhớ rằng execute của nó cần { sequentially: true }.
  • Đóng tài khoản NFT của bạn → ClosePosition đốt NFT và đóng ATA của nó. Nó cũng đóng mint NFT Token-2022; mint SPL Token cổ điển vẫn ở mức cung cấp bằng không vì chương trình đó không thể đóng mint. Không đóng các tài khoản được hỗ trợ riêng biệt hoặc lệnh sẽ hoàn nguyên.
  • Mở lệnh giới hạn tại tick không cách đều → TickAndSpacingNotMatch. Luôn lượng tử hóa qua trợ giúp getOrderTick được xuất.
  • Gọi decreaseLimitOrder trên lệnh được điền hoàn toàn → InvalidOrderPhase. Sử dụng settleLimitOrder rồi closeLimitOrder thay thế.
  • Mong đợi cờ enableDynamicFee → không có cái nào. Bỏ qua dynamicFeeConfig đơn giản tạo pool phí tĩnh, im lặng và không có lỗi. Nếu bạn muốn phí động, hãy chuyển PublicKey của tài khoản cấu hình, được chọn từ /main/clmm-dynamic-config.

Tiếp theo đi đâu

Nguồn: