الانتقال إلى المحتوى الرئيسي

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.

هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.عرض النسخة الإنجليزية →
كل معاملة على Solana تحدد (بشكل صريح أو ضمني) معاملين: حد وحدات الحساب (الحد الأقصى للـ CUs التي قد تستهلكها المعاملة؛ الافتراضي هو 200,000 × عدد التعليمات حتى الحد الأقصى للمعاملة) ورسم الأولوية بالميكرو-لامبورت لكل وحدة حساب. عدم تحديد حد أدنى لأي منهما يؤدي إلى فشل المعاملات — حدود CU المنخفضة جداً تسبب ProgramFailedToComplete؛ رسوم الأولوية المنخفضة جداً تجعل المعاملة معلقة حتى انتهاء صلاحيتها.

الإعدادات الاثنان

import { ComputeBudgetProgram } from "@solana/web3.js";

const tx = new Transaction()
  .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 250_000 }))
  .add(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 50_000 }))
  .add(yourRaydiumSwapIx);
  • setComputeUnitLimit(units) — يحد من الحسابات؛ تدفع المعاملة مقابل units CUs على الأكثر.
  • setComputeUnitPrice(microLamports) — عرض رسم الأولوية، بالميكرو-لامبورت لكل وحدة حساب. إجمالي رسم الأولوية = units × microLamports × 1e-6 لامبورت.
حساب التكلفة: حد 250 ألف CU بـ 50 ألف ميكرو-لامبورت/CU يعرض 250_000 × 50_000 / 1e6 = 12,500 لامبورت ≈ 0.0000125 SOL ≈ $0.003 عند $200 SOL. رسوم الأولوية بهذا الحجم لا تعني شيئاً بالنسبة لمعظم تبديلات المستخدمين ولكنها مادية للبوتات التي تنفذ 1000 معاملة/يوم.

معايير CU لكل تعليمة

معايير من سجلات التنفيذ على الشبكة الرئيسية، متوسطة عبر التشغيلات الأخيرة. الأرقام تقريبية (±15%)؛ أعد القياس لتدفقاتك المحددة.
التعليمةSPL TokenToken-2022 (بسيط)Token-2022 (رسم التحويل)
CPMM initialize_pool180,000200,000
CPMM swap_base_input140,000180,000200,000
CPMM swap_base_output150,000185,000205,000
CPMM deposit130,000160,000180,000
CPMM withdraw120,000150,000170,000
CLMM create_pool70,00085,000
CLMM open_position_v2120,000140,000160,000
CLMM increase_liquidity_v2150,000175,000195,000
CLMM decrease_liquidity_v2140,000165,000185,000
CLMM swap_v2 (0 tick crossings)170,000205,000225,000
CLMM swap_v2 (1 tick crossing)220,000255,000275,000
CLMM swap_v2 (3 tick crossings)320,000355,000375,000
CLMM collect_fee80,00095,000105,000
AMM v4 swap_base_in140,000
AMM v4 deposit120,000
AMM v4 withdraw110,000
Farm v6 create_farm70,00085,000
Farm v6 deposit (1 reward slot)130,000155,000175,000
Farm v6 deposit (3 reward slots)220,000255,000275,000
Farm v6 withdrawيطابق deposit
Farm v6 harvestيطابق deposit
Farm v3/v5 deposit100,000
LaunchLab initialize100,000
LaunchLab buy_exact_in140,000
LaunchLab graduate250,000
صف “tick crossings” لـ CLMM هو أكبر متغير CU. إذا لم تكن تعرف كم عدد الـ ticks التي ستعبرها المبادلة، احجز لأسوأ الحالات — 8 crossings هي الحد القاسي (يحمل البرنامج 8 مصفوفات tick على الأكثر).

المعاملات المركبة

اجمع الميزانيات الفردية وأضف:
  • +1,500 CU لكل CPI frame — الحد الثابت للتشغيل الزمني لكل استدعاء برنامج متقاطع.
  • +20,000 CU لكل إنشاء ATAcreate_associated_token_account ليست مجانية.
  • +5,000 CU لـ setComputeUnitLimit / setComputeUnitPrice لكل واحدة.
مثال: مبادلة مستخدم تنشئ ATA الإخراج وتلف SOL الأصلي:
wrap_sol (create_ata + system transfer + sync_native)   ≈ 30,000
CPMM swap_base_input (SPL)                              ≈ 140,000
close_account (unwrap)                                  ≈ 5,000
ComputeBudget instructions                              ≈ 10,000
────────────────────────────────────────────────────────
Total                                                   ≈ 185,000 → budget 250,000
الحشو: اضبط حد CU على حوالي 25% أعلى من الاستخدام المتوقع. عدم التقدير الكافي يكلف المعاملة بأكملها؛ الإفراط في التقدير يرفع تكلفة رسم الأولوية بشكل متناسب (رسم الأولوية هو units × microLamports، لذا فإن حوالي 25% إفراط في الميزانية يكلف 25% إضافية في رسم الأولوية).

تقدير رسم الأولوية

سوق الرسوم المحلي في Solana يعني أن رسوم الأولوية هي لكل حساب قابل للكتابة. المعاملة التي تكتب إلى حساب ساخن (حالة مجموعة شعبية) تدفع أكثر من المعاملة التي تكتب إلى حساب بارد. مستوى الرسوم العام ليس المقياس الصحيح لمبادلات Raydium؛ تريد الرسوم على المجموعات المحددة التي تلمسها.

الاستراتيجية 1: مُقدّر موفر RPC

كل موفر RPC رئيسي ينشر مُقدّر رسم أولوية يستعلم عن الرسوم الأخيرة على حسابات محددة:
// Helius
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${apiKey}`, {
  method: "POST",
  body: JSON.stringify({
    jsonrpc: "2.0",
    id:      "fee-estimate",
    method:  "getPriorityFeeEstimate",
    params: [{
      accountKeys: [poolStatePubkey.toBase58()],
      options:     { priorityLevel: "High" },
    }],
  }),
});
const { result } = await response.json();
const microLamports = result.priorityFeeEstimate;
مستويات الأولوية عبر معظم الموفرين: Min / Low / Medium / High / VeryHigh / UnsafeMax. اربطها بالنسب المئوية:
المستوىالنسبة المئويةحالة الاستخدام
Minالـ 25حركة المرور في الخلفية، بوتات غير عاجلة
Lowالـ 50مبادلات المستخدم العادية
Mediumالـ 60الافتراضي لواجهات المحفظة
Highالـ 75المراجحة الحساسة للوقت
VeryHighالـ 95التصفيات، خروج الفرصة الأخيرة
الموفرون: Helius (getPriorityFeeEstimate)، Triton (getRecentPrioritizationFees مع قائمة الحسابات)، QuickNode (مماثل).

الاستراتيجية 2: استعلام RPC مباشر

استخدم RPC معياري getRecentPrioritizationFees:
const fees = await connection.getRecentPrioritizationFees({
  lockedWritableAccounts: [poolStatePubkey],
});

// fees: Array<{ slot, prioritizationFee }>
// الـ N slots الأخيرة؛ افتراضي حوالي 150 slot.

const median = percentile(fees.map(f => f.prioritizationFee), 0.5);
هذه طريقة Solana RPC الفانيلا؛ تعمل مع أي موفر. العيب: العينة صغيرة (150 slot ≈ 60 ثانية) وضوضاء. لتقديرات أكثر سلاسة، استخدم تجميع موفر.

الاستراتيجية 3: الضبط الذاتي التاريخي

للبوتات التي تنفذ تدفقاً ثابتاً، تتبع معدلات الهبوط مقابل انتهاء الصلاحية:
هدف لكل مجموعة: معدل هبوط 80% عند <30s
إذا كان current_land_rate < 80%: priorityFee += 10%
إذا كان current_land_rate > 95%: priorityFee -= 5%
يصحح هذا نفسه بسرعة أكبر من المُقدّرات العامة ويلتقط هيكل كل مجموعة الذي لا يراه المُقدّرون العامون دائماً.

التعامل مع فشل استنزاف CU

العرض: المعاملة تفشل مع exceeded maximum number of instructions allowed (200000) أو ProgramFailedToComplete. التشخيص:
solana confirm <tx-sig> -v
# ابحث عن "consumed N of M compute units" والتعليمة التي استنزفت.
الإصلاحات:
  1. رفع حد CU. إذا كانت معاملتك تستخدم 195 ألف من ميزانية 200 ألف، ارفع إلى 300 ألف.
  2. قسّم المعاملة. إذا كنت تضرب الحد الأقصى البالغ 1.4M لكل معاملة، اقسم إلى معاملتين. harvest then stake على المزرعة نموذجي لتقسيمه عندما تكون المكافآت كثيرة.
  3. قلل الحسابات. كل حساب قابل للكتابة إضافي يضيف ~2,000 CU. تقليص الحسابات غير المستخدمة يساعد في الحالات الحدية.
  4. استخدم جداول البحث. بحث LUT هو ~50 CU لكل عنوان معاد، مما يوفر 5,000 CU لمرجع حساب كامل لكل إدخال.

التعامل مع المعاملات المعلقة

العرض: المعاملة مقدمة، لا تتأكد أبداً، تنتهي في النهاية مع BlockhashNotFound. التشخيص:
  • getSignatureStatuses([sig]) يعود null → القائد لم يرها.
  • يعود { confirmationStatus: null } → القائد رآها لكن لم يضمنها.
الإصلاحات:
  1. رفع رسم الأولوية. أعد الإرسال بـ 2× الرسم الحالي.
  2. أعد البناء مع blockhash جديد. عمر Blockhash حوالي 60 ثانية؛ بعد ذلك المعاملة غير صالحة بغض النظر عن الرسوم.
  3. بث متعدد الـ RPC. بعض RPCs لديها اتصالات قائدة أفضل من غيرها. أرسل إلى 3-5 بالتوازي.
  4. التبديل إلى Jito bundles. انظر integration-guides/routing-and-mev. تتجاوز الحزم قوائم الانتظار العامة للحزم.
هيكل عظمي لمنطق إعادة المحاولة:
async function submitWithRetry(buildTx, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const tx = await buildTx({
      priorityFee: basePriorityFee * Math.pow(1.5, attempt),
      blockhash:   (await connection.getLatestBlockhash()).blockhash,
    });

    try {
      const sig = await connection.sendRawTransaction(tx.serialize(), {
        skipPreflight: attempt > 0,  // تخطي بعد المحاولة الأولى لتوفير الكمون
      });

      const result = await connection.confirmTransaction(sig, "confirmed");
      if (result.value.err) {
        // خطأ منطقي؛ لا تعد المحاولة.
        throw result.value.err;
      }
      return sig;

    } catch (e) {
      if (isExpiredError(e)) continue;  // أعد المحاولة
      if (isRevertError(e)) throw e;    // لا تعد المحاولة؛ فشل حتمي
      throw e;
    }
  }
  throw new Error("submit: exhausted retries");
}

تحت الاختناق

عندما تكون الشبكة مختنقة (لوحات معلومات Jupiter / Jito bundle تظهر تراكماً، ارتفاع كمون RPC، معدلات انتهاء الصلاحية ترتفع)، اضبط:
المعاملالظروف العاديةالظروف المختنقة
حد CU+25% فوق التقدير+25% فوق التقدير (بدون تغيير)
نسبة مئوية رسم الأولويةالـ 50الـ 75-95
عدد المحاولات35-7
تأخير إعادة المحاولة500ms1000ms
استخدام Jito bundlesاختياريموصى به بقوة
تحديث Blockhash عند إعادة المحاولةنعمنعم، إلزامي
مراقبة إشارات الاختناق:
  • النسبة المئوية الـ 75 لرسم الأولوية > 500 ألف ميكرو-لامبورت: اختناق.
  • Jito النسبة المئوية الـ 50 للنصيحة > 0.001 SOL: اختناق.
  • RPC p99 > 2s: مشكلة خاصة بـ RPC أو اختناق.

ميزانية الرسوم للبوتات

بوت التداول الذي ينفذ ~1000 معاملة/يوم يحتاج إلى ميزانية رسم أولوية. تقدير قريب:
متوسط CU لكل معاملة:          ~250,000
النسبة المئوية الـ 50 للرسم:  ~20,000 ميكرو-لامبورت/CU
التكلفة لكل معاملة:          250_000 × 20_000 × 1e-6 = 5_000 لامبورت = 5e-6 SOL
التكلفة اليومية (1000 معاملة): 5e-3 SOL ≈ $1 @ $200 SOL
التكلفة الشهرية:             ~$30
هذا هو الحد الأدنى. أثناء الاختناق، اضرب بـ 5-10×. خطط لـ ~$150-300/شهر في رسوم الأولوية لبوت تدفق ثابت. البوتات التي يجب أن تهبط في slots محددة (التصفيات، الـ arb) تدفع النسبة المئوية الـ 95 باستمرار وتنفق ~10× أكثر. نصائح Jito bundle هيمنة على هذا الحجم — غالباً $1000+/شهر — لكن البديل (أن تكون محاطاً أو تنتهي الصلاحية) أسوأ.

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

1. نسيان حد CU

الافتراضي هو 200 ألف CUs × (التعليمات في المعاملة). مبادلة تعليمة واحدة تفترض 200 ألف؛ هذا كافٍ لـ CPMM على SPL Token لكن ليس لـ CLMM مع tick crossings أو أي شيء Token-2022. اضبطها دائماً بصراحة.

2. رسم الأولوية على الحساب الخاطئ

إذا قدرت رسم الأولوية ضد mint الرمز لكن الحساب الساخن هو حالة المجموعة، تقديرك منخفض جداً. حالة المجموعة هي حساب قابل للكتابة الصحيح لـ Raydium.

3. الرسوم تتساقط مع حد CU

total_priority_fee = units × microLamports. رفع units من 200 ألف إلى 1 مليون عند 50 ألف ميكرو-لامبورت/CU يضاعف رسم الأولوية 5×. لا تفرط في ميزانية CU فقط في الحالات؛ قيس.

4. إصدار المعاملة الافتراضي

المعاملات القديمة لديها حدود حساب أقل؛ المعاملات V0 مع جداول البحث للعناوين تفتح مسارات أكبر. يستخدم SDK V0 بشكل افتراضي في txVersion: TxVersion.V0. لا تنزل إلى legacy إلا إذا كنت تحتاج توافق المحفظة.

5. skipPreflight يخفي أخطاء CU

skipPreflight: true يرسل المعاملة بدون محاكاة محلية. توفر ~100ms لكن تخسر ردود فعل مبكرة على استنزاف CU. استخدمه فقط على إعادة المحاولات، وليس على المحاولة الأولى.

مؤشرات

المصادر: