> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 部署 CPMM 流動性池

> 即插即用的 Node 腳本，可建立新的 CPMM 池。透過環境變數設定代幣與初始投入金額。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/quick-start/deploy-cpmm-pool)
</Info>

<Info>
  **這個腳本會做什麼。** 為你指定的兩個代幣建立全新 CPMM 池、選擇 0.25% 費用層級、按照初始投入金額所暗示的價格注入流動性，並列印新池的 ID 和交易簽名。
</Info>

## 準備工作

請確認你已閱讀 [快速開始先決條件](/zh-Hant/quick-start)，並已設定 `RPC_URL`、`KEYPAIR`，且已安裝相關套件。

你還需要 **為錢包注入雙方代幣的初始投入金額**，加上足夠的 SOL 來支付一次性池創建費用（主網約 0.15 SOL，詳見 [`reference/program-addresses`](/zh-Hant/reference/program-addresses) 取得當前數值）。

## 腳本

存為 `create-cpmm.mjs`：

```ts theme={null}
// create-cpmm.mjs
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import {
  Raydium,
  TxVersion,
  CREATE_CPMM_POOL_PROGRAM,
  CREATE_CPMM_POOL_FEE_ACC,
} from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";
import fs from "node:fs";

// ── Config from env ──────────────────────────────────────────────
const RPC_URL  = process.env.RPC_URL  ?? "https://api.mainnet-beta.solana.com";
const KEYPAIR  = process.env.KEYPAIR  ?? `${process.env.HOME}/.config/solana/id.json`;
const MINT_A   = process.env.MINT_A;   // required, base58
const MINT_B   = process.env.MINT_B;   // required, base58
const AMOUNT_A = process.env.AMOUNT_A; // required, integer raw units
const AMOUNT_B = process.env.AMOUNT_B; // required, integer raw units

if (!MINT_A || !MINT_B || !AMOUNT_A || !AMOUNT_B) {
  console.error("Set MINT_A, MINT_B, AMOUNT_A, AMOUNT_B env vars.");
  process.exit(1);
}

// ── Setup ────────────────────────────────────────────────────────
const connection = new Connection(RPC_URL, "confirmed");
const owner = Keypair.fromSecretKey(
  new Uint8Array(JSON.parse(fs.readFileSync(KEYPAIR, "utf8"))),
);
const raydium = await Raydium.load({
  owner,
  connection,
  cluster: "mainnet",
  disableFeatureCheck: true,
  blockhashCommitment: "finalized",
});

// ── Pick the 0.25% fee tier ─────────────────────────────────────
const feeConfigs = await raydium.api.getCpmmConfigs();
const feeConfig  = feeConfigs.find((c) => c.index === 0);
if (!feeConfig) throw new Error("0.25% fee tier not found in CPMM configs.");

// ── Resolve mint metadata (Token-2022-aware) ────────────────────
const mintA = await raydium.token.getTokenInfo(new PublicKey(MINT_A));
const mintB = await raydium.token.getTokenInfo(new PublicKey(MINT_B));

// ── Build and execute ───────────────────────────────────────────
const { execute, extInfo } = await raydium.cpmm.createPool({
  programId:       CREATE_CPMM_POOL_PROGRAM,
  poolFeeAccount:  CREATE_CPMM_POOL_FEE_ACC,
  mintA,
  mintB,
  mintAAmount:     new BN(AMOUNT_A),
  mintBAmount:     new BN(AMOUNT_B),
  startTime:       new BN(0), // open immediately
  feeConfig,
  associatedOnly:  false,
  ownerInfo:       { useSOLBalance: true },
  txVersion:       TxVersion.V0,
  computeBudgetConfig: {
    units: 600_000,
    microLamports: 100_000,
  },
});

const { txId } = await execute({ sendAndConfirm: true });

console.log(`Pool ID:  ${extInfo.address.poolId.toBase58()}`);
console.log(`LP mint:  ${extInfo.address.lpMint.toBase58()}`);
console.log(`Vault A:  ${extInfo.address.vaultA.toBase58()}`);
console.log(`Vault B:  ${extInfo.address.vaultB.toBase58()}`);
console.log(`Tx:       https://solscan.io/tx/${txId}`);
```

## 執行

範例：建立 SOL/USDC 池，初始投入 1 SOL 和 160 USDC：

```bash theme={null}
export MINT_A="So11111111111111111111111111111111111111112"   # wSOL
export MINT_B="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"   # USDC
export AMOUNT_A="1000000000"   # 1 SOL (9 decimals)
export AMOUNT_B="160000000"    # 160 USDC (6 decimals)

node create-cpmm.mjs
```

預期的輸出：

```
Pool ID:  HgC5...3kXb
LP mint:  4ZAS...9rkV
Vault A:  J9Mu...mP2k
Vault B:  AaJq...8wxx
Tx:       https://solscan.io/tx/5dQ...
```

## 發生了什麼

1. **`getCpmmConfigs`** 從 `api-v3.raydium.io` 拉取即時費用層級清單，並挑選索引 0（0.25% 層級——詳見 [`reference/fee-comparison`](/zh-Hant/reference/fee-comparison) 查看完整列表）。
2. **`getTokenInfo`** 解析每個代幣的元資料，包括它使用的代幣程式。CPMM 同時接受 SPL Token 和 Token-2022 代幣；SDK 會自動路由。
3. **`createPool`** 建立一個交易，進行以下操作：
   * 按標準順序排序代幣
   * 推導池 PDA、金庫、LP 代幣和授權者
   * 向 `CREATE_CPMM_POOL_FEE_ACC` 支付一次性 `create_pool_fee`
   * 建立調用者的 ATA（如果缺失）
   * 將 `AMOUNT_A` 和 `AMOUNT_B` 注入金庫
4. **初始價格** 由初始投入比例決定：經過小數點調整後，`price = AMOUNT_B / AMOUNT_A`。請小心選擇——在池開放後的數秒內，機器人會對任何定價錯誤進行套利。
5. **`startTime: new BN(0)`** 立即開放交易。若要在公開前準備流動性，請設定未來的 Unix 時戳。

## 常見錯誤

* **`pool already exists`** — 此代幣對已在此費用層級存在池。建立前請先查詢。
* **`insufficient funds`** — 你的錢包沒有足夠的 `MINT_A`、`MINT_B` 或 SOL（用於創建池費用 + 租金）。
* **`Token-2022 extension not supported`** — 你的其中一個代幣使用了 CPMM 不支援的擴展功能。詳見 [`reference/token-2022-support`](/zh-Hant/reference/token-2022-support)。

## 部署後

你可以立即針對新池進行交換——[從 CLI 進行交換](/zh-Hant/quick-start/swap-from-cli)腳本直接接受你的新 `POOL_ID`。彙整器（Jupiter 等）將在數分鐘內索引新池。

## 下一步

* [`products/cpmm/overview`](/zh-Hant/products/cpmm/overview) — CPMM 是什麼以及何時選擇它。
* [`user-flows/create-cpmm-pool`](/zh-Hant/user-flows/create-cpmm-pool) — 帶有截圖的相同流程，透過 Raydium UI。
* [`user-flows/choosing-a-pool-type`](/zh-Hant/user-flows/choosing-a-pool-type) — 你應該改用 CLMM 嗎？
