이 페이지는 AI 자동 번역입니다. 모든 내용은 영문판을 기준으로 합니다.영문판 보기 →
sdk-api/rust-cpi는 각 Raydium 프로그램을 호출하는 저수준 메커니즘을 다룹니다. 이 페이지는 상위 수준의 동반 자료입니다: Raydium을 자신의 프로그램에 구성하는 이유, 어떤 패턴이 당신의 사용 사례에 맞는지, 그리고 처음부터 끝까지 필요한 전체 접착제입니다.CPI가 올바른 도구인 경우
커스텀 프로그램은 거래가 오직 당신의 프로그램만 수행할 수 있는 다른 온체인 상태 변경과 원자적으로 발생해야 할 때 의미가 있습니다. 일반적인 경우:- 에스크로우 / 지정가 주문 프로그램 — 사용자가 민트를 에스크로우에 예치하고, 당신의 프로그램이 가격 조건을 감시하다가 트리거되면 원자적으로 Raydium을 통해 스왑하고 사용자 계정에 크레딧을 부여합니다.
- 애그리게이터 프록시 — Raydium과 하나 이상의 다른 DEX를 통해 스왑을 라우팅하는 단일 명령어로, 모든 홉이 당신의 프로그램이 소유한 단일 슬리피지 체크 아래에 있습니다.
- 자동 복리 금고 — LP 또는 팜 스테이크를 금고에 예치하고, 금고가 일정에 따라 보상을 수확하고, 유동성을 다시 공급하고, 주식 토큰을 발행합니다.
- 전략 금고 — CLMM을 통해 스왑하여 리밸런싱하는 레버리지 LP 포지션; 포지션을 종료하고 한 거래에서 담보를 스왑하는 청산자.
- 커스텀 베스팅이 있는 토큰 출시 플랫폼 — 당신의 프로그램이 베스팅 토큰을 보유하고 일정에 따라 Raydium 풀로 릴리스합니다.
구성 패턴
패턴 1: 얇은 프록시
당신의 프로그램은 어떤 정책을 검증하는 단일 명령어를 노출합니다 (예: 화이트리스트된 민트 쌍, 검증된 사용자를 위한 수수료 할인) 그리고 나서 Raydium으로 전달합니다.패턴 2: 에스크로우
당신의 프로그램은 사용자의 입력 민트를 보유하는 PDA를 소유합니다. 트리거 시 PDA는 Raydium에 CPI에 서명하여 자신의 잔액을 스왑합니다.CpiContext::new_with_signer를 통해 서명합니다. 서명자 시드를 참조하세요.
패턴 3: 구성된 멀티홉
당신의 프로그램은 한 명령어에서 여러 CPI를 발행하여 모든 CPI에 걸쳐 단일 슬리피지 한계를 적용합니다. Raydium 스왑 명령어는 각각 자신의minimum_amount_out을 가지지만, 당신은 그것들을 0 (또는 매우 느슨한 바닥)으로 설정하고 마지막 홉 후에 엄격한 최종 최소값을 직접 적용합니다.
패턴 4: 금고 / 전략
당신의 프로그램은 LP 토큰 또는 팜 스테이크를 PDA에 보유합니다. 키퍼 (또는 사용자)가compound()를 호출하면:
- 팜에서 보상을 수확합니다.
- 보상을 풀 토큰으로 스왑합니다 (CPMM 또는 CLMM으로 CPI).
- 수익금을 LP에 다시 예치합니다 (또 다른 CPI).
- 새 LP를 스테이크합니다 (또 다른 CPI).
계정 목록 구성
호출 프로그램의Accounts 구조체는 Raydium 프로그램의 계정 순서를 반영하지만, 대부분의 Raydium 측 계정은 Raydium이 자체적으로 검증하기 때문에 UncheckedAccount입니다. 당신은 당신이 소유한 계정에만 제약을 추가합니다:
UncheckedAccount — 은 게으름이 아닙니다. 수신자는 자신의 것을 검증합니다; 호출자에서 이중 검증하는 것은 CU를 낭비하고 Raydium이 새로운 구조체 레이아웃 필드를 배포할 때 동기화되지 않을 위험이 있습니다.
CPI 호출 자체
PDA 서명자 시드
CPI는authority로 전달된 PDA가 호출자가 주장하는 파생과 일치할 때만 성공합니다. 둘 다 다음에 동의해야 합니다:
- 시드 바이트 시퀀스 (여기서
[b"escrow", user.key().as_ref()]). - 범프.
- 호출 프로그램 ID (Raydium이 아닌 당신의 프로그램).
authority 슬롯은 CPMM 자체의 보관소 PDA입니다 — CPMM이 직접 파생하고 스스로 서명하는 고정된 프로그램 전역 계정이며, 당신의 프로그램이 통제하거나 대체하지 않습니다. 당신의 PDA 시드가 일치해야 하는 계정은 **payer**입니다: 검증은 CPMM 자체의 transfer_from_user_to_pool_vault 헬퍼 내부에서 이루어지며, payer로 전달된 계정이 input_token_account의 소유자여야 합니다.
일반적인 버그: escrow_input_ata가 에스크로우 PDA의 소유인데 user를 payer로 전달하는 것입니다. SPL Token 프로그램은 owner mismatch로 거부합니다. 항상 payer를 ATA의 소유자로 지정하고, 그 소유자가 PDA인 경우 new_with_signer로 서명하세요.
남은 계정
여러 Raydium 명령어는 고정된 계정 뒤에 추가된 가변 길이 계정 목록을 가집니다 — 남은 계정.- CLMM
SwapV2: 스왑이 스왑 방향으로 순회할 수 있는 틱 배열에 대한 1–8개의TickArrayState계정. - Farm v6
Deposit/Harvest/Withdraw:(reward_vault, user_reward_ata)쌍, 활성 보상 슬롯당 한 쌍. - Token-2022 전송 훅 민트: 전송 훅 프로그램과 훅이 필요한 모든 계정.
구성된 호출을 위한 컴퓨트 예산
CPI는 호출 프레임 자체에 약 1,500 CU를 소비합니다. 피호출자 자신의 CU 사용량은 그 위에 쌓입니다. 아래 피호출자 수치는 2026-09-09에 거래량이 많은 풀의 실제 메인넷 트랜잭션에서 측정한 값으로, Raydium 프로그램 자체 호출에 대한Program <id> consumed N of M compute units 로그 라인에서 읽었습니다(따라서 내부 토큰 프로그램 CPI가 포함됩니다):
각 CPI 프레임에 약 1,500을 더하고 그 위에 당신의 프로그램 오버헤드를 더하세요. CLMM 스왑 비용은 틱 교차 횟수에 따라 증가하므로 그 수치는 하한으로 취급하세요. Token-2022 민트는 전송 자체의 확장 처리 비용을 추가합니다. 일률적인 배수를 적용하지 말고 자신의 민트에 대해 직접 측정하세요.
항상 명시적
ComputeBudgetProgram::set_compute_unit_limit을 설정하세요:
오류 전파
Raydium의 프로그램은 안정적인 오류 코드를 가진 Anchor 오류를 반환합니다. 당신의 호출 프로그램은 그것들을Err(ProgramError::Custom(code))로 봅니다. 기본적으로 버블링하세요:
ERROR_CODE_OFFSET 항목에 주의하세요: #[error_code] 배리언트는 6000부터 시작하는 번호로 발행되므로, 순수 enum 판별자와 비교하면 절대 일치하지 않습니다. (anchor-lang이나 raydium_cp_swap에는 is_err 헬퍼가 없습니다 — 이 페이지의 이전 리비전은 존재하지 않는 헬퍼를 사용했습니다.)
오류 코드-의미 매핑은 IDL 정책에 따라 안정적입니다 (sdk-api/anchor-idl); 새 코드는 끝에 추가되고, 기존 코드는 절대 의미가 변경되지 않습니다.
완전한 실제 예제: 지정가 주문 에스크로우
흐름:open_order— 사용자가input_mint의amount_in을 에스크로우 PDA에 예치합니다; 목표min_amount_out과 만료를 기록합니다.execute_order— 누구든지 (키퍼)가 현재 풀 계정으로 호출합니다. 프로그램은 현재 견적이min_amount_out이상인지 확인한 다음 Raydium 스왑을 CPI하고 출력을 에스크로우에 유지합니다.claim— 사용자가 에스크로우에서 출력 민트를 인출합니다.
order PDA는 에스크로우의 입력 ATA를 소유하므로 payer로서 CPI에 서명합니다. 따라서 ExecuteOrder에는 CPMM 자체의 보관소 PDA를 위한 pool_authority: UncheckedAccount<'info> 필드도 필요합니다. Raydium 측 슬리피지 체크 와 에스크로우 자체의 델타 체크 모두 바닥을 적용합니다 — 이중 확인입니다.
테스트
로컬 검증자에 Raydium 프로그램을 통합 테스트로 가져오기 (Anchor.toml에서):
anchor test는 시작 시 메인넷에서 가져옵니다. sdk-api/rust-cpi를 참조하세요.
구성에 특정한 함정
재진입성
Solana는 진정한 재진입성이 없습니다 — CPI는 같은 호출에서 원래 프로그램으로 다시 호출할 수 없습니다. 하지만 당신은 여전히 자신을 논리적 재진입성으로 구성할 수 있습니다: CPI가 당신의 상태를 읽고, 그 다음 당신의 코드가 CPI가 변경하지 않았다고 가정하고 다시 읽습니다. Raydium의 경우 CPI는 당신의 상태를 건드리지 않으므로 이것은 예를 들어 플래시 론 컨텍스트보다 덜 우려됩니다. 하지만 Raydium을 대출 프로토콜과 구성하면 주의하세요.계정 가변성 드리프트
당신의 프로그램이 계정을mut로 전달하지만 Raydium이 읽기 전용으로 예상하는 경우(또는 그 반대), 런타임은 InvalidAccountData로 호출을 거부합니다. 항상 Raydium 명령어의 예상 가변성을 IDL에서 확인하세요. raydium_cp_swap::cpi::accounts::Swap은 CPMM 자체 Swap 구조체의 #[account(mut)] 표시로부터 각 계정의 가변성을 대신 설정해 줍니다 — 생성된 필드는 모두 일반 AccountInfo<'info>이므로, 플래그를 담고 있는 것은 필드 타입이 아니라 파생된 ToAccountMetas 구현입니다.
Token-2022 프로그램 필드
입력 및 출력 민트는 다른 토큰 프로그램 아래에 있을 수 있습니다 — 하나는 SPL Token, 하나는 Token-2022. CPI는 이 이유로 별도의input_token_program과 output_token_program 필드를 가집니다. 항상 각 민트의 owner 필드를 확인하고 올바른 프로그램을 각 슬롯으로 라우팅하세요.
버전화된 거래
2개 이상의 Raydium CPI와 ATA 생성을 수행하는 구성된 tx는 레거시 (v0-without-LUT) 거래에 거의 맞지 않습니다. V0을 주소 조회 테이블과 함께 사용하세요;raydium.getRaydiumLutAddresses()를 통해 Raydium의 공개 LUT를 가져오세요.
포인터
sdk-api/rust-cpi— 저수준 CPI 메커니즘.integration-guides/priority-fee-tuning— 컴퓨트 예산 크기 조정.products/cpmm/code-demos,products/clmm/code-demos,products/farm-staking/code-demos— 제품별 CPI 스니펫.

