Skip to main content
هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
بيان الإصدار. جميع أمثلة TypeScript تستهدف @raydium-io/raydium-sdk-v2@0.2.64-alpha؛ تم تنفيذها آخر مرة مقابل 0.2.42-alpha (2026-04) وتم إعادة فحص توقيعات الاستدعاء الخاصة بها مقابل مصدر 0.2.64-alpha في 2026-09-09، مقابل Solana mainnet-beta. هيكل Rust CPI في النهاية يستهدف raydium-clmm على فرع chore/upgrade-anchor، Anchor 1.0.2، نفس الإصدار المثبت كما في صفحة CPMM، بحيث يمكن للاثنين أن يعيشا في صندوق واحد. master لا يزال يثبت 0.32.1. معرفات البرامج تأتي من reference/program-addresses عبر SDK.

الإعداد

كل مثال على هذه الصفحة يعكس ملف في raydium-sdk-V2-demo/src/clmm؛ رابط GitHub يجلس بجانب كل قسم. يتبع التمهيد ملف config.ts.template من مستودع العرض التوضيحي (المصدر) — disableFeatureCheck: true هو الإعداد الموصى به لأي تكامل غير تافه:

إنشاء مجمع CLMM

المصدر: src/clmm/createPool.ts
يقوم SDK بما يلي:
  • ترتيب mint1/mint2 حسب ترتيب البايت قبل الاشتقاق.
  • حساب sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • إنشاء حسابات observation و tick_array_bitmap_extension.
  • دفع رسوم إنشاء المجمع المحددة بواسطة ammConfig.

فتح مركز في نطاق محدد

المصدر: src/clmm/createPosition.ts
يحسب SDK أي مصفوفات tick يلمسها النطاق ويمررها كحسابات. لا يحتاج إلى دمج أي تعليمات init — لا توجد تعليمات init-tick-array؛ OpenPosition* تخصص مصفوفة tick مفقودة بنفسها، على حساب الدافع.

زيادة السيولة على مركز موجود

المصدر: src/clmm/increaseLiquidity.ts

تقليل السيولة (وجمع الرسوم في نفس الوقت)

المصدر: src/clmm/decreaseLiquidity.ts و src/clmm/closePosition.ts
لـ جمع الرسوم والمكافآت فقط، استدعِ decreaseLiquidity مع liquidity = new BN(0). التأثير الجانبي للتعليمة هو تسوية token_fees_owed_{0,1} و reward_amount_owed ونقلها — هذه هي الطريقة الوحيدة لجمع أي منهما. لإغلاق المركز بالكامل بعد تصفير السيولة والرسوم، مرّر ownerInfo: { closePosition: true } على استدعاء decreaseLiquidity النهائي. يضيف SDK ClosePosition ويحرق NFT.
المراكز ذات المُصدِر المقيد تتطلب منشئ إغلاق متوافق. هذه المراكز لها حساب NFT مجمد. يجب أن يضيف ClosePosition معرف المجمع للمركز كأول حساب متبقي بحيث يمكن لـ CLMM إذابة الحساب قبل حرق NFT. فرع مصدر البرنامج لا يتضمن تغيير SDK. تأكد من أن إصدار SDK الخاص بك يدعم بشكل صريح مسار الإغلاق المجمد قبل تفعيل إنشاء مركز المُصدِر المقيد.
لعميل Anchor مباشر، احتفظ بالحسابات المعلنة دون تغيير وأضف المجمع:
يمكنك تمرير poolId في كل إغلاق. يقرأه CLMM فقط عندما يكون positionNftAccount مجمدًا، مما يحافظ على مسار عميل واحد متوافق مع المراكز القديمة والجديدة.

جمع المكافآت

المصدر: src/clmm/harvestAllRewards.ts
يمشي harvestAllRewards عبر كل مركز على كل مجمع تم تمريره، ويجمع استدعاءات DecreaseLiquidity بدون سيولة التي تسوي الرسوم والمكافآت (بالإضافة إلى أي UpdateRewardInfos)، ويقسمها عبر المعاملات إذا لزم الأمر.

المبادلة

المصدر: src/clmm/swap.ts
تمشي المحاكاة عبر خريطة tick بدون اتصال بنفس منطق البرنامج على السلسلة وتعيد المبلغ (amountCalculated) بالإضافة إلى قائمة الحساب الدقيقة التي ستلمسها المبادلة (accounts). مرّر دائمًا remainingAccounts التي تعيدها المحاكاة: إذا كانت قليلة جدًا، ستعود المبادلة في منتصف المسير مع NotEnoughTickArrayAccount؛ الحسابات القديمة تهدر فقط الحساب.
PoolUtils.computeAmountOutFormat لا يزال موجودًا، لكنه يحتاج إلى ComputeClmmPoolInfo (الـ computePoolInfo من getPoolInfoFromRpc، وليس كائن مجمع API) بالإضافة إلى وسيطتين مطلوبتين أخريين — tickarrayBitmapExtension و blockTimestamp — ولا توجد طريقة raydium.clmm.fetchTickArrays (fetchTickArrays هي دالة حرة؛ المساعدات على مستوى الوحدة هي PoolUtils.fetchMultiplePoolTickArrays و tickData / tickArrays المعادة بواسطة getPoolInfoFromRpc).

إنشاء مجمع CLMM قابل للتخصيص

createCustomizablePool هي نقطة الدخول التي تعرض مفاتيح الرسوم الديناميكية والرسوم أحادية الجانب في وقت إنشاء المجمع. تأخذ شكل createPool بالإضافة إلى إضافتين:
لا توجد علامة enableDynamicFee ولا معامل dynamicFeeConfigId، ولا startTime. تمرير dynamicFeeConfig هو ما يفعّل الرسوم الديناميكية — حذفه وستحصل على مجمع برسوم ثابتة، بدون خطأ. لاحظ أيضًا أن أعضاء تعداد SDK هي TokenOnlyA / TokenOnlyB، بينما تكتبها قائمة Rust على السلسلة Token0Only / Token1Only؛ القيم الرقمية متطابقة (FromInput = 0).
يستمر createPool في العمل لمسار الرسوم الافتراضية بدون رسوم ديناميكية. استخدم createCustomizablePool كلما احتجت إلى أي مفتاح. انظر products/clmm/instructions لقائمة الحساب على السلسلة.

أوامر الحد

يوقف أمر الحد إدخال المستخدم عند tick واحد ويتم ملؤه FIFO عندما تعبر مبادلة هذا الـ tick. يتم دفع المخرجات إلى ATA المالك في وقت التسوية؛ لا يحتاج المالك إلى أن يكون متصلاً ليتم ملؤه.

فتح أمر حد

يشتق SDK LimitOrderState PDA من (owner, nonce PDA, order nonce)، ويرفع LimitOrderNonce لكل محفظة، ويدرج الأمر في مجموعة FIFO في هذا الـ tick.

زيادة / تقليل أمر مفتوح

يمكن لـ decreaseLimitOrder فقط إزالة من الجزء غير المملوء من الأمر؛ الجزء المملوء مقفول حتى التسوية. كلا التعليمتين تعودان مع InvalidOrderPhase إذا تم ملء الأمر بالكامل بالفعل.

تسوية أمر مملوء

يقرأ settleLimitOrder unfilled_ratio_x64 للأمر مقابل متتبع المجموعة، ويحسب المخرجات المملوءة، وينقلها إلى ATA المالك. يمكن للمالك استدعاء هذا بنفسه؛ limit_order_admin (حارس تشغيلي بدون اتصال) يمكنه أيضًا استدعاؤه نيابة عن المالك — المخرجات لا تزال تذهب إلى المالك. لإغلاق الأوامر المسوّاة بالكامل لاسترجاع الإيجار، استخدم closeLimitOrder (واحد) أو closeAllLimitOrder (دفعة). لتسوية الكثير في وقت واحد، يجمع settleAllLimitOrder استدعاءات SettleLimitOrder قدر الإمكان في معاملة v0.

قائمة أوامر المحفظة المتوقفة (بدون اتصال)

تعيد نقطة نهاية الأوامر النشطة الأوامر غير المملوءة والمملوءة جزئيًا في حمولة واحدة (totalAmount / filledAmount / pendingSettle تميز المراحل). لسجل الأوامر المغلقة استخدم /limit-order/history/order/list-by-user?wallet=… (لكل محفظة، مرقمة حسب nextPageId)؛ لسجل الأحداث الكامل لأمر معين استخدم /limit-order/history/event/list-by-pda?pda=….

هيكل Rust CPI

ترتيب الحساب المتبقي لـ SwapV2:
إذا لم تحتج المبادلة أبدًا إلى الامتداد، حذفه؛ وإلا فهو أول حساب متبقي.

الأخطاء الشائعة

  • نقاط نهاية tick خارج المسافة → TickAndSpacingNotMatch. قم دائمًا بالمحاذاة عبر TickUtil.getPriceAndTick (singular TickUtil).
  • عدم توفير مصفوفات tick كافية في SwapV2 → NotEnoughTickArrayAccount. خذ القائمة من swapInternal(...).accounts.
  • مركز النطاق الكامل بدون امتداد bitmap → يجب أن يكون PDA الامتداد قابلاً للكتابة؛ يتعامل SDK مع هذا تلقائيًا.
  • الخلط بين sqrt_price_x64 و price → الالتباس بمعامل 2 هنا مؤلم بشكل خاص. عند الشك، دع SDK يحسبه من سعر يمكن قراءته بواسطة الإنسان.
  • جمع المكافآت بحماس شديد → كل جمع هو DecreaseLiquidity بدون سيولة ويكلف معاملة واحدة. جمّع عبر harvestAllRewards عبر العديد من المراكز، وتذكر أن execute الخاص به يحتاج إلى { sequentially: true }.
  • إغلاق حسابات NFT بنفسك → ClosePosition يحرق NFT ويغلق ATA الخاص به. كما يغلق mint NFT Token-2022؛ يبقى mint SPL Token الكلاسيكي عند صفر الإمداد لأن هذا البرنامج لا يمكنه إغلاق mints. لا تغلق الحسابات المدعومة بشكل منفصل أو ستعود التعليمة.
  • فتح أمر حد عند tick غير متباعد → TickAndSpacingNotMatch. قم دائمًا بتحديد الكمية عبر مساعد getOrderTick المُصدَّر.
  • استدعاء decreaseLimitOrder على أمر مملوء بالكامل → InvalidOrderPhase. استخدم settleLimitOrder ثم closeLimitOrder بدلاً من ذلك.
  • توقع علامة enableDynamicFee → لا توجد. حذف dynamicFeeConfig ببساطة ينشئ مجمع برسوم ثابتة، بصمت وبدون خطأ. إذا كنت تريد رسوم ديناميكية، مرّر PublicKey حساب الإعدادات، المختار من /main/clmm-dynamic-config.

الخطوات التالية

المصادر: