هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
تقترن هذه الصفحة بـ
products/clmm/accounts (ما هي الحسابات) و products/clmm/math (ما هي الرياضيات). وهي مرجعية للمعاملات وترتيب الحسابات؛ تأتي تخطيطات البايت المحددة من IDL.أعاد ترقية البرنامج 2026-09 بناء CLMM على Anchor 1.0.2 / Solana 3.1.10، وأضاف تعليمات المسؤول CollectExcessLamports، وغيّر ما تكتبه CreateAmmConfig في owner / fund_owner. لم تغيّر أي تعليمات موجهة للمستخدم حساباتها أو معاملات أو رياضيات. انظر إدخال السجل 2026-09-30.جرد التعليمات
لا توجد تعليمة init-tick-array، ولا حاجة لها. يتم إنشاء مصفوفة علامة داخل
OpenPosition* / IncreaseLiquidity* بواسطة TickArrayState::get_or_create_tick_array، يتم دفعها بواسطة
payer. مرر PDA مصفوفة العلامة (ربما لا تزال غير مهيأة، مملوكة للنظام) كـ
tick_array_lower / tick_array_upper والبرنامج يخصصها إذا كانت مفقودة.
OpenLimitOrder يفعل الشيء نفسه لـ tick_array الواحد الخاص به.CreateAmmConfig، UpdateAmmConfig، UpdatePoolStatus، CreateOperationAccount، UpdateOperationAccount، CloseProtocolPosition) يتم التحكم فيها بواسطة مفتاح admin المشفر بقوة في البرنامج. CreatePermissionPda / ClosePermissionPda تقبل إما مفتاح admin أو مفتاح permission_pda_admin مخصص؛ CreateSupportMintAssociated / CloseSupportMintAssociated تقبل إما مفتاح admin أو مفتاح مالك support-mint مخصص؛ CollectExcessLamports تقبل إما مفتاح admin أو محفظة جمع lamports مخصصة. تعليمات مسؤول تدفق المكافآت (TransferRewardOwner، CollectRemainingRewards) يتم التحكم فيها بواسطة ممول المكافآت، وليس مسؤول البرنامج.
لاحقة V2 تعني “يدعم Token-2022 على الأقبية / NFT، يتطلب فتحة امتداد bitmap”. يختار SDK V2 بشكل افتراضي للمجمعات الجديدة.
CreatePool
المعاملات
الشروط المسبقة
token_mint_0 < token_mint_1حسب ترتيب البايت.amm_config.disable_create_pool == false.- لم يتم رفض الـ mints بواسطة قائمة السماح بامتداد Token-2022.
pool_state.sqrt_price_x64 = sqrt_price_x64،tick_current = floor(log_{1.0001}(price)).pool_state.liquidity = 0(لا توجد مراكز حتى الآن).pool_state.fee_on = FromInput(الافتراضي القديم).pool_state.dynamic_fee_infoمصفر (الرسوم الديناميكية معطلة).
CreateCustomizablePool
موصى به للمجمعات الجديدة. نفس تأثير CreatePool بالإضافة إلى وضع جمع الرسوم لكل مجمع واختيار رسوم ديناميكية اختياري.
المعاملات
CreatePool. dynamic_fee_config ليس حسابًا معلنًا.
الشروط المسبقة — نفس CreatePool. إذا كان enable_dynamic_fee = false، لا يلزم remaining_account وأي يتم تمريره يتم فحصه فقط للحصول على سجلات support-mint.
الشروط اللاحقة
pool_state.fee_onمضبوط على متغيرCollectFeeOnالمختار.- إذا تم تفعيل الرسوم الديناميكية: يتم تهيئة
pool_state.dynamic_fee_infoمنDynamicFeeConfigالمزود (خمسة معاملات معايرة مسخوخة؛ حقول الحالة مصفرة). - وإلا:
pool_state.dynamic_fee_infoمصفر (= الرسوم الديناميكية غير نشطة إلى الأبد لهذا المجمع).
fee_on وبت تفعيل الرسوم الديناميكية فقط عند إنشاء المجمع. لا توجد ترقية في المكان — لا يمكن للمجمعات التي تم إنشاؤها عبر CreatePool القديم أن تكتسب رسوم ديناميكية أو رسوم أحادية الجانب بأثر رجعي. يجب أن تستخدم النشرات الجديدة هذه التعليمة بشكل افتراضي.
CreatePermissionedPool
كل من CreatePool و CreateCustomizablePool يشتقان PDA المجمع من ["pool", amm_config, token_mint_0, token_mint_1]، لذا يوجد بالضبط عنوان مجمع قانوني واحد لكل ثلاثية (config, mint0, mint1) — محاولة init ثانية بنفس البذور تفشل. CreatePermissionedPool يرفع هذا التقييد بطي seed_index: u16 المزود من قبل العميل في بذور PDA المجمع، مما يسمح بـ مجمعات متعددة لنفس الزوج وفئة الرسوم — كل واحد في عنوانه الخاص. لأن عنوان مجمع تعسفي هو قدرة مميزة، يجب أن يحتفظ الدافع بـ PDA Permission يفوضه.
كل شيء آخر عن المجمع متطابق مع CreateCustomizablePool: يأخذ نفس CreateCustomizableParams ويدعم الرسوم أحادية الجانب واختيار الرسوم الديناميكية.
المعاملات
CreateCustomizablePool بالإضافة إلى، في الأمام:
يتم اشتقاق PDA
pool_state من ["pool", amm_config, token_mint_0, token_mint_1, seed_index.to_le_bytes()].
الشروط المسبقة
seed_index != 0.seed_indexمن0محجوز للمجمعات القديمة ويتم رفضه هنا؛ مكون البذرة[0, 0]هو ما يجعل عنوان المجمع القديم ينهار إلى الشكل الكلاسيكي ذي البذور الأربع.- PDA
permissionلـpayerموجود (تم إنشاؤه بواسطة مسؤول عبرCreatePermissionPda). - نفس قواعد mint / allow-list مثل
CreatePool.
pool_stateجديد موجود في عنوان مشتق منseed_index، معpool_state.seed_index = seed_index.- جميع حالات ما بعد الحالة الأخرى تطابق
CreateCustomizablePool(وضع الرسوم، الرسوم الديناميكية الاختيارية).
هذه التعليمة لا توسع الوصول العام لإنشاء المجمع — الإنشاء بدون إذن يستمر عبر
CreatePool / CreateCustomizablePool، والتي تبقى مجمع واحد لكل زوج. CreatePermissionedPool موجود للحالة المحددة حيث يحتاج مشغل مدرج في القائمة البيضاء إلى عدة مجمعات لنفس الزوج (على سبيل المثال، أسعار أولية مختلفة أو مجموعات إطلاق) ويحتفظ بـ PDA Permission منحه المسؤول.OpenPositionV2 / OpenPositionWithToken22Nft
إنشاء مركز جديد داخل مجمع موجود.
المعاملات
OpenPositionV2 يعلن 22؛ OpenPositionWithToken22Nft يعلن 20.
OpenPositionV2، بالترتيب:
OpenPositionWithToken22Nft هي نفس القائمة مع metadata_account (5) و metadata_program (19) محذوفة — تكتب بيانات وصفية المركز عبر امتداد البيانات الوصفية Token-2022 على NFT mint بدلاً من ذلك — مما يعطي 20 حسابًا. position_nft_mint الخاص به هو Signer عادي و position_nft_account هو UncheckedAccount.
الرياضيات — انظر products/clmm/math. بالنظر إلى base_flag، يحل البرنامج إما liquidity أو (amount_0_max, amount_1_max) إلى L الفعلي والمبالغ الفعلية للرموز المستهلكة.
الشروط المسبقة
tick_lower < tick_upper، كلاهما مضاعفاتpool.tick_spacing، ضمن[MIN_TICK, MAX_TICK].- يتم تمرير PDA مصفوفتي العلامة. لا يجب أن تكون موجودة بالفعل —
get_or_create_tick_arrayيخصص واحدة مفقودة على حسابpayerداخل هذه التعليمة. لا توجد تعليمة init-tick-array منفصلة. - يحتوي المستخدم على ما لا يقل عن
amount_0_maxوamount_1_maxفي ATAs المصدر.
personal_positionموجود،liquidityمضبوط،fee_growth_inside_lastمأخوذ لقطة.- تم تحديث إدخالات مصفوفة العلامة في
tick_lowerوtick_upper(liquidity_gross += L،liquidity_net ± L، لقطات نمو الرسوم المحفوظة). pool_state.liquidity += Lإذا كان المركز في النطاق (tick_lower ≤ tick_current < tick_upper).- يسجل NFT mint
pool_stateكسلطة تجميد. يتم إزالة سلطة الـ mint بعد صك NFT الواحد. تسجيل سلطة التجميد لا يغير حالة حساب رمز NFT. - يبقى حساب رمز NFT غير مجمد ما لم تكن التعليمة
OpenPositionV2أوOpenPositionWithToken22Nftو تطابق سلطة تجميد أي vault mint قائمة المُصدر المقيد لـ CLMM. فقط مسار V2 المطابق هذا يجمد الحساب.OpenPositionV1 لا يجمد.
TickInvalidOrder (tick_lower >= tick_upper)، TickAndSpacingNotMatch (نقطة نهاية ليست مضاعفة tick_spacing)، InvalidTickIndex (خارج [MIN_TICK, MAX_TICK])، MissingTickArrayBitmapExtensionAccount (النطاق خارج bitmap المضمن والامتداد لم يتم إلحاقه)، NotApproved (pool_state.status يمنع الفتح)، ZeroAmountSpecified.
تجميد المركز لا يضيف حسابات تعليمات معلنة أو معاملات. يمكن للعملاء فتح هذه المراكز بتخطيطات V2 الموجودة. يتم اختيار السلوك على السلسلة من
vault_0_mint و vault_1_mint.IncreaseLiquidityV2
إضافة السيولة إلى مركز مفتوح بالفعل.
المعاملات
OpenPosition: لا توجد rent، لا system_program، لا associated_token_program ولا حساب بيانات وصفية.
أضف PDA
TickArrayBitmapExtension في البداية كـ remaining_accounts[0] عندما يكون نطاق المركز خارج bitmap المضمن.
التأثير
- ينقل
amount_0_actual/amount_1_actualمن المستخدم → الأقبية. - يزيد
personal_position.liquidityوpool_state.liquidity(إذا كان في النطاق)، وإدخالات العلامة النهائيةliquidity_gross/liquidity_netوفقًا لذلك. - يجمع الرسوم والمكافآت المستحقة منذ آخر لمسة ويعتمدها على
token_fees_owed_{0,1}/reward_amount_owed. يتم دفعها فقط علىDecreaseLiquidity/DecreaseLiquidityV2، وليس على الزيادة — لا توجد تعليمة جمع مستقلة.
DecreaseLiquidityV2
إزالة السيولة من مركز.
المعاملات
IncreaseLiquidityV2: personal_position و pool_state مبدلان، الأقبية تأتي قبل مصفوفات العلامة، حسابات جانب المستخدم مسماة recipient_token_account_*، وهناك memo_program إضافي.
الحسابات المتبقية — ثلاثة لكل مكافأة نشطة يتم جمعها، بالترتيب
reward_token_vault(W)، recipient_token_account(W)، reward_vault_mint. أضف PDA TickArrayBitmapExtension عندما يكون نطاق المركز خارج bitmap المضمن.
هذا هو أيضًا الطريقة الوحيدة لجمع الرسوم والمكافآت. لجمع بدون تغيير المركز، استدعه مع
liquidity = 0، amount_0_min = 0، amount_1_min = 0.- يحسب
(amount_0, amount_1)للـLالمزال بالنظر إلىsqrt_price_x64الحالي. - يسوي الرسوم/المكافآت المتراكمة منذ آخر لمسة، نفس
IncreaseLiquidity. - ينقل
amount_0 + fees_owed_0وamount_1 + fees_owed_1خارج الأقبية إلى المستخدم. - ينقص عدادات السيولة؛ إذا كان
personal_position.liquidity == 0الجديد، يكون المركز مؤهلاً لـClosePosition.
amount_0_min و amount_1_min هما الحد الأدنى الذي يقبله المستخدم بعد خصم رسوم نقل Token-2022 على جانب الإخراج.
ClosePosition
حرق NFT المركز وإغلاق PersonalPositionState.
الحسابات المعلنة
الحسابات المتبقية
- NFT غير مجمد: لا يلزم أي شيء؛ حساب مجمع إضافي غير ضار لأن المعالج لا يقرأه.
- NFT مجمد: أضف
personal_position.pool_idكأول حساب متبقي. يحمل البرنامج كـPoolStateويستخدم بذور PDA الخاصة به للتوقيع على الإذابة.
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- جميع عدادات المكافآت
reward_amount_owed == 0.
- إذا كان حساب رمز NFT مجمدًا، تحقق من أن أول حساب متبقي يساوي
personal_position.pool_id، ثم أذبه مع PDA المجمع. - حرق NFT.
- أغلق حساب رمز NFT و
personal_position، مسترجعًا الإيجار إلىnft_owner. إذا كان NFT المركز يستخدم Token-2022، فإنه يغلق أيضًا NFT mint؛ لا يمكن إغلاق mints SPL Token الكلاسيكية وتبقى بإمداد صفر.
AccountLack عند إغلاق مركز مجمد. تمرير المجمع لكل إغلاق هي أبسط استراتيجية متوافقة.
SwapV2
المشي على منحنى السيولة؛ إدخال دقيق أو إخراج دقيق حسب is_base_input.
المعاملات
يمرر المتصلون قائمة مرتبة من مصفوفات العلامة التي تغطي مشي المبادلة المتوقع؛ يستخدم البرنامج ما يحتاجه. يحسب SDK هذه القائمة عبر
PoolUtils.computeAmountOutFormat أو نقطة نهاية الاقتباس في API.
الشروط المسبقة
pool_state.statusيسمح بالمبادلة.now >= open_time.sqrt_price_limit_x64على الجانب الصحيح منsqrt_price_x64للاتجاه.
TooLittleOutputReceived (انزلاق إدخال دقيق)، TooMuchInputPaid (انزلاق إخراج دقيق)، SqrtPriceLimitOverflow، NotEnoughTickArrayAccount، InvalidFirstTickArrayAccount، MissingTickArrayBitmapExtensionAccount، LiquidityInsufficient، NotApproved (بت المبادلة مضبوط على pool_state.status). CLMM ليس لديه متغير ExceededSlippage — هذا الاسم خاص بـ CPMM — ولا TickArrayNotFound.
ما الذي يفعله SwapV2 داخليًا والذي يجب أن يعرفه المتصلون (بعد إصدار 2025):
- رسوم ديناميكية إضافية — إذا كان
pool.dynamic_fee_infoغير صفري، يحدّث البرنامج مراكم التقلب باستخدام مسافة العلامة المقطوعة منذ آخر مبادلة (مع قواعد التصفية/الاضمحلال منproducts/clmm/fees) ويضيفdynamic_fee_componentعلى رأسAmmConfig.trade_fee_rate. إجمالي الرسوم مغطى بـ 10% (MAX_FEE_RATE_NUMERATOR / 1_000_000). - مطابقة أوامر الحد — عندما يعبر مشي السعر علامة تحتفظ بأوامر حد مفتوحة، يملأ البرنامج أولاً سيولة أوامر الحد المتاحة في تلك العلامة (FIFO حسب
order_phase)، ثم يمضي على منحنى سيولة LP. تحدّث المبالغ المملوءةtick.unfilled_ratio_x64وtick.part_filled_orders_remainingللتسوية لاحقًا؛ تبقى الأوامر نفسها غير منفقة حتى يستدعي مالكهاSettleLimitOrder. - توجيه الرسوم أحادي الجانب — عندما
pool.fee_on = Token0OnlyأوToken1Only، تحسب خطوة المبادلة نفس إدخال-إخراج التجارة؛ يتم بعد ذلك توجيه الرسوم إلى الجانب المكون. بالنسبة للاتجاهات حيث جانب الرسوم المكون هو الإخراج، يتم خصم الرسوم من إخراج المبادلة (يتلقى المستخدمout − fee)؛ بالنسبة للاتجاهات حيث يكون الإدخال، السلوك يطابقFromInput. انظرis_fee_on_input(zero_for_one)وis_fee_on_token0(zero_for_one)علىPoolState.
Swap (V1) ينفذ نفس الرسوم الديناميكية وتوجيه الرسوم أحادي الجانب ومطابقة أوامر الحد مثل SwapV2؛ الميزة الوحيدة التي ينقصها هي دعم Token-2022 — يجب أن تكون كلا الأقبية SPL Token كلاسيكية. يجب مبادلة المجمعات التي تحتوي على أي mint Token-2022 عبر SwapV2. يفضل المجمع والـ SDK بالفعل V2 لكل ساق CLMM لذا لا يضطر المتصلون إلى الفرع على نوع mint.
OpenLimitOrder
ضع أمر بيع في علامة محددة. يجلس الأمر في مجموعة FIFO لكل علامة ويملأ عندما يمشي السعر بجانبه.
المعاملات
الحسابات المتبقية —
[0] tick_array_bitmap_extension، مطلوب فقط عند تهيئة مصفوفة علامة يقع فهرس البداية الخاص بها خارج bitmap المضمن للمجمع. لا تمرر أي شيء وإلا.
تغيير قائمة الحسابات (إصدار 2026-07).
OpenLimitOrder يأخذ الآن أيضًا حسابات جانب الإخراج — output_token_account، output_vault، و output_vault_mint — بالإضافة إلى جانب الإدخال. يتم استخدامها فقط للتحقق: يرفض البرنامج الأمر إذا كان حساب رمز الإدخال أو الإخراج للمالك مجمدًا. هذا يضمن أن الملء يمكن فعلاً تسويته إلى ATA الإخراج للمالك، وهو مهم لـ mints Token-2022 المسموح بها / المجمدة بشكل افتراضي (على سبيل المثال، الرموز المرخصة) حيث قد لا يكون الحساب قد تم إذابته بعد. يجب على العملاء المبنيين مقابل قائمة الحسابات أحادية الجانب الأقدم إضافة الحسابات الثلاثة للإخراج.- لا
input_token_accountولاoutput_token_accountمجمد (وإلاNotApproved). pool_state.statusيسمح بعمليات المبادلة (بت 4) وأوامر الحد (بت 5) (وإلاNotApproved).tick_index % pool.tick_spacing == 0وضمن[MIN_TICK, MAX_TICK].tick_indexعلى الجانب الأيمن منpool.tick_currentللاتجاه المختار (بيع token0 → يجب أن تكون العلامة فوق الحالية، والعكس صحيح). البيع عند علامة تم عبورها بالفعل سيتم مطابقته فورًا ويتم رفضه.
limit_orderموجود، لقطةtick.order_phaseوtick.unfilled_ratio_x64عند وقت الفتح.tick.orders_amount += amount(في المجموعة الحالية).limit_order_nonce.order_nonce += 1.OpenLimitOrderEventمُصدر.
NotApproved (حساب رمز الإدخال أو الإخراج مجمد، أو المجمع لديه مبادلة / أوامر حد معطلة)، ZeroAmountSpecified (amount == 0 بعد رسوم نقل جانب الإدخال)، InvalidLimitOrderAmount (المبلغ سينتج إخراجًا أقل من 1 وحدة أساسية في تلك العلامة، أو تجاوز u64)، InvalidTickIndex (خارج [MIN_TICK, MAX_TICK]، أو على الجانب الخاطئ من tick_current للاتجاه المختار)، TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0)، OrderPhaseSaturated.
IncreaseLimitOrder
إضافة إلى أمر مفتوح موجود. قابل للاستدعاء فقط من قبل owner الأمر.
المعاملات
system_program.
الشروط المسبقة
limit_order.owner == signer.- الأمر لا يزال في نفس المجموعة (
tick.order_phase == limit_order.order_phase). إذا بدأت المجموعة بالفعل بالملء، يتم تسوية الأمر جزئيًا — يجب على المتصل استدعاءDecreaseLimitOrderأوSettleLimitOrderأولاً للمضي قدمًا.
- ينقل
amountمن ATA المالك إلىinput_vault. limit_order.total_amount += amount؛tick.orders_amount += amount.

