이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
버전 배너. 모든 데모는 Solana mainnet-beta에서
@raydium-io/raydium-sdk-v2@0.2.42-alpha를 대상으로 하며, 2026-04에 검증되었습니다. 프로그램 ID는 SDK를 통해 reference/program-addresses에서 가져옵니다.설정
raydium-sdk-V2-demo/src/clmm의 파일을 반영하며, 각 섹션 옆에 GitHub 링크가 있습니다. 부트스트랩은 데모 저장소의 config.ts.template (소스)를 따르며, disableFeatureCheck: true는 모든 비자명한 통합에 권장되는 설정입니다:
CLMM 풀 생성
소스:src/clmm/createPool.ts
- 파생 전에 바이트 순서로
mint1/mint2를 정렬합니다. sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64)를 계산합니다.observation및tick_array_bitmap_extension계정을 생성합니다.ammConfig에서 정의한 풀 생성 수수료를 지불합니다.
선택한 범위에서 포지션 열기
소스:src/clmm/createPosition.ts
InitTickArray 명령을 번들로 묶습니다.
기존 포지션의 유동성 증가
소스:src/clmm/increaseLiquidity.ts
유동성 감소 (동시에 수수료 수집)
소스:src/clmm/decreaseLiquidity.ts 및 src/clmm/closePosition.ts
liquidity = new BN(0)으로 decreaseLiquidity를 호출합니다. 명령의 부작용은 tokens_fees_owed_{0,1}을 정산하고 이를 전송하는 것입니다.
유동성과 수수료를 0으로 만든 후 포지션을 완전히 닫으려면 최종 decreaseLiquidity 호출에서 closePosition: true를 전달합니다. SDK는 ClosePosition을 추가하고 NFT를 소각합니다.
직접 Anchor 클라이언트의 경우 선언된 계정을 변경하지 않고 풀을 추가합니다:
poolId를 전달할 수 있습니다. CLMM은 positionNftAccount가 동결되었을 때만 읽으므로, 한 클라이언트 경로를 이전 및 새 포지션과 호환되게 유지합니다.
보상 수집
소스:src/clmm/harvestAllRewards.ts
harvestAllRewards는 전달된 모든 풀의 모든 포지션을 순회하고, CollectReward (및 모든 UpdateRewardInfos) 명령을 배치하며, 필요한 경우 트랜잭션 간에 분할합니다.
스왑
소스:src/clmm/swap.ts
computeAmountOutFormat는 온체인 프로그램과 동일한 로직을 사용하여 틱 맵을 오프체인에서 순회하고 다음을 반환합니다:
- 예상 출력 금액,
- 슬리피지 후 최소 출력 금액,
- 실제 스왑이 터치할 틱 배열 계정 목록 (
remainingAccounts).
remainingAccounts를 항상 전달합니다: 너무 적게 전달하면 스왑이 TickArrayNotFound로 중간에 되돌아가고, 오래된 것을 전달하면 낭비되는 계산이 발생합니다.
사용자 정의 가능한 CLMM 풀 생성
createCustomizablePool은 풀 생성 시 동적 수수료 및 단측 수수료 토글을 노출하는 새로운 진입점입니다. createPool과 동일한 형태에 세 가지 추가 사항이 있습니다:
createPool은 기본 수수료, 제한 주문 없음, 동적 수수료 없음 경로에 계속 작동합니다. 세 가지 새로운 노브 중 하나가 필요할 때마다 createCustomizablePool을 사용합니다. 온체인 계정 목록은 products/clmm/instructions를 참조하세요.
제한 주문
제한 주문은 사용자 입력을 단일 틱에 주차하고, 스왑이 해당 틱을 교차할 때 FIFO로 채워집니다. 출력은 정산 시 소유자의 ATA로 푸시되며, 소유자가 온라인 상태일 필요가 없습니다.제한 주문 열기
(pool, owner, tick, nonce)에서 LimitOrderState PDA를 파생하고, 풀당 소유자별 LimitOrderNonce를 범프하며, 해당 틱의 FIFO 코호트에 주문을 삽입합니다.
열린 주문 증가 / 감소
decreaseLimitOrder는 주문의 채워지지 않은 부분에서만 제거할 수 있습니다. 채워진 부분은 정산까지 잠깁니다. 주문이 이미 완전히 채워진 경우 두 명령 모두 InvalidOrderPhase로 되돌아갑니다.
채워진 주문 정산
settleLimitOrder는 주문의 unfilled_ratio_x64를 코호트 추적기에 대해 읽고, 채워진 출력을 계산하며, 이를 소유자의 ATA로 전송합니다. 소유자가 직접 호출할 수 있습니다. limit_order_admin (오프체인 운영 키퍼)도 소유자를 대신하여 호출할 수 있습니다. 출력은 여전히 소유자에게 갑니다.
완전히 정산된 주문을 닫아 임차료를 복구하려면 closeLimitOrder (단일) 또는 closeAllLimitOrder (배치)를 사용합니다. 한 번에 많은 것을 정산하려면 settleAllLimitOrder가 v0 tx에 맞는 만큼 많은 SettleLimitOrder 호출을 패킹합니다.
지갑의 주차된 주문 나열 (오프체인)
totalAmount / filledAmount / pendingSettle이 단계를 구분합니다). 닫힌 주문 기록의 경우 /limit-order/history/order/list-by-user?wallet=… (지갑별, nextPageId로 페이지 매김)을 사용합니다. 특정 주문의 전체 이벤트 로그의 경우 /limit-order/history/event/list-by-pda?pda=…를 사용합니다.
Rust CPI 스켈레톤
SwapV2의 남은 계정 순서:
일반적인 함정
- 간격을 벗어난 틱 끝점 →
InvalidTickIndex. 항상TickUtils.getPriceAndTick을 통해 스냅합니다. SwapV2에서 제공된 틱 배열이 부족 →TickArrayNotFound.computeAmountOutFormat을 사용하여 전체 목록을 가져옵니다.- 비트맵 확장 없는 전체 범위 포지션 → 확장 PDA는 쓰기 가능해야 합니다. SDK가 자동으로 처리합니다.
sqrt_price_x64를price로 착각 → 여기서 2배 혼동은 특히 고통스럽습니다. 의심할 때는 SDK가 인간이 읽을 수 있는 가격에서 계산하도록 하세요.- 너무 열심히 보상 수집 → 각 수집은 하나의 트랜잭션이 소요됩니다. 많은 포지션에서
harvestAllRewards를 통해 배치합니다. - NFT 계정을 직접 닫기 →
ClosePosition은 NFT를 소각하고 ATA를 닫습니다. Token-2022 NFT 민트도 닫습니다. 고전적인 SPL Token 민트는 해당 프로그램이 민트를 닫을 수 없기 때문에 공급량 0으로 유지됩니다. 지원되는 계정을 별도로 닫지 마세요. 그렇지 않으면 명령이 되돌아갑니다. - 간격이 없는 틱에서 제한 주문 열기 →
InvalidTickIndex. 항상TickUtils.getPriceAndTick을 통해 양자화합니다. - 완전히 채워진 주문에서
decreaseLimitOrder호출 →InvalidOrderPhase. 대신settleLimitOrder다음closeLimitOrder를 사용합니다. enableDynamicFee: true를 전달하면서dynamicFeeConfigId잊기 →CreateCustomizablePool되돌아가기는InvalidDynamicFeeConfigParams입니다. 동적 수수료를 끄거나/main/clmm-dynamic-config에서 구성을 선택합니다.
다음 단계
sdk-api/typescript-sdk— 완전한 SDK 표면.sdk-api/rest-api— 견적 및 풀 메타데이터 엔드포인트.user-flows/create-clmm-pool— 비코드 안내.integration-guides/aggregator— 경로의 일부로 CLMM 라우팅.

