> ## 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.

# Triển khai một pool CPMM

> Script Node paste-and-go tạo một pool CPMM mới. Cấu hình mints và số lượng seed thông qua các biến env.

<Info>
  **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 →](/quick-start/deploy-cpmm-pool)
</Info>

<Info>
  **Cách thực hiện.** Tạo một pool CPMM hoàn toàn mới cho hai mints bạn chỉ định, chọn mức phí 0.25%, seed thanh khoản ban đầu ở giá được ngụ ý bởi các lượng seed, và in ra ID pool mới cùng chữ ký giao dịch.
</Info>

## Thiết lập

Hãy chắc chắn rằng bạn đã đọc [Điều kiện tiên quyết Bắt đầu nhanh](/vi/quick-start) và có `RPC_URL`, `KEYPAIR`, cũng như các thư viện phụ thuộc được cài đặt.

Bạn cũng cần **cấp cho ví các lượng seed của cả hai mints**, cộng thêm đủ SOL để chi trả phí tạo pool một lần (\~0.15 SOL trên mainnet, xem [`reference/program-addresses`](/vi/reference/program-addresses) để xem giá trị hiện tại).

## Script

Lưu dưới dạng `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}`);
```

## Chạy script

Ví dụ: tạo một pool SOL/USDC với 1 SOL và 160 USDC seed:

```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
```

Kết quả dự kiến:

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

## Điều gì vừa xảy ra

1. **`getCpmmConfigs`** lấy danh sách các mức phí live từ `api-v3.raydium.io` và chọn index 0 (mức phí 0.25% — xem [`reference/fee-comparison`](/vi/reference/fee-comparison) để xem toàn bộ tập hợp).
2. **`getTokenInfo`** giải quyết metadata của mỗi mint, bao gồm cả chương trình token nào sở hữu nó. CPMM chấp nhận cả SPL Token và Token-2022 mints; SDK định tuyến tự động.
3. **`createPool`** xây dựng một giao dịch thực hiện:
   * sắp xếp các mints theo thứ tự chính tắc,
   * dẫn xuất PDA pool, vaults, LP mint, và authority,
   * thanh toán `create_pool_fee` một lần cho `CREATE_CPMM_POOL_FEE_ACC`,
   * tạo ATAs của người gọi nếu chưa có,
   * seed các vaults với `AMOUNT_A` và `AMOUNT_B`.
4. **Giá ban đầu** được đặt theo tỷ lệ seed: `price = AMOUNT_B / AMOUNT_A` sau điều chỉnh số thập phân. Chọn cẩn thận — các bot sẽ arbitrage bất kỳ giá sai nào trong vòng vài giây sau khi pool mở.
5. **`startTime: new BN(0)`** mở giao dịch ngay lập tức. Để chuẩn bị thanh khoản trước khi mở cho công chúng, đặt một dấu thời gian Unix trong tương lai.

## Lỗi thường gặp

* **`pool already exists`** — Một pool đã tồn tại cho cặp mint này ở mức phí này. Tra cứu trước khi tạo.
* **`insufficient funds`** — Ví của bạn không có đủ `MINT_A`, `MINT_B`, hoặc SOL (cho phí tạo pool + rent).
* **`Token-2022 extension not supported`** — Một trong các mints của bạn sử dụng một extension mà CPMM không chấp nhận. Xem [`reference/token-2022-support`](/vi/reference/token-2022-support).

## Sau triển khai

Bạn có thể swap ngay lập tức đối với pool mới — script [Swap from CLI](/vi/quick-start/swap-from-cli) chấp nhận `POOL_ID` mới của bạn trực tiếp. Các aggregators (Jupiter, v.v.) sẽ index pool mới trong vòng vài phút.

## Tiếp theo

* [`products/cpmm/overview`](/vi/products/cpmm/overview) — CPMM là gì và khi nào nên chọn nó.
* [`user-flows/create-cpmm-pool`](/vi/user-flows/create-cpmm-pool) — cùng một luồng với ảnh chụp màn hình, thông qua giao diện Raydium.
* [`user-flows/choosing-a-pool-type`](/vi/user-flows/choosing-a-pool-type) — bạn có nên sử dụng CLMM thay thế không?
