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

> كل PDA وحساب مشترك يتفاعل معه مجموعة CPMM: PoolState و AmmConfig والسلطة و LP mint وخزائن الرموز وحلقة المراقبة.

<Info>
  **هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.**

  [عرض النسخة الإنجليزية →](/products/cpmm/accounts)
</Info>

<Info>
  معرّفات البرنامج وبذور PDA للـ CPMM مدرجة بشكل رسمي في [`reference/program-addresses`](/ar/reference/program-addresses). تركز هذه الصفحة على **الغرض من كل حساب والثوابت التي يحافظ عليها**، وليس على العناوين المشفرة.
</Info>

## الحسابات الستة لمجموعة CPMM

يتم وصف كل مجموعة CPMM بالكامل من خلال ستة عناوين مشتقة من البرنامج (PDAs) تحت برنامج CPMM، بالإضافة إلى حساب `AmmConfig` مشترك واحد يُشير إليه. بمجرد حصولك على الـ mint الاثنين، يمكنك اشتقاق كل شيء بشكل حتمي دون لمس الشبكة.

| الحساب        | البذرة(ات)                                                                                  | المالك                 | الغرض                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------------------------------------------------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authority`   | `"vault_and_lp_mint_auth_seed"`                                                             | CPMM                   | الموقّع لكل حركة خزينة وكل عملية mint/burn من LP. مشترك عبر **جميع** مجموعات CPMM.                                                                                                                                                                                                                                                                      |
| `poolState`   | `"pool"`، `ammConfig`، `token0Mint`، `token1Mint` **أو** أي زوج مفاتيح عشوائي يوفره الموقّع | CPMM                   | هيكل حالة المجموعة — زوج mint والأرصدة في الخزائن وإمداد LP وتراكم الرسوم وموقّع المراقبة. تقبل تعليمات CPMM `Initialize` إما PDA الكنسي المشتق من البذور الأربع **أو** زوج مفاتيح تعسفي موقّع من قِبل المُنشئ. يوجد مسار زوج المفاتيح العشوائي لهزيمة هجوم front-running حيث يراقب خصم المجموعة الذاكرة ويتسابق لاحتلال PDA الكنسي قبل المُنشئ الشرعي. |
| `lpMint`      | `"pool_lp_mint"`، `poolState`                                                               | SPL Token              | رمز LP للمجموعة. الإمداد = إجمالي LP المعترف به. سلطة mint = CPMM authority PDA.                                                                                                                                                                                                                                                                        |
| `vault0`      | `"pool_vault"`، `poolState`، `token0Mint`                                                   | SPL Token / Token-2022 | يحتفظ برصيد المجموعة من token0. مملوك بواسطة authority PDA.                                                                                                                                                                                                                                                                                             |
| `vault1`      | `"pool_vault"`، `poolState`، `token1Mint`                                                   | SPL Token / Token-2022 | يحتفظ برصيد المجموعة من token1. مملوك بواسطة authority PDA.                                                                                                                                                                                                                                                                                             |
| `observation` | `"observation"`، `poolState`                                                                | CPMM                   | حلقة مخزن مؤقت من عينات الأسعار المستخدمة للـ TWAP. يتم الكتابة في كل swap.                                                                                                                                                                                                                                                                             |

والإعدادات المشتركة:

| الحساب      | البذرة(ات)                   | المالك | الغرض                                                                                                                                                  |
| ----------- | ---------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ammConfig` | `"amm_config"`، `index: u16` | CPMM   | يحتفظ برسوم التداول والبروتوكول والصندوق والمُنشئ والمفاتيح الإدارية. واحد لكل "طبقة رسوم". يرتبط poolstate بواحدة عند الإنشاء ولا يمكن تغييره لاحقاً. |

## استخراج مجموعة من لا شيء سوى اثنين من mints

```ts theme={null}
import { PublicKey } from "@solana/web3.js";
import BN from "bn.js";

const CPMM_PROGRAM_ID = new PublicKey(
  "CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C"
); // mainnet — see reference/program-addresses

function u16ToBytes(n: number): Buffer {
  const b = Buffer.alloc(2);
  b.writeUInt16BE(n);
  return b;
}

// token0 < token1 by byte order. Getting this wrong yields a valid PDA
// that points at a nonexistent pool.
function sortMints(a: PublicKey, b: PublicKey): [PublicKey, PublicKey] {
  return Buffer.compare(a.toBuffer(), b.toBuffer()) < 0 ? [a, b] : [b, a];
}

export function deriveCpmmAccounts(
  mintA: PublicKey,
  mintB: PublicKey,
  ammConfigIndex = 0,
) {
  const [token0Mint, token1Mint] = sortMints(mintA, mintB);

  const [ammConfig] = PublicKey.findProgramAddressSync(
    [Buffer.from("amm_config"), u16ToBytes(ammConfigIndex)],
    CPMM_PROGRAM_ID,
  );
  const [authority] = PublicKey.findProgramAddressSync(
    [Buffer.from("vault_and_lp_mint_auth_seed")],
    CPMM_PROGRAM_ID,
  );
  const [poolState] = PublicKey.findProgramAddressSync(
    [
      Buffer.from("pool"),
      ammConfig.toBuffer(),
      token0Mint.toBuffer(),
      token1Mint.toBuffer(),
    ],
    CPMM_PROGRAM_ID,
  );
  const [lpMint] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_lp_mint"), poolState.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [vault0] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_vault"), poolState.toBuffer(), token0Mint.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [vault1] = PublicKey.findProgramAddressSync(
    [Buffer.from("pool_vault"), poolState.toBuffer(), token1Mint.toBuffer()],
    CPMM_PROGRAM_ID,
  );
  const [observation] = PublicKey.findProgramAddressSync(
    [Buffer.from("observation"), poolState.toBuffer()],
    CPMM_PROGRAM_ID,
  );

  return {
    ammConfig,
    authority,
    poolState,
    lpMint,
    token0Mint,
    token1Mint,
    vault0,
    vault1,
    observation,
  };
}
```

<Tip>
  **رتّب الـ mints دائماً قبل استخراج PDA المجموعة.** تقوم البذرة بمصادفة الـ mints بترتيب البايت، وليس بترتيب المستخدم. كان لدى مجموعتين مع `(A, B)` و `(B, A)` ستتصادم على السلسلة — الترتيب هو كيفية جعل البرنامج للتخطيط الكنسي.
</Tip>

<Note>
  **معرّف المجموعة ليس دائماً الـ PDA الكنسي.** تقبل `Initialize` زوج مفاتيح موقّع تعسفي كـ `pool_state` بالإضافة إلى PDA أعلاه. إذا لم يطابق الحساب المُمرر الـ PDA الكنسي، يتطلب البرنامج أن يكون موقّعاً — أي يمرر المُنشئ زوج مفاتيح جديد يوقّعون به. هذا هو الدفاع ضد front-running: يمكن لأي طرف ثالث يتسابق لالتقاط الـ PDA الكنسي أن يتم تجاوزه من قِبل المُنشئ الشرعي باستخدام زوج مفاتيح عشوائي بدلاً من ذلك. يتم اشتقاق الـ PDAs اللاحقة (`lpMint`، `vault0`، `vault1`، `observation`) من `poolState.key()`، لذا تبقى فريدة لأي عنوان تم استخدامه. عندما تقوم بفهرسة المجموعات، قم دائماً باكتشاف معرّف المجموعة من الحالة على السلسلة (مثل حسابات `PoolState` تحت برنامج CPMM)، وليس بمحاولة استخراج الـ PDA الكنسي — سيفقد الأخير مجموعات أزواج المفاتيح العشوائية.
</Note>

## تخطيطات الحساب

تعيش التعريفات الكاملة لـ Rust في مصدر [`raydium-cp-swap`](https://github.com/raydium-io/raydium-cp-swap). الحقول أدناه هي التي ستقرأها من التكامل.

### `PoolState`

```rust theme={null}
// programs/cp-swap/src/states/pool.rs
pub struct PoolState {
    pub amm_config: Pubkey,               // binds this pool to an AmmConfig
    pub pool_creator: Pubkey,             // who ran initialize
    pub token_0_vault: Pubkey,            // == vault0 PDA
    pub token_1_vault: Pubkey,            // == vault1 PDA

    pub lp_mint: Pubkey,
    pub token_0_mint: Pubkey,
    pub token_1_mint: Pubkey,

    pub token_0_program: Pubkey,          // SPL Token or Token-2022 program
    pub token_1_program: Pubkey,

    pub observation_key: Pubkey,          // == observation PDA
    pub auth_bump: u8,
    pub status: u8,                       // bitmask: deposit | withdraw | swap
    pub lp_mint_decimals: u8,
    pub mint_0_decimals: u8,
    pub mint_1_decimals: u8,

    pub lp_supply: u64,                   // mirrors lp_mint supply
    pub protocol_fees_token_0: u64,
    pub protocol_fees_token_1: u64,
    pub fund_fees_token_0: u64,
    pub fund_fees_token_1: u64,

    pub open_time: u64,                   // unix; swaps rejected before this
    pub recent_epoch: u64,

    // Creator-fee state (added after the original layout):
    pub creator_fee_on: u8,               // 0=BothToken, 1=OnlyToken0, 2=OnlyToken1
    pub enable_creator_fee: bool,
    pub padding1: [u8; 6],
    pub creator_fees_token_0: u64,
    pub creator_fees_token_1: u64,

    pub padding: [u64; 28],
}
```

ما يجب قراءته فعلياً:

* **`lp_supply`** — مرآة داخلية للمجموعة لإجمالي إمداد LP mint. استخدمه لرياضيات LP-share؛ يجب أن تطابق القيمة الإمداد على السلسلة من mint، لكن قراءتها من `PoolState` تتجنب جلب حساب إضافي.
* **`protocol_fees_token{0,1}`**، **`fund_fees_token{0,1}`** — الرسوم *المتراكمة* التي لم يتم حصدها بعد. هذه لا تؤثر على تسعير swap؛ تجلس في الخزائن حتى استدعاء `CollectProtocolFee` / `CollectFundFee`.
* **`status`** — قناع بت يتحكم في السماح بـ `Swap` و `Deposit` و `Withdraw`. تم تحديثه بواسطة الإدارة عبر `UpdatePoolStatus`. يتحقق الـ SDK من هذا قبل بناء معاملة؛ إذا كنت تقوم بـ CPI مباشرة، تحقق منها بنفسك.
* **`token0_program` / `token1_program`** — برنامج الرمز للـ CPI في لكل خزينة. يمكن لأحدهما أن يكون SPL Token الكلاسيكي والآخر Token-2022؛ يكونان مستقلين.
* **`open_time`** — طابع زمني Unix. يفشل swaps قبل هذا الوقت. يُسمح بالإيداعات قبل `open_time` حتى يمكن زرع المجموعة.
* **`creator_fee_on` / `enable_creator_fee`** — معاً يتحكمان في ما إذا كانت رسوم المُنشئ الاختيارية نشطة لهذه المجموعة وأي جانب من swap يتم جمعها. `enable_creator_fee == false` يصفر مسار رسوم المُنشئ بالكامل. عند التفعيل، يختار `creator_fee_on`: `0` = خذ الرسم من أي رمز هو مدخل swap (`BothToken`)؛ `1` = خذ الرسم من `token_0` فقط (تخطي في swaps `token_1 → token_0`)؛ `2` = خذ الرسم من `token_1` فقط. تم التعيين عند إنشاء المجموعة عبر `InitializeWithPermission`؛ لا يمكن تغييره لاحقاً.
* **`creator_fees_token_{0,1}`** — الرسوم المتراكمة للمُنشئ، يتم حصدها بواسطة `CollectCreatorFee`.

### `AmmConfig`

```rust theme={null}
pub struct AmmConfig {
    pub bump: u8,
    pub disable_create_pool: bool,
    pub index: u16,                       // matches the seed
    pub trade_fee_rate: u64,              // e.g., 2500 = 0.25%
    pub protocol_fee_rate: u64,           // fraction of trade fee to protocol
    pub fund_fee_rate: u64,               // fraction of trade fee to fund
    pub create_pool_fee: u64,             // paid once at init (in SOL or token)
    pub protocol_owner: Pubkey,           // can call CollectProtocolFee
    pub fund_owner: Pubkey,               // can call CollectFundFee
    pub creator_fee_rate: u64,            // optional pool-creator fee rate (1/1_000_000 of volume)
    pub padding: [u64; 15],
}
```

ثلاثة أشياء يجب الحذر منها:

1. **`trade_fee_rate` و `creator_fee_rate` هما كسور من الحجم**، كلاهما مقسم بوحدات `1/1_000_000`. `2500` تعني 0.25% من حجم التداول. **`protocol_fee_rate` و `fund_fee_rate` هما كسور من *رسوم التداول*** (وليس من الحجم)، بنفس مقسم `1/1_000_000`. رسوم المُنشئ **ليست** كسراً من رسوم التداول — فهي معدل مستقل خاص بها. الحسابات الكاملة موجودة في [`products/cpmm/fees`](/ar/products/cpmm/fees).
2. **`index` هو `u16`**، لذا تستخدم بذرة الـ hash 2 بايت بترتيب big-endian. عدم التطابق على ترتيب البايت هو خطأ تكامل شائع.
3. **`AmmConfig` ثابت على مستوى المجموعة.** تشير المجموعة إلى `AmmConfig` واحد عند الإنشاء ولا تتحول أبداً. تنتشر تغييرات الرسوم لأن المجموعة تقرأ الإعدادات في كل swap — لكن المجموعة لا يمكن نقلها بين طبقات الرسوم.

ملاحظة على رسوم المُنشئ: **المعدل** نفسه (`creator_fee_rate`) يعيش على `AmmConfig` ومشترك عبر طبقة الرسوم. ما إذا كانت مجموعة معينة تفرضها فعلاً (`enable_creator_fee`) وأي جانب من swap تقع عليه (`creator_fee_on`) يعيش على `PoolState`. رسوم المُنشئ **مستقلة** عن رسوم التداول — فهي معدل خاص بها، متراكمة على عدادات خاصة بها (`creator_fees_token_{0,1}`)، وأبداً لا تقلل من أسهم LP / البروتوكول / الصندوق من رسوم التداول. الحصد عبر `CollectCreatorFee`. انظر [`products/cpmm/fees`](/ar/products/cpmm/fees) للميكانيكا الكاملة.

### `Permission`

حساب تحكم الوصول الصغير المستخدم بواسطة `InitializeWithPermission`. يدعم برنامج CPMM مسار إنشاء مجموعة محدود بحيث يمكن للبرامج الأخرى (على سبيل المثال LaunchLab عند تخريج رمز إلى CPMM) إثبات أنهم مخوّلون بإنشاء مجموعة ضد `AmmConfig` معين.

```rust theme={null}
pub struct Permission {
    pub authority: Pubkey,    // who is allowed to call InitializeWithPermission
    pub padding: [u64; 8],
}
```

يتم إنشاء PDA Permission بواسطة إدارة CPMM عبر `CreatePermissionPda` وإلغاء صلاحيته عبر `ClosePermissionPda`. لا يتفاعل المستخدمون النهائيون مع هذا الحساب مباشرة — إنه أنابيب لتدفقات برنامج متقاطع.

### الخزائن و Token-2022

يمتلك `vault0` و `vault1` CPMM authority PDA، وفي حين أن مالك برنامج الرمز (`token_program`) هو إما SPL Token أو Token-2022، تم تحديده عند إنشاء المجموعة ببرنامج mint. تتعامل المجموعة مع الحالتين بشفافية — يمكنك تمرير معرّف برنامج الرمز الصحيح لكل جانب في حسابات تعليمات `Swap` / `Deposit` / `Withdraw`.

تفرض CPMM **قائمة سماح امتدادات صارمة** عند إنشاء المجموعة (`is_supported_mint` في `utils/token.rs`). يمكن استخدام mint Token-2022 في مجموعة CPMM فقط إذا كان **كل** امتداد يحمله موجود على هذه القائمة:

* **`TransferFeeConfig`.** يتم تطبيقه بواسطة mint في كل نقل. المجموعة على الجانب المستقبل لإيداعات `SwapBaseInput` والجانب الإرسال للانسحابات. يقوم البرنامج بحساب **الكمية الصافية** الهابطة في الخزينة ويعيّن المنحنى وفقاً لذلك. انظر [`algorithms/token-2022-transfer-fees`](/ar/algorithms/token-2022-transfer-fees).
* **`MetadataPointer`** و **`TokenMetadata`.** البيانات الوصفية المعيارية على mint. لا تأثير على رياضيات swap.
* **`InterestBearingConfig`.** يتراكم مبلغ واجهة المستخدم في mint الفائدة. الخزينة تخزن مبالغ خام؛ المنحنى يعمل على مبالغ خام فقط. يجب على الواجهات التي تعرض APR استدعاء مساعدات Token-2022 لتقديم مبلغ الواجهة.
* **`ScaledUiAmount`.** امتداد تحجيم عرض الواجهة. معاملة نفس `InterestBearingConfig` — يستخدم المنحنى مبالغ خام.

أي امتداد آخر — `PermanentDelegate`، `TransferHook`، `DefaultAccountState`، `NonTransferable`، `ConfidentialTransfer`، `Group`/`GroupMember`، `MintCloseAuthority`، إلخ. — يسبب `Initialize` في الرفض مع `NotSupportMint`. الاستثناء هو **قائمة mint بيضاء** صغيرة مشفرة في البرنامج (حفنة من pubkeys محددة) تتجاوز فحص الامتداد؛ يتم استخدامها لتوزيع mints محددة حسب الحالة.

تعيش قائمة الامتدادات المدققة وقائمة بيضاء mint في مصدر CP-Swap ضمن `programs/cp-swap/src/utils/token.rs` ويمكن أن تتغير مع ترقيات البرنامج المستقبلية.

### المراقبة

حساب المراقبة هو حلقة مخزن مؤقت لإدخالات `ObservationState`، تخزن كل واحدة `block_timestamp` و **سعر تراكمي**. في كل swap، يقوم البرنامج بإضافة ملاحظة جديدة إذا مر وقت كاف منذ آخر ملاحظة. يتم حساب TWAPs بقراءة ملاحظتين وقسم `Δcumulative / Δtime`.

```rust theme={null}
// OBSERVATION_NUM is hardcoded in the program to 100.
pub const OBSERVATION_NUM: usize = 100;

pub struct Observation {
    pub block_timestamp:              u64,
    pub cumulative_token_0_price_x32: u128,   // Q32.32, top 64 bits left for overflow
    pub cumulative_token_1_price_x32: u128,
}

pub struct ObservationState {
    pub initialized:           bool,
    pub observation_index:     u16,                            // circular index
    pub pool_id:               Pubkey,
    pub observations:          [Observation; OBSERVATION_NUM], // 100 entries
    pub last_update_timestamp: u64,                            // timestamp of the most recent append
    pub padding:               [u64; 3],
}
```

تم تحجيم حلقة المخزن المؤقت **لـ 100 ملاحظة**. كل ملاحظة هي 40 بايت، لذا الصفيف وحده هو 4,000 بايت؛ `ObservationState` PDA الكامل حوالي 4,100 بايت بعد الحقول المحيطة والمميز.

قاعدتا مستهلك:

* **لا تستخدم ملاحظة واحدة كسعر.** إنها *تراكمية*، وليست سعر فوري. استخدم اثنتين منهما لحساب TWAP.
* **اختر ملاحظات على الأقل كتلة واحدة بعيدة.** قد لا تُنتج swaps داخل نفس الكتلة ملاحظة جديدة؛ القراءة المتتالية يمكن أن تعود السجل نفسه.

المزيد من الرياضيات في [`products/clmm/accounts`](/ar/products/clmm/accounts).

## دورة حياة الحساب

| الحدث                | الحسابات التي تم إنشاؤها                                 | الحسابات المحذوفة |
| -------------------- | -------------------------------------------------------- | ----------------- |
| `Initialize`         | `poolState`، `lpMint`، `vault0`، `vault1`، `observation` | —                 |
| `Deposit`            | — (قد تنشئ ATA LP للمستخدم)                              | —                 |
| `Withdraw`           | —                                                        | —                 |
| `Swap`               | — (قد تنشئ ATA وجهة المستخدم)                            | —                 |
| `CollectProtocolFee` | —                                                        | —                 |
| `CollectFundFee`     | —                                                        | —                 |
| `UpdatePoolStatus`   | —                                                        | —                 |

المجموعات CPMM و PDAs الخاصة بها **لا تُغلق أبداً**. حتى في سيولة الصفر، `poolState` يبقى. هذا مقصود: إعادة زراعة نفس المجموعة لاحقاً تحافظ على مخزن المراقبة التاريخي و مشتقات PDA تبقى مستقرة.

## ما يجب قراءته من أين

* **قوائم حسابات التعليمات** (أيّ من الحسابات أعلاه قابلة للكتابة/موقّعة لكل تعليمة): [`products/cpmm/instructions`](/ar/products/cpmm/instructions).
* **دلالات تراكم الرسوم**: [`products/cpmm/fees`](/ar/products/cpmm/fees).
* **رياضيات swap / قاعدة تحديث المراقبة**: [`products/cpmm/math`](/ar/products/cpmm/math).
* **البذور الكنسية / معرّفات البرنامج**: [`reference/program-addresses`](/ar/reference/program-addresses).

المصادر:

* [`raydium-io/raydium-cp-swap` — PoolState, AmmConfig, ObservationState](https://github.com/raydium-io/raydium-cp-swap)
