Solana Geyser gRPC - المرشحات

Solana Stream SDK
يتم توفير Solana Stream SDK كبرنامج مفتوح المصدر. لمزيد من التفاصيل، يرجى زيارة مستودع GitHub أدناه.

نظرة عامة على مرشحات gRPC

يستخدم Solana Geyser gRPC المرشحات لجلب البيانات التي تهمك فقط بكفاءة، مثل حسابات أو برامج أو معاملات أو خانات أو كتل محددة.
فيما يلي، نقدم أمثلة TypeScript باستخدام Solana Stream SDK، مع شرح واضح للأدوار المحددة لكل مرشح. بنية المرشحات ومعناها متطابقان عند استخدام Rust.

أدوار كل مرشح وأمثلته

الاشتراك في حساب

اشترك في تحديثات الوقت الفعلي لحساب محدد. يشترك المثال التالي في حساب SOL-USDC OpenBook عند مستوى الالتزام Confirmed:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: { slots: {} },
  accounts: {
    'wsol/usdc': {
      account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.CONFIRMED,
}
  • "wsol/usdc" هو تسمية يحددها العميل.
  • يمكن دمج مرشحات متعددة للحسابات والبرامج والكتل والخانات في طلب JSON واحد.

الاشتراك في حساب مع account_data_slice

يوضح هذا المثال استرداد جزء محدد فقط من بيانات الحساب. فبدلًا من جلب البيانات الكاملة (165 بايت) لحساب توكن USDC، يسترد 40 بايت بدءًا من الإزاحة 32. يتضمن هذا النطاق معلومات مثل المالك ورصيد lamports.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {
    usdc: {
      owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
      filters: [
        {
          tokenAccountState: true,
        },
        {
          memcmp: {
            offset: 0,
            data: {
              base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
            },
          },
        },
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  commitment: CommitmentLevel.CONFIRMED,
  accountsDataSlice: [{ offset: 32, length: 40 }],
}

الاشتراك في برنامج

يوضح هذا المثال الاشتراك في تحديثات الحسابات المرتبطة ببرنامج محدد.
فيما يلي، نشترك في تحديثات الحسابات المملوكة لبرنامج Solend عند مستوى الالتزام Processed.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
  • "solend" هي تسمية مخصصة يمكن للعميل تعيينها بحرية.
  • للاشتراك في برامج متعددة، يرجى الرجوع إلى القسم التالي بعنوان "الاشتراك في برامج متعددة".

الاشتراك في برامج متعددة

يوضح هذا المثال كيفية الاشتراك في تحديثات الحسابات المرتبطة بعدة برامج دفعة واحدة.
يشترك المثال أدناه في تحديثات الحسابات المملوكة لكل من برنامجي Solend وSerum.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    programs: {
      owner: [
        'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo',
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
      ],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}
إذا كنت تفضل تعيين تسميات فردية لكل برنامج، استخدم النهج التالي:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {
    solend: {
      owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
    serum: {
      owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في جميع المعاملات النهائية غير التصويتية وغير الفاشلة

يوضح هذا المثال الاشتراك في جميع المعاملات عند مستوى الالتزام Finalized، مع استبعاد معاملات التصويت والمعاملات الفاشلة.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    alltxs: {
      vote: false,
      failed: false,
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.FINALIZED,
}
  • vote: false يستبعد معاملات التصويت.
  • failed: false يستبعد المعاملات الفاشلة.
  • إذا تُركت الحقول فارغة، يتم استرداد جميع المعاملات.
  • عند تحديد حقول متعددة، تعمل بشرط AND.

الاشتراك في المعاملات غير التصويتية التي تذكر حسابًا

يوضح هذا المثال الاشتراك في المعاملات التي تتضمن حسابًا محددًا مع استبعاد معاملات التصويت.
يشترك المثال أدناه في المعاملات غير التصويتية التي تذكر حسابات مرتبطة ببرنامج Serum.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      vote: false,
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في المعاملات مع استبعاد حسابات

يوضح هذا المثال الاشتراك في المعاملات مع استبعاد تلك التي تتضمن حسابات محددة.
يسترد المثال أدناه المعاملات مع استبعاد أي حسابات مملوكة لبرنامجي Serum وTokenkeg.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountExclude: [
        '9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
      ],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في المعاملات التي تذكر حسابات وتستبعد حسابات معينة

يوضح هذا المثال الاشتراك في المعاملات التي تتضمن حسابات معينة، مع استبعاد حسابات محددة أخرى صراحةً.
يشترك المثال أدناه في المعاملات التي تذكر حساب Serum لكنه يستبعد حسابًا محددًا:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    slots: {},
  },
  accounts: {},
  transactions: {
    serum: {
      accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
      accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في توقيع معاملة

يوضح هذا المثال الاشتراك في تحديثات الوقت الفعلي لتوقيع معاملة محدد، حتى يصل إلى حالة Confirmed أو Finalized.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {
    sign: {
      signature:
        '5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
    },
  },
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في الخانات

يوضح هذا المثال الاشتراك في إشعارات الخانات الواردة. لا يلزم أي تفاصيل إضافية سوى تعيين اسم وسم مخصص:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {
    incoming_slots: {},
  },
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في الكتل

اشترك في تحديثات الوقت الفعلي لجميع الكتل المُنشأة. افتراضيًا، سيتم استرداد جميع المعاملات داخل الكتلة:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {},
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

لاستبعاد المعاملات واسترداد معلومات الحسابات المحدثة فقط:

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      includeTransactions: false,
      includeAccounts: true,
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

لاسترداد المعاملات/الحسابات التي تتضمن حسابات محددة فقط:

typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {
    blocks: {
      accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
    },
  },
  blocksMeta: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

الاشتراك في بيانات الكتلة الوصفية

اشترك فقط في إشعارات بيانات الكتلة الوصفية عند معالجة الكتل. لا تتضمن بيانات المعاملات التفصيلية.
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

const request = {
  slots: {},
  accounts: {},
  transactions: {},
  blocks: {},
  blocksMeta: {
    blockmetadata: {},
  },
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
}

إدارة مستويات الالتزام

يتعين تدفق Solana Geyser gRPC افتراضيًا على مستوى الالتزام Processed.
يمكنك تحديد مستويات التزام أعلى مثل Confirmed أو Finalized. في هذه الحالات، يخزن Geyser البيانات مؤقتًا ويرسل الإشعارات بمجرد بلوغ مستوى الالتزام المحدد.
للحصول على أقصى أداء، يُوصى بإدارة مستوى الالتزام على جانب العميل.
إليك كيفية تحديد مستويات الالتزام:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'

enum CommitmentLevel {
  PROCESSED = 0,
  CONFIRMED = 1,
  FINALIZED = 2,
}
  • PROCESSED: بيانات فورية بعد المعالجة. استرداد سريع، لكنها غير مؤكدة بعد.
  • CONFIRMED: بيانات أكدتها المجموعة (cluster)، مما يوفر يقينًا متزايدًا.
  • FINALIZED: بيانات نهائية بالكامل دون مخاطر إعادة التنظيم.

فوائد العمل عند Processed

الميزة الرئيسية لمستوى الالتزام Processed هي الاسترداد الفوري للمعاملات، مما يتيح معالجة سريعة على جانب العميل. يمكن للعملاء لاحقًا اكتشاف الانتقالات إلى Confirmed أو Finalized، مما يوفر استجابة سريعة.

كيفية إدارة Confirmed وFinalized

عند استخدام مستويي Confirmed أو Finalized، يجب تخزين الأحداث (المعاملات أو تحديثات الحسابات) مؤقتًا لكل خانة.
خزّن الأحداث مؤقتًا خانةً بخانة، واشترك في إشعارات الخانات، وأطلق الأحداث من المخزن المؤقت بمجرد وصول خانة محددة إلى الالتزام المطلوب (Confirmed أو Finalized).
سيتم استلام الأحداث مبدئيًا قبل أن تصل الخانة إلى Confirmed أو Finalized.

الخاص بشأن Finalized

بسبب مواصفات Solana Geyser، لا تتلقى جميع الخانات إشعارات finalized صريحة. لذلك، عندما تتلقى إشعار finalized لخانة ما، يجب أن تعامل جميع الخانات الأصلية (ancestor) كخانات نهائية، حتى لو لم يتم استلام إشعارات صراحةً.
وعلى وجه التحديد، عند تلقي إشعار finalized، عامل بأثر رجعي جميع الخانات الأصلية كخانات نهائية.