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 →
Thông tin phiên bản. Tất cả các demo trên trang này sử dụng @raydium-io/raydium-sdk-v2@0.2.42-alpha trên Solana mainnet-beta, xác minh vào 2026-04. Các Program ID lấy từ reference/program-addresses thông qua SDK.

Cài đặt

Mỗi demo trên trang này tương ứng với một file trong raydium-sdk-V2-demo/src/clmm; đường link GitHub được đặt ngay cạnh từng phần. Phần khởi tạo tuân theo file config.ts.template của demo repo (nguồn) — disableFeatureCheck: true là cài đặt được khuyến nghị cho mọi tích hợp không tầm thường:

Tạo pool CLMM

Nguồn: src/clmm/createPool.ts
SDK sẽ thực hiện:
  • Sắp xếp mint1/mint2 theo thứ tự byte trước khi tính toán địa chỉ.
  • Tính sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Tạo các account observationtick_array_bitmap_extension.
  • Thanh toán phí tạo pool được xác định bởi ammConfig.

Mở vị thế trong khoảng giá tùy chọn

Nguồn: src/clmm/createPosition.ts
SDK tự động xác định các tick array mà khoảng giá chạm đến và đóng gói các lệnh InitTickArray nếu có bất kỳ array nào chưa được khởi tạo.

Tăng thanh khoản cho vị thế hiện có

Nguồn: src/clmm/increaseLiquidity.ts

Giảm thanh khoản (và thu phí đồng thời)

Nguồn: src/clmm/decreaseLiquidity.tssrc/clmm/closePosition.ts
Để chỉ thu phí, hãy gọi decreaseLiquidity với liquidity = new BN(0). Tác dụng phụ của lệnh này là thanh toán tokens_fees_owed_{0,1} và chuyển chúng ra ngoài. Để đóng hoàn toàn vị thế sau khi đã về zero thanh khoản và phí, truyền closePosition: true vào lần gọi decreaseLiquidity cuối cùng. SDK sẽ thêm lệnh ClosePosition và đốt NFT.

Thu phần thưởng

Nguồn: src/clmm/harvestAllRewards.ts
harvestAllRewards duyệt qua mọi vị thế trên mọi pool được truyền vào, gom nhóm các lệnh CollectReward (và mọi UpdateRewardInfos), rồi tách chúng thành nhiều giao dịch nếu cần.

Swap

Nguồn: src/clmm/swap.ts
computeAmountOutFormat duyệt bản đồ tick off-chain bằng cùng logic với chương trình on-chain và trả về:
  • lượng token nhận được dự kiến,
  • lượng token nhận tối thiểu sau slippage,
  • danh sách các account tick-array mà swap thực tế sẽ chạm vào (remainingAccounts).
Luôn truyền remainingAccounts được trả về từ bước mô phỏng: nếu truyền quá ít, swap sẽ revert giữa chừng với lỗi TickArrayNotFound; nếu truyền dữ liệu cũ, sẽ lãng phí compute.

Tạo pool CLMM tùy chỉnh

createCustomizablePool là entry point mới cho phép bật tắt dynamic-fee và single-sided-fee ngay tại thời điểm tạo pool. Tham số đầu vào giống với createPool nhưng có thêm ba trường mới:
createPool vẫn hoạt động bình thường cho trường hợp phí mặc định, không có limit order và không có dynamic fee. Hãy dùng createCustomizablePool khi bạn cần bất kỳ một trong ba tùy chọn mới trên. Xem products/clmm/instructions để biết danh sách account on-chain.

Lệnh limit order

Một limit order đặt token đầu vào của người dùng tại một tick duy nhất và được khớp theo thứ tự FIFO khi một swap vượt qua tick đó. Token đầu ra được chuyển vào ATA của chủ sở hữu tại thời điểm thanh toán; chủ sở hữu không cần trực tuyến để lệnh được khớp.

Mở limit order

SDK tính toán PDA LimitOrderState từ (pool, owner, tick, nonce), tăng LimitOrderNonce theo cặp (pool, owner), và chèn lệnh vào nhóm FIFO tại tick đó.

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

decreaseLimitOrder chỉ có thể xóa khỏi phần chưa được khớp của lệnh; phần đã khớp bị khóa cho đến khi thanh toán. Cả hai lệnh đều revert với lỗi InvalidOrderPhase nếu lệnh đã được khớp hoàn toàn.

Thanh toán lệnh đã khớp

settleLimitOrder đọc unfilled_ratio_x64 của lệnh so với bộ theo dõi nhóm, tính toán lượng đầu ra đã khớp, rồi chuyển vào ATA của chủ sở hữu. Chủ sở hữu có thể tự gọi hàm này; limit_order_admin (một keeper vận hành off-chain) cũng có thể gọi thay mặt chủ sở hữu — token đầu ra vẫn đến tay chủ sở hữu. Để đóng các lệnh đã thanh toán hoàn toàn nhằm thu hồi rent, dùng closeLimitOrder (đơn lẻ) hoặc closeAllLimitOrder (theo lô). Để thanh toán nhiều lệnh cùng lúc, settleAllLimitOrder đóng gói nhiều lệnh SettleLimitOrder nhất có thể vào một giao dịch v0.

Xem danh sách lệnh đang chờ của một ví (off-chain)

Endpoint lệnh đang hoạt động trả về cả lệnh chưa khớp lẫn khớp một phần trong một payload (totalAmount / filledAmount / pendingSettle phân biệt các trạng thái). Để xem lịch sử lệnh đã đóng, dùng /limit-order/history/order/list-by-user?wallet=… (theo ví, phân trang bằng nextPageId); để xem toàn bộ nhật ký sự kiện của một lệnh cụ thể, dùng /limit-order/history/event/list-by-pda?pda=….

Skeleton CPI bằng Rust

Thứ tự remaining account cho SwapV2:
Nếu swap không cần đến extension, hãy bỏ qua; ngược lại, nó phải là remaining account đầu tiên.

Các lỗi thường gặp

  • Tick endpoint không khớp với tick_spacingInvalidTickIndex. Luôn căn chỉnh bằng TickUtils.getPriceAndTick.
  • Không cung cấp đủ tick array trong SwapV2TickArrayNotFound. Dùng computeAmountOutFormat để lấy danh sách đầy đủ.
  • Vị thế full-range thiếu bitmap extension → PDA của extension phải có quyền ghi; SDK xử lý điều này tự động.
  • Nhầm lẫn sqrt_price_x64 với price → Nhầm lẫn này gây sai lệch theo hệ số 2 rất khó phát hiện. Khi không chắc, hãy để SDK tính từ giá dạng con người đọc được.
  • Thu phần thưởng quá thường xuyên → Mỗi lần thu tốn một giao dịch. Hãy gom nhóm bằng harvestAllRewards cho nhiều vị thế cùng lúc.
  • Đốt NFT khi mint vẫn còn nợ rentClosePosition cũng đóng luôn NFT mint và ATA; đừng đóng chúng riêng lẻ vì chương trình sẽ revert.
  • Mở limit order tại tick không đúng bội số của tick_spacingInvalidTickIndex. Luôn căn chỉnh bằng TickUtils.getPriceAndTick.
  • Gọi decreaseLimitOrder trên lệnh đã khớp hoàn toànInvalidOrderPhase. Thay vào đó hãy dùng settleLimitOrder rồi closeLimitOrder.
  • Quên dynamicFeeConfigId trong khi truyền enableDynamicFee: trueCreateCustomizablePool sẽ revert với lỗi InvalidDynamicFeeConfigParams. Hãy tắt dynamic fee hoặc chọn một config từ /main/clmm-dynamic-config.

Tiếp theo

Nguồn tham khảo: