هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
هذه الصفحة هي المرجع الموثوق للتعليمات. للكود الذي يؤلف هذه التعليمات فعليًا، انظر
products/cpmm/code-demos. لمعاني رموز الأخطاء انظر reference/error-codes.ترقية البرنامج 2026-09 أعادت بناء CPMM على Anchor 1.0.2 / Solana 3.1.10، وأضافت تعليمة المسؤول CollectExcessLamports، وأزالت قائمة Token-2022 mint المرمزة بشكل ثابت، وغيّرت ما تكتبه CreateAmmConfig في protocol_owner / fund_owner. لم تغيّر أي تعليمة موجهة للمستخدم حساباتها أو معاملات البرنامج أو الرياضيات. انظر إدخال السجل من 2026-09-09.ملخص التعليمات
قناع الحالة:
status كل مجموعة هو u8 حيث البت 0 = الإيداع معطل، البت 1 = السحب معطل، البت 2 = المبادلة معطلة (PoolStatusBitIndex { Deposit, Withdraw, Swap } في البرنامج). البت الواضح يعني أن العملية مسموحة؛ البت المعين يعني أنها موقوفة. تأخذ UpdatePoolStatus u8 خام وتستبدل القيمة الموجودة.
تمر الأقسام التالية عبر كل واحدة بالتفصيل. ترتيب الحسابات يتبع IDL الخاص بـ CPMM؛ SDK وعميل Rust في raydium-cp-swap/programs/cp-swap/src/instructions يطابقان هذا الترتيب.
Initialize
إنشاء مجموعة CPMM جديدة.
المعاملات
* يوقّع pool_state فقط على مسار المفتاح العشوائي؛ مسار PDA القانوني يعمل بدون توقيع pool_state.
الشروط السابقة
- يتم ترتيب الـ mints (
token_0_mint < token_1_mintحسب ترتيب البايت). - لا يستخدم أي mint امتدادًا خارج قائمة السماح بـ CPMM (
TransferFeeConfig،MetadataPointer،TokenMetadata،InterestBearingConfig،ScaledUiAmount) — انظرproducts/cpmm/accounts. يتخطى mint الذي يوجد PDASupportMintAssociatedالخاص به (البذرة[b"support_mint", mint]) فحص الامتداد — لكن يجب عليك إلحاق هذا PDA بـremaining_accounts. البرنامج يفحص فقط الحسابات التي تمررها ولا يحمل PDA بنفسه أبدًا، لذا الاعتماد على السجل بدون توفير الحساب يفشل معNotSupportMint(6007). الترتيب لا يهم (المطابقة حسب المفتاح)؛ مرر إدخالاً واحدًا لكل mint يحتاج إلى التجاوز. هذا السجل هو التجاوز الوحيد منذ أن أزالت ترقية 2026-09 قائمة الـ mint الأربعة المرمزة بشكل ثابت. - لدى
creatorعلى الأقلinit_amount_0وinit_amount_1في ATAs الخاصة. amm_config.disable_create_pool == false.
pool_state.lp_supply = sqrt(init_amount_0 * init_amount_1)— الجذر التربيعي الكامل. يتم صك المنشئlp_supply − 100؛ وحدات 100 الأساسية المقفلة تُحسب فيlp_supplyلكن لا تُصك أبدًا.- لذا
lp_mint.supply == pool_state.lp_supply − 100لحياة المجموعة. كل رياضيات حصة LP (الإيداع، السحب) تقسم علىlp_supply، لذا استخدم هذا الحقل ولا تستبدل بـ supply الـ mint على السلسلة. يعود معInitLpAmountTooLessإذا كانsqrt(...) < 100. - يتم تهيئة
observation_state؛observation_index = 0وpool_id = pool_state.key(). - يتم نقل lamports
create_pool_feeمن المنشئ إلى المستقبل ومزامنتها كـ SOL أصلي (إنها ATA wSOL). - قناع حالة المجموعة هو
0(الإيداع / السحب / المبادلة كلها مفعلة). enable_creator_fee = falseوcreator_fee_on = BothToken. لا تدعمInitializeتفعيل رسوم المنشئ — هذا المسار هوInitializeWithPermission.- يتم رفع
open_timeإلىblock_timestamp + 1إذا مرر المستدعي قيمة<= block_timestamp. يتم رفض المبادلات قبلopen_time؛ الإيداعات والسحوبات تعمل فورًا.
reference/error-codes)
InvalidInput— mints غير مرتبة، أو mints متطابقة.NotSupportMint— امتداد Token-2022 محظور.ExceededSlippage— نادرًا؛ إذا أسفرتinit_amount_0/1عن صفر LP بسبب عدم تطابق الكسور العشرية.
Deposit
إضافة السيولة في كلا الرمزين بنسبة متناسبة مع المجموعة.
المعاملات
الرياضيات
vault_amount_without_fee، أي الرصيد الخام مطروحاً منه عدادات البروتوكول والصندوق والمنشئ المتراكمة)، وليس رصيد الخزان الخام؛ وتُفحص حد الانزلاق مقابل ما يحوله الدافع فعلياً، بعد إضافة رسم نقل Token-2022، وليس مقابل حركة الخزان الإجمالية.
لا يوجد تغيير في تناسب k — يتم قياس كل من الإجماليات وlp_supply بنفس العامل.
الشروط اللاحقة
lp_supply += lp_token_amount.vault_0 += needed_token_0(صافي أي رسم نقل Token-2022 على الإدخال).vault_1 += needed_token_1(صافي أي رسم نقل Token-2022 على الإدخال).
ExceededSlippage، ZeroTradingTokens، InvalidStatus إذا كان الإيداع موقوفاً.
Withdraw
حرق رموز LP واستقبال كلا الرمزين الأساسيين بنسبة متناسبة.
المعاملات
الحسابات الثلاثة عشر الأولى متطابقة مع
Deposit، وlp_mint قابل للكتابة لأن رموز LP يتم حرقها. يأخذ Withdraw بالإضافة إلى ذلك حساباً رابع عشر، memo_program (مقيد address = memo::ID) — Deposit لا يأخذه. يفشل Withdraw بـ 13 حساباً في فك تسلسل Anchor، لذا لا يمكن لصاحب LP الخروج.
الرياضيات
lp_supply -= lp_token_amount.- تُرسل الخزانات
out_token_0/out_token_1(إجمالي؛ يستقبل المستخدم صافي أي رسم نقل Token-2022).
SwapBaseInput
مبادلة بإدخال دقيق.
المعاملات
الترتيب input → output حسب اتجاه المستخدم، وليس حسب
token_0 / token_1 الأساسي للمجموعة. يحدد البرنامج أي خزان هو أي بمطابقة الرموز.
الرياضيات — انظر products/cpmm/math.
الشروط المسبقة
open_time <= now.pool_statusيسمح بالمبادلة.- لا يوجد رمز موقوف أو مجمد لهذه السلطة.
amount_in > 0.
ExceededSlippage—amount_out < minimum_amount_out.ZeroTradingTokens— تقريب التجارة إلى صفر.NotApproved— المجموعة موقوفة للمبادلات عبرUpdatePoolStatus.InvalidInput— الرموز لا تطابق أياً من رموز خزان المجموعة.
SwapBaseOutput
مبادلة بإخراج دقيق.
المعاملات
SwapBaseInput.
الرياضيات — منحنى معكوس مع سقف، انظر products/cpmm/math.
الأخطاء الشائعة — ExceededSlippage (gross_in > max_amount_in)، ZeroTradingTokens، InvalidInput، NotApproved.
CollectProtocolFee
مسح رسوم البروتوكول المتراكمة من الخزانات إلى وجهة البروتوكول.
المعاملات — لا توجد.
الحسابات
التأثير
InvalidOwner (6001) إذا لم يكن الموقّع amm_config.protocol_owner ولا مسؤول البرنامج. (لا يوجد NotApproved على هذا المسار.)
CollectFundFee
نفس شكل CollectProtocolFee لكن موقّع بواسطة amm_config.fund_owner — أو، مرة أخرى، مسؤول البرنامج — وتصفير عدادات fund_fees_*. نفس InvalidOwner على موقّع خاطئ.
CollectCreatorFee
موقّع بواسطة pool_state.pool_creator. يسوي الرسم المتراكم للمنشئ وينقل حصة المنشئ إلى حسابات الرموز الخاصة به.
المعاملات — لا توجد.
الحسابات
التأثير
CollectProtocolFee. كلا العدادين مستثنيان بالفعل من رؤية المنحنى للخزان، لذا لا يتحرك سعر المجموعة. الاشتقاق الكامل في products/cpmm/fees.
الأخطاء الشائعة — NoFeeCollect عندما يكون كلا عدادي المنشئ صفراً (يتم الفحص قبل الانقسام)، InvalidInput (6003) إذا تجاوز share_rate المحلول 1_000_000، MathOverflow (6011) إذا كان حجز الحصة سيتجاوز protocol_fees_token_*، وخطأ ConstraintSeeds من Anchor إذا لم يكن creator_fee_share هو PDA الأساسي.
CollectCreatorFeePermissionless
يمكن لأي شخص تفعيل جمع رسوم المنشئ. تُرسل الحصة الخاصة بالمنشئ دائماً إلى حسابات الرموز المرتبطة الأساسية المملوكة لـ pool_state.pool_creator؛ لا يمكن للمستدعي اختيار منشئ أو وجهة أخرى. إذا كان أي من حسابات الرموز المرتبطة مفقوداً، يمول الدافع إنشاءه.
يبقى CollectCreatorFee الأصلي قابلاً للاستدعاء، لذا يمكن للمنشئ الذي يريد التوقيع على جمع رسومه الخاص أن يفعل ذلك.
المعاملات — لا توجد.
الحسابات
التأثير — متطابق مع
CollectCreatorFee أعلاه: يتم حل الحصة من creator_fee_share أو amm_config، يتم حجز حصة البروتوكول في protocol_fees_token_{0,1}، يتم تحويل حصة المنشئ إلى حسابات الرموز المرتبطة للمنشئ، يتم تصفير كلا عدادي المنشئ، ويتم تحديث recent_epoch. يُرجع NoFeeCollect عندما يكون كلا العدادين صفراً.
UpdatePoolStatus
إيقاف أو استئناف العمليات الفردية على مجموعة. حقل status هو قناع بت:
المعاملات
مفتاح المسؤول هو مفتاح عام مُترجم في البرنامج (
crate::admin::ID)، وليس سلطة ترقية BPF — تغييره يتطلب ترقية برنامج. انظر reference/program-addresses للقيمة و security/admin-and-multisig لمن يحتفظ بها.
CreateAmmConfig
إنشاء فئة رسوم جديدة.
المعاملات
الشروط المسبقة
- لا يوجد
AmmConfigموجود بنفسindex. protocol_fee_rate + fund_fee_rate <= FEE_RATE_DENOMINATOR_VALUE.
تم التغيير في 2026-09: مالكو الرسوم في الإعدادات الجديدة لم يعودوا يأتون من الموقّع.
create_amm_config الآن يكتب protocol_fee_owner::ID المُشفّر في البرنامج إلى protocol_owner و fund_fee_owner::ID إلى fund_owner، بدلاً من نسخ مفتاح موقّع المسؤول إلى كليهما. العناوين موجودة في reference/program-addresses.النتائج: الرسوم على AmmConfig المُنشأ حديثاً تذهب إلى محافظ الرسوم المخصصة بدلاً من محفظة المسؤول. يبقى المسؤول موقّعاً مقبولاً للجمع — CollectProtocolFee / CollectFundFee يقبلان amm_config.protocol_owner / fund_owner أو crate::admin::ID — لذا لا يتعين تدوير أي شيء للمسح؛ ما تغيّر هو فقط حيث تذهب العائدات بشكل افتراضي. حسابات AmmConfig الموجودة لم تُعاد كتابتها — ما يتم تخزينه عليها لا يزال يحكم، لذا اقرأ دائماً protocol_owner / fund_owner من الحساب بدلاً من افتراض أي قيمة. معاملات UpdateAmmConfig 3 و 4 لا تزال تدورهما.UpdateAmmConfig
تغيير معدلات الرسوم أو الملكية على AmmConfig موجود. يأخذ param: u8 (أي حقل لتحديثه) و value: u64. جدول الإرسال الكامل:
param = 0→trade_fee_rate(يؤكدtrade_fee_rate + creator_fee_rate < 1_000_000)param = 1→protocol_fee_rate(يؤكد≤ 1_000_000و+ fund_fee_rate ≤ 1_000_000)param = 2→fund_fee_rate(يؤكد≤ 1_000_000و+ protocol_fee_rate ≤ 1_000_000)param = 3→protocol_owner. المفتاح الجديد ليس فيvalue: ألحقه كـremaining_accounts[0](القراءة فقط تمام). يجب ألا يكون المفتاح العام الافتراضي، وحذف الحساب يُحدث panic علىunwrap().param = 4→fund_owner. نفس الآلية كـ3.param = 5→create_pool_feeparam = 6→disable_create_pool(أيvalueغير صفري يعطّل)param = 7→creator_fee_rate(يؤكدcreator_fee_rate + trade_fee_rate < 1_000_000)param = 8→creator_fee_share_rate(يؤكد≤ 1_000_000). أضيف 2026-09-19. حصة البروتوكول الافتراضية من رسوم المنشئ على هذه الفئة؛ انظرproducts/cpmm/fees. لا علاقة لها بـprotocol_fee_rate، الذي يقسم رسوم التداول.
param آخر يُرجع InvalidInput.
التغييرات موقّعة من قبل المسؤول وتؤثر على كل مجموعة مرتبطة بهذا AmmConfig عند المبادلة التالية. لا هجرة؛ المجموعات ببساطة تقرأ القيم الجديدة.
CreateCreatorFeeShare
تعيين حصة بروتوكول مخصصة من رسوم المنشئ لزوج واحد (creator, amm_config)، مما يتجاوز AmmConfig.creator_fee_share_rate لكل مجموعة يملكها هذا المنشئ على فئة الرسوم تلك. أضيف في ترقية حصة رسوم المنشئ 2026-09-19.
المعاملات
الشروط المسبقة
share_rate <= 1_000_000، وإلاInvalidInput(6003).- يجب ألا يكون PDA موجوداً بالفعل —
initالخاص بـ Anchor يفشل عند استدعاء ثانٍ لنفس الزوج. لتغيير معدل، أغلق الحساب وأنشئه مرة أخرى.
creator_fee_shareيخزنbump،creator،amm_configوshare_rate.- كل
CollectCreatorFee/CollectCreatorFeePermissionlessلاحق على مجموعة أنشأهاcreatorتحتamm_configيحل الحصة من هذا الحساب بدلاً من الإعدادات.
منشئ المجموعة ليس طرفاً في هذه التعليمة ولا يوقّعها. يتم قراءة المعدل في وقت الجمع، لذا يتم تطبيق تجاوز تم إنشاؤه بعد تراكم الرسوم بالفعل على هذا الرصيد المتراكم أيضاً.
CloseCreatorFeeShare
إزالة التجاوز. يعود الزوج إلى AmmConfig.creator_fee_share_rate.
المعاملات — لا توجد.
الحسابات
الشروط اللاحقة
- الحساب مُغلق وتذهب lamports الخاصة به إلى
owner. - الجمع لهذا الزوج يحل الحصة من
amm_config.creator_fee_share_rateمرة أخرى — وهي0ما لم يقم المسؤول بتعيين معاملUpdateAmmConfig8.
CollectExcessLamports
عملية مسح إداري لـ lamports المتراكمة فوق الحد الأدنى المعفي من الإيجار على الحسابات التي يتحكم بها CPMM. تمت إضافتها في ترقية 2026-09 بحيث يمكن للبروتوكول استرجاع الإفراط في التمويل الذي يتركه تقليل الإيجار SIMD-0437 على الحسابات المُنشأة قبل كل خطوة.
ينتقل الفائض فقط. أرصدة الرموز وبيانات الحساب والمالكون وحالة المجموعة والمنحنى تبقى دون تغيير، والتعليمة لا تفعل شيئًا ضد حساب بالفعل عند الحد الأدنى — لذا من الآمن إعادة تشغيلها بعد كل خطوة نشر.
الوسائط — لا توجد.
الحسابات
إصلاح الترتيب، 2026-09-19. يقوم البرنامج الآن بمسحتين على
remaining_accounts — كل CPIs برنامج الرموز أولاً، ثم الخصومات المباشرة لـ PDAs المملوكة لـ CPMM. كان الفصل بينها يؤدي إلى الإجهاض مع UnbalancedInstruction للوقت التشغيلي (“مجموع أرصدة الحساب قبل وبعد التعليمة لا تتطابق”) كلما تم خصم PDA قبل CPI، لأن التغييرات المعلقة في lamports للمتصل يتم تفريغها فقط في الحسابات التي تحملها CPI فعلاً. لا يتعين على المتصلين تجميع أو فرز القائمة بأنفسهم.owner حساب المصدر:
لأنها تأخذ قائمة
remaining_accounts غير محدودة، حجم المعاملة هو الحد الحقيقي — نفس القيد كما هو الحال في المسح من جانب المحفظة الموصوف في solana-fundamentals/rent-and-reclaimable-rent.
الأخطاء الشائعة — InvalidOwner (6001، موقّع خاطئ)، LamportsCalculateError (6015، رحلة wSOL ذهابًا وإيابًا لم تصل إلى الصفر)، و InsufficientFunds من مسار المملوك للبرنامج عندما يحتفظ الحساب بأقل من الحد الأدنى للإيجار الخاص به.
لا يوجد منشئ SDK. @raydium-io/raydium-sdk-v2 لا يشحن منشئًا لهذه التعليمة، وكذلك مستودع raydium-sdk-V2-demo — إنها مسار إداري. قم بترميزها يدويًا، بالطريقة التي يفعلها المسح من جانب المحفظة في solana-fundamentals/rent-and-reclaimable-rent لتعليمة برنامج الرموز.
مصفوفة تغيير الحالة
الخطوات التالية
products/cpmm/code-demos— عينات TypeScript قابلة للتشغيل للأعلى.reference/error-codes— جدول أخطاء Anchor الكامل.products/cpmm/fees— نموذج تراكم الرسوم الذي تستنزفه تعليماتCollect*Fee.

