إجراءات سولانا هي واجهات برمجية متوافقة مع المواصفات تُعيد معاملات على بلوكتشين سولانا لمعاينتها والتوقيع عليها وإرسالها عبر سياقات متعددة، تشمل رموز QR والأزرار والعناصر المصغّرة والمواقع الإلكترونية عبر الإنترنت. تُسهّل الإجراءات على المطورين دمج كل ما يمكن القيام به داخل منظومة سولانا مباشرةً في بيئتهم، مما يتيح لهم تنفيذ معاملات البلوكتشين دون الحاجة إلى مغادرة التطبيق أو صفحة الويب الحالية.
روابط البلوكتشين – أو الومضات – تحوّل أي إجراء من إجراءات سولانا إلى رابط قابل للمشاركة غني بالبيانات الوصفية. تتيح الومضات للعملاء المتوافقين مع الإجراءات (مثل امتدادات المتصفح للمحافظ والبوتات) عرض إمكانيات إضافية للمستخدم. على موقع ويب، قد تُطلق الومضة معاينةً فورية للمعاملة في المحفظة دون الانتقال إلى تطبيق لامركزي؛ وفي Discord، قد يحوّل البوت الومضةَ إلى مجموعة تفاعلية من الأزرار. هذا يمنح القدرة على التفاعل مع البلوكتشين لأي سطح ويب قادر على عرض رابط URL.
ابدأ الآن
للبدء السريع في إنشاء إجراءات سولانا المخصصة:
npm install @solana/actions
- ثبّت حزمة SDK لإجراءات سولانا في تطبيقك
- أنشئ نقطة نهاية API لـ طلب GET تُعيد البيانات الوصفية الخاصة بإجراءك
- أنشئ نقطة نهاية API تقبل طلب POST وتُعيد المعاملة القابلة للتوقيع للمستخدم
اطّلع على هذا الدرس المرئي حول كيفية بناء إجراء سولانا باستخدام حزمة SDK
@solana/actions.يمكنك أيضاً الاطلاع على الكود المصدري لإجراء يُنفّذ تحويل SOL الأصلي هنا، إلى جانب عدة إجراءات نموذجية أخرى في هذا المستودع.
عند نشر إجراءات سولانا المخصصة في بيئة الإنتاج:
- تأكّد من أن تطبيقك يحتوي على ملف actions.json صالح في الجذر الأساسي لنطاقك
- تأكّد من أن تطبيقك يُرسل
ترويسات Cross-Origin المطلوبة على جميع نقاط نهاية الإجراءات،
بما فيها ملف
actions.json - اختبر ومضاتك وإجراءاتك وتحقق منها باستخدام Blinks Inspector
إن كنت تبحث عن أفكار لبناء الإجراءات والومضات، اطّلع على مستودع Awesome Blinks للاستلهام من إبداعات المجتمع، بل و اقتراح أفكار جديدة.
الإجراءات
تستخدم مواصفة إجراءات سولانا مجموعة من الواجهات البرمجية القياسية لتوصيل المعاملات القابلة للتوقيع (وفي نهاية المطاف الرسائل القابلة للتوقيع) من تطبيق ما مباشرةً إلى المستخدم. تُستضاف على عناوين URL يمكن الوصول إليها علنياً، وبالتالي يمكن لأي عميل التفاعل معها عبر عنوان URL الخاص بها.
يمكنك التفكير في الإجراءات باعتبارها نقطة نهاية API تُعيد بيانات وصفية و شيئاً ما يوقّعه المستخدم (سواء معاملة أو رسالة مصادقة) باستخدام محفظته على البلوكتشين.
تتألف واجهة برمجة الإجراءات من إرسال طلبات GET وPOST بسيطة إلى نقطة نهاية URL الخاصة بالإجراء، ومعالجة الاستجابات المتوافقة مع واجهة الإجراءات.
- يُعيد طلب GET بيانات وصفية تُقدّم معلومات مقروءة للعميل حول الإجراءات المتاحة على هذا الرابط، إلى جانب قائمة اختيارية بالإجراءات ذات الصلة.
- يُعيد طلب POST معاملةً أو رسالةً قابلةً للتوقيع يطلب العميل بعدها من محفظة المستخدم التوقيعَ عليها وتنفيذها على البلوكتشين أو في خدمة أخرى خارج السلسلة.
تنفيذ الإجراء ودورة حياته
عملياً، يشبه التفاعل مع الإجراءات إلى حدٍّ بعيد التفاعلَ مع واجهة REST API اعتيادية:
- يُرسل العميل طلب
GETالأولي إلى رابط URL الخاص بالإجراء للحصول على البيانات الوصفية المتعلقة بالإجراءات المتاحة - تُعيد نقطة النهاية استجابةً تتضمن بيانات وصفية عنها (كعنوان التطبيق وأيقونته) وقائمة بالإجراءات المتاحة لهذه النقطة
- يعرض تطبيق العميل (كمحفظة الهاتف المحمول أو البوت الدردشي أو الموقع الإلكتروني) واجهة مستخدم تُمكّن المستخدم من تنفيذ أحد الإجراءات
- بعد أن يختار المستخدم إجراءً (بالنقر على زر)، يُرسل العميل
طلب
POSTإلى نقطة النهاية للحصول على المعاملة التي يوقّعها المستخدم - تُيسّر المحفظة توقيع المستخدم على المعاملة وتُرسلها في نهاية المطاف إلى البلوكتشين للتأكيد
تنفيذ إجراءات سولانا ودورة حياتها
عند تلقّي المعاملات من رابط URL الخاص بالإجراءات، يجب على العملاء معالجة إرسال هذه المعاملات إلى البلوكتشين وإدارة دورة حياتها.
تدعم الإجراءات أيضاً مستوىً معيناً من الإلغاء قبل التنفيذ. قد يُعيد طلبا GET وPOST بعض البيانات الوصفية التي تُشير إلى ما إذا كان الإجراء قابلاً للتنفيذ (كما هو الحال مع حقل disabled).
على سبيل المثال، إذا كان هناك نقطة نهاية لإجراء تُتيح التصويت على مقترح حوكمة DAO انتهت نافذة التصويت عليه، فقد يُعيد طلب GET الأولي رسالة الخطأ "هذا المقترح لم يعد مطروحاً للتصويت" وتظهر زرّا "التصويت بنعم" و"التصويت بلا" بحالة "معطّل".
الومضات
الومضات (روابط البلوكتشين) هي تطبيقات عميل تستكشف واجهات برمجة الإجراءات وتبني واجهات مستخدم حولها للتفاعل مع الإجراءات وتنفيذها.
تطبيقات العميل التي تدعم الومضات تكتشف ببساطة عناوين URL المتوافقة مع الإجراءات وتُحللها، وتتيح للمستخدمين التفاعل معها من خلال واجهات مستخدم موحّدة.
أي تطبيق عميل يستكشف واجهة برمجة الإجراءات بالكامل لبناء واجهة متكاملة لها هو ومضة. لذلك، ليس كل عميل يستهلك واجهات برمجة الإجراءات يُعدّ ومضةً.
مواصفة رابط الومضة
يصف رابط الومضة تطبيق عميل يُمكّن المستخدم من إتمام دورة حياة تنفيذ إجراء كاملة، بما في ذلك التوقيع باستخدام محفظته.
https://example.domain/?action=<action_url>
لكي يتحوّل أي تطبيق عميل إلى ومضة:
-
يجب أن يحتوي رابط الومضة على معامل استعلام
actionتكون قيمته رابط إجراء مشفّراً بتنسيق URL. يجب أن تكون هذه القيمة مشفّرة بصيغة URL حتى لا تتعارض مع معاملات البروتوكول الأخرى. -
يجب على تطبيق العميل فكّ تشفير URL لمعامل الاستعلام
actionواستكشاف رابط واجهة برمجة الإجراءات المُقدَّم (انظر مخطط رابط الإجراء). -
يجب على العميل عرض واجهة مستخدم غنية تُمكّن المستخدم من إتمام دورة حياة تنفيذ الإجراء كاملةً، بما في ذلك التوقيع باستخدام محفظته.
لن تدعم جميع تطبيقات عملاء الومضات (مثل المواقع الإلكترونية أو التطبيقات اللامركزية) كلَّ الإجراءات. قد يختار مطوّرو التطبيقات الإجراءاتِ التي يرغبون في دعمها ضمن واجهات الومضات الخاصة بهم.
يوضّح المثال التالي رابط ومضة صالحاً بقيمة action تساوي
solana-action:https://actions.alice.com/donate مشفّرةً بصيغة URL:
https://example.domain/?action=solana-action%3Ahttps%3A%2F%2Factions.alice.com%2Fdonate
اكتشاف الإجراءات عبر الومضات
يمكن ربط الومضات بالإجراءات بثلاث طرق على الأقل:
-
مشاركة رابط إجراء صريح:
solana-action:https://actions.alice.com/donateفي هذه الحالة، يستطيع العرضَ العملاءُ المدعومون فقط. لن يكون هناك معاينة رابط احتياطية أو موقع يمكن زيارته خارج العميل غير الداعم.
-
مشاركة رابط لموقع إلكتروني مرتبط بواجهة برمجة الإجراءات عبر ملف
actions.jsonفي الجذر الأساسي لنطاق الموقع.على سبيل المثال، يُعيّن
https://alice.com/actions.jsonالرابطَhttps://alice.com/donate، وهو رابط الموقع الذي يمكن للمستخدمين من خلاله التبرع لأليس، إلى رابط API هوhttps://actions.alice.com/donate، حيث تُستضاف إجراءات التبرع لأليس. -
تضمين رابط إجراء في رابط موقع "انتقالي" يفهم كيفية تحليل الإجراءات.
https://example.domain/?action=<action_url>
يجب على العملاء الذين يدعمون الومضات القدرةَ على استقبال أي من الصيغ المذكورة أعلاه وعرض واجهة صحيحة تُتيح تنفيذ الإجراء مباشرةً في العميل.
بالنسبة للعملاء الذين لا يدعمون الومضات، يجب أن يكون هناك موقع إلكتروني أساسي (يجعل المتصفح يمثّل الملاذ الاحتياطي الشامل).
إذا نقر المستخدم في أي مكان على العميل لا يكون زر إجراء أو حقل إدخال نصي، يجب أن يُنقل إلى الموقع الأساسي.
اختبار الومضات والتحقق منها
بينما تُعدّ إجراءات سولانا والومضات بروتوكولاً/مواصفةً مفتوحة لا تتطلب إذناً، لا تزال تطبيقات العميل والمحافظ مُلزَمة في نهاية المطاف بتسهيل توقيع المستخدمين على المعاملات.
استخدم أداة Blinks Inspector لفحص ومضاتك وإجراءاتك وتصحيحها واختبارها مباشرةً في متصفحك. يمكنك عرض حمولات استجابة GET وPOST وترويسات الاستجابة، واختبار جميع المدخلات لكل إجراء من إجراءاتك المرتبطة.
قد تختلف متطلبات كل تطبيق عميل أو محفظة فيما يخص نقاط نهاية الإجراءات التي سيعرضها عميلها تلقائياً ويُظهرها فوراً للمستخدمين على منصات التواصل الاجتماعي.
على سبيل المثال، قد تعتمد بعض العملاء نهج "القائمة البيضاء" الذي قد يستلزم التحقق قبل أن يعرض العميل إجراءً للمستخدمين، كما هو الحال مع سجل إجراءات Dialect (المفصّل أدناه).
ستظل جميع الومضات تُعرض وتتيح التوقيع على موقع الومضات الانتقالي dial.to الخاص بـ Dialect، مع عرض حالة تسجيلها في الومضة.
سجل إجراءات Dialect
كمنفعة عامة لمنظومة سولانا، تحتفظ Dialect بسجل عام — بالتعاون مع مؤسسة سولانا وأعضاء المجتمع الآخرين — لروابط البلوكتشين الصادرة من مصادر معروفة والتي تم التحقق منها مسبقاً. منذ الإطلاق، لن تنتشر في خلاصة تويتر إلا الإجراءات المسجّلة في سجل Dialect.
يمكن لتطبيقات العميل والمحافظ اختيار استخدام هذا السجل العام أو حلٍّ آخر لضمان أمان المستخدمين وسلامتهم. إن لم يُتحقق منه عبر سجل Dialect، فلن يتعامل عميل الومضة مع رابط البلوكتشين وسيُعرض كرابط URL عادي.
يمكن للمطورين التقدم للتحقق من قِبَل Dialect هنا: dial.to/register
المواصفة
تتألف مواصفة إجراءات سولانا من أقسام رئيسية تُشكّل جزءاً من تدفق التفاعل بطلب/استجابة:
- مخطط URL لإجراء سولانا يُقدّم رابط الإجراء
- استجابة OPTIONS إلى رابط إجراء لتلبية متطلبات CORS
- طلب GET إلى رابط إجراء
- استجابة GET من الخادم
- طلب POST إلى رابط إجراء
- استجابة POST من الخادم
يتم تقديم كل هذه الطلبات من قِبل عميل الإجراء (مثل: تطبيق المحفظة، أو إضافة المتصفح، أو التطبيق اللامركزي، أو الموقع الإلكتروني، وغيرها) لجمع بيانات وصفية محددة لواجهات مستخدم غنية، وتسهيل إدخال المستخدم إلى واجهة برمجة تطبيقات الإجراءات.
يتم صياغة كل الاستجابات من قِبل تطبيق ما (مثل: موقع إلكتروني، أو خادم خلفي، وغيرها) وإعادتها إلى عميل الإجراء. وفي نهاية المطاف، يتم توفير معاملة أو رسالة قابلة للتوقيع لتطبيق المحفظة لمطالبة المستخدم بالموافقة عليها وتوقيعها وإرسالها إلى البلوك تشين.
الأنواع والواجهات المُعلَنة في ملفات readme هي في الغالب نسخة مبسّطة من الأنواع لتسهيل القراءة.
للحصول على أمان أفضل للأنواع وتجربة مطوّر محسّنة، تحتوي حزمة
@solana/actions-specعلى تعريفات أنواع أكثر تعقيدًا. يمكنك الاطلاع على الكود المصدري الخاص بها هنا.
مخطط URL
يصف رابط إجراء سولانا طلبًا تفاعليًا للحصول على معاملة أو رسالة سولانا قابلة للتوقيع باستخدام بروتوكول solana-action.
الطلب تفاعلي لأن المعاملات الواردة في الرابط يستخدمها العميل لتقديم سلسلة من طلبات HTTP المعيارية لتأليف معاملة أو رسالة قابلة للتوقيع للمستخدم كي يوقّعها بواسطة محفظته.
solana-action:<link>
-
يُشترط وجود حقل
linkواحد كمسار. يجب أن تكون القيمة رابط HTTPS مطلقًا مُرمَّزًا بـ URL بشكل مشروط. -
إذا كان الرابط يحتوي على معاملات استعلام، يجب أن يكون مُرمَّزًا بـ URL. إذ يمنع ترميز URL للقيمة أي تعارض مع معاملات بروتوكول الإجراءات، التي قد تُضاف عبر مواصفات البروتوكول.
-
إذا كان الرابط لا يحتوي على معاملات استعلام، فلا ينبغي ترميزه بـ URL. وهذا ينتج رابطًا أقصر ورمز QR أقل كثافة.
في كلتا الحالتين، يجب على العملاء فك ترميز URL للقيمة. ولا يؤثر ذلك إذا لم تكن القيمة مُرمَّزة بـ URL. وإذا لم تكن القيمة المفكوكة رابط HTTPS مطلقًا، يجب على المحفظة رفضها باعتبارها غير صحيحة.
استجابة OPTIONS
للسماح بمشاركة الموارد عبر الأصول
(CORS) داخل عملاء الإجراءات
(بما في ذلك blinks)، يجب أن تستجيب جميع نقاط نهاية الإجراءات لطلبات HTTP
الخاصة بالطريقة OPTIONS برؤوس صالحة تتيح للعملاء اجتياز فحوصات CORS
لجميع الطلبات اللاحقة الصادرة من نفس نطاق أصلهم.
قد يُجري عميل الإجراء طلبات
"preflight"
إلى نقطة نهاية رابط الإجراء للتحقق مما إذا كان طلب GET اللاحق
إلى رابط الإجراء سيجتاز جميع فحوصات CORS. تُجرى فحوصات CORS الاستباقية هذه
باستخدام طريقة HTTP OPTIONS ويجب أن تستجيب بجميع رؤوس HTTP المطلوبة
التي ستتيح لعملاء الإجراءات (مثل blinks) تقديم جميع الطلبات اللاحقة بشكل صحيح من نطاق أصلهم.
كحد أدنى، تشمل رؤوس HTTP المطلوبة:
Access-Control-Allow-Originبقيمة*- يضمن ذلك أن جميع عملاء الإجراءات يمكنهم اجتياز فحوصات CORS بأمان لتقديم جميع الطلبات المطلوبة
Access-Control-Allow-MethodsبقيمةGET,POST,PUT,OPTIONS- يضمن دعم جميع طرق طلبات HTTP المطلوبة للإجراءات
Access-Control-Allow-Headersبقيمة دنيا تشملContent-Type, Authorization, Content-Encoding, Accept-Encoding
لتبسيط الأمور، ينبغي للمطوّرين النظر في إعادة نفس الاستجابة والرؤوس
لطلبات OPTIONS كما في استجابة GET.
رؤوس Cross-Origin لملف actions.json
يجب أن تُعيد استجابة ملف actions.json أيضًا رؤوس Cross-Origin صالحة لطلبات
GET وOPTIONS، وتحديدًا قيمة رأس Access-Control-Allow-Origin بـ *.
راجع actions.json أدناه لمزيد من التفاصيل.
طلب GET
يجب على عميل الإجراء (مثل: المحفظة، أو إضافة المتصفح، وغيرها) تقديم طلب HTTP
GET بصيغة JSON إلى نقطة نهاية رابط الإجراء.
- يجب ألا يُعرِّف الطلب المحفظةَ أو المستخدم.
- يجب على العميل تقديم الطلب مع
رأس
Accept-Encoding. - يجب على العميل عرض نطاق الرابط أثناء تقديم الطلب.
استجابة GET
يجب أن تستجيب نقطة نهاية رابط الإجراء (مثل: التطبيق أو الخادم الخلفي) باستجابة HTTP OK بصيغة JSON (مع حمولة صالحة في الجسم) أو بخطأ HTTP مناسب.
-
يجب على العميل معالجة أخطاء العميل، وأخطاء الخادم، و استجابات إعادة التوجيه.
-
يجب أن تستجيب نقطة النهاية بـ رأس
Content-Encodingلضغط HTTP. -
يجب أن تستجيب نقطة النهاية بـ رأس
Content-Typeبقيمةapplication/json. -
يجب على العميل عدم تخزين الاستجابة مؤقتًا إلا وفقًا لتعليمات رؤوس استجابة التخزين المؤقت HTTP.
-
يجب على العميل عرض
titleوتصيير صورةiconللمستخدم.
يجب أن تُعيد استجابات الأخطاء (أي رموز حالة HTTP 4xx و5xx) جسم استجابة JSON وفق ActionError لتقديم رسالة خطأ مفيدة للمستخدمين. راجع أخطاء الإجراءات.
جسم استجابة GET
يجب أن تتضمن استجابة GET بـ HTTP OK بصيغة JSON حمولة في الجسم تتبع مواصفات الواجهة:
export type ActionType = "action" | "completed";export type ActionGetResponse = Action<"action">;export interface Action<T extends ActionType> {/** type of Action to present to the user */type: T;/** image url that represents the source of the action request */icon: string;/** describes the source of the action request */title: string;/** brief summary of the action to be performed */description: string;/** button text rendered to the user */label: string;/** UI state for the button being rendered to the user */disabled?: boolean;links?: {/** list of related Actions a user could perform */actions: LinkedAction[];};/** non-fatal error message to be displayed to the user */error?: ActionError;}
-
type- نوع الإجراء المُقدَّم للمستخدم. القيمة الافتراضية هيaction. يجب أن يحتويActionGetResponseالأولي على نوعaction.action- إجراء قياسي يتيح للمستخدم التفاعل مع أيٍّ منLinkedActionscompleted- يُستخدم للإعلان عن حالة "مكتمل" ضمن تسلسل الإجراءات.
-
icon- يجب أن تكون القيمة رابط HTTP أو HTTPS مطلقًا لصورة أيقونة. يجب أن يكون الملف صورة SVG أو PNG أو WebP، وإلا وجب على العميل/المحفظة رفضه باعتباره غير صحيح. -
title- يجب أن تكون القيمة سلسلة نصية بترميز UTF-8 تمثّل مصدر طلب الإجراء. على سبيل المثال، قد تكون اسم علامة تجارية، أو متجر، أو تطبيق، أو شخص يُقدّم الطلب. -
description- يجب أن تكون القيمة سلسلة نصية بترميز UTF-8 تُقدّم معلومات حول الإجراء. يجب عرض الوصف للمستخدم. -
label- يجب أن تكون القيمة سلسلة نصية بترميز UTF-8 ستُعرض على زر لنقر المستخدم عليه. يجب ألا تتجاوز جميع التسميات 5 كلمات وأن تبدأ بفعل لتوضيح الإجراء المطلوب من المستخدم. على سبيل المثال، "Mint NFT"، أو "Vote Yes"، أو "Stake 1 SOL". -
disabled- يجب أن تكون القيمة منطقية (boolean) للتعبير عن حالة التعطيل للزر المُصيَّر (الذي يعرض سلسلةlabel). إذا لم تُقدَّم أي قيمة، يجب أن يكونdisabledافتراضيًاfalse(أي مُفعَّل بشكل افتراضي). على سبيل المثال، إذا كانت نقطة نهاية الإجراء لتصويت حوكمة قد أُغلق، اضبطdisabled=trueويمكن أن تكونlabelهي "Vote Closed". -
error- إشارة اختيارية للأخطاء غير الحرجة. إذا كانت موجودة، يجب على العميل عرضها للمستخدم. إذا تم ضبطها، يجب ألا تمنع العميل من تفسير الإجراء أو عرضه للمستخدم (راجع أخطاء الإجراءات). على سبيل المثال، يمكن استخدام الخطأ معdisabledلعرض سبب كقيود تجارية، أو تفويض، أو الحالة، أو خطأ في مورد خارجي. -
links.actions- مصفوفة اختيارية من الإجراءات ذات الصلة بنقطة النهاية. يجب عرض واجهة المستخدم لكل من الإجراءات المُدرَجة وتوقُّع تنفيذ المستخدم لإجراء واحد فقط. على سبيل المثال، قد تُعيد نقطة نهاية إجراء تصويت الحوكمة ثلاثة خيارات للمستخدم: "Vote Yes"، و"Vote No"، و"Abstain from Vote".-
إذا لم يُقدَّم
links.actions، يجب على العميل تصيير زر واحد باستخدام سلسلةlabelالجذرية وتقديم طلب POST إلى نفس نقطة نهاية رابط الإجراء كطلب GET الأولي. -
إذا قُدِّم أي من
links.actions، يجب على العميل تصيير الأزرار وحقول الإدخال بناءً فقط على العناصر المُدرَجة في حقلlinks.actions. يجب على العميل عدم تصيير زر لمحتوىlabelالجذري.
-
export interface LinkedAction {/** Type of action to be performed by user */type: LinkedActionType;/** URL endpoint for an action */href: string;/** button text rendered to the user */label: string;/*** Parameters to accept user input within an action* @see {ActionParameter}* @see {ActionParameterSelectable}*/parameters?: Array<TypedActionParameter>;}
يتيح ActionParameter الإعلان عن نوع الإدخال الذي تطلبه واجهة برمجة تطبيقات الإجراءات من المستخدم:
/*** Parameter to accept user input within an action* note: for ease of reading, this is a simplified type of the actual*/export interface ActionParameter {/** input field type */type?: ActionParameterType;/** parameter name in url */name: string;/** placeholder text for the user input field */label?: string;/** declare if this field is required (defaults to `false`) */required?: boolean;/** regular expression pattern to validate user input client side */pattern?: string;/** human-readable description of the `type` and/or `pattern`, represents a caption and error, if value doesn't match */patternDescription?: string;/** the minimum value allowed based on the `type` */min?: string | number;/** the maximum value allowed based on the `type` */max?: string | number;}
يجب أن يكون pattern سلسلة نصية تعادل تعبيرًا نمطيًا صالحًا. يجب أن يستخدم عملاء blink هذا النمط للتحقق من صحة مدخلات المستخدم قبل تقديم طلب POST. إذا لم يكن pattern تعبيرًا نمطيًا صالحًا، يجب على العملاء تجاهله.
يُعدّ patternDescription وصفًا بلغة بشرية مقروءة للإدخال المتوقع من المستخدم. إذا تم توفير pattern، يصبح توفير patternDescription إلزاميًا.
تتيح قيم min وmax ضبط حدٍّ أدنى و/أو أقصى للإدخال المطلوب من المستخدم (أي الحد الأدنى/الأقصى للرقم و/أو طول الأحرف)، ويجب استخدامها للتحقق من الصحة على جانب العميل. لأنواع الإدخال type من date أو datetime-local، يجب أن تكون هذه القيم سلاسل تواريخ. لأنواع الإدخال النصية الأخرى، يجب أن تكون القيم أرقامًا تمثّل الحد الأدنى/الأقصى لطول الأحرف.
إذا لم تكن قيمة إدخال المستخدم صالحة وفق pattern، يجب أن يتلقى المستخدم رسالة خطأ على جانب العميل تُشير إلى أن حقل الإدخال غير صالح وتعرض سلسلة patternDescription.
يتيح حقل type لواجهة برمجة تطبيقات الإجراءات الإعلان عن حقول إدخال مستخدم أكثر تحديدًا، مما يوفر تحققًا أفضل على جانب العميل ويُحسّن تجربة المستخدم. في كثير من الحالات، سيشبه هذا النوع عنصر
إدخال HTML القياسي.
يمكن تبسيط ActionParameterType إلى النوع التالي:
/*** Input field type to present to the user* @default `text`*/export type ActionParameterType =| "text"| "email"| "url"| "number"| "date"| "datetime-local"| "checkbox"| "radio"| "textarea"| "select";
يجب أن يُفضي كل من قيم type عادةً إلى حقل إدخال مستخدم يشبه عنصر HTML input القياسي من النوع المقابل (أي
<input type="email" />) لتوفير تحقق أفضل على جانب العميل وتجربة مستخدم أفضل:
text- يعادل عنصر HTML إدخال "text"email- يعادل عنصر HTML إدخال "email"url- يعادل عنصر HTML إدخال "url"number- يعادل عنصر HTML إدخال "number"date- يعادل عنصر HTML إدخال "date"datetime-local- يعادل عنصر HTML إدخال "datetime-local"checkbox- يعادل مجموعة من عناصر HTML القياسية إدخال "checkbox". يجب أن تُعيد واجهة برمجة تطبيقات الإجراءاتoptionsكما هو مُفصَّل أدناه. يجب أن يتمكن المستخدم من تحديد عدة خيارات من خيارات مربع الاختيار المُقدَّمة.radio- يعادل مجموعة من عناصر HTML القياسية إدخال "radio". يجب أن تُعيد واجهة برمجة تطبيقات الإجراءاتoptionsكما هو مُفصَّل أدناه. يجب أن يتمكن المستخدم من تحديد خيار واحد فقط من خيارات الزر الراديوي المُقدَّمة.- المكافئات الأخرى لأنواع إدخال HTML غير المذكورة أعلاه (
hidden،button،submit،file، إلخ) غير مدعومة في الوقت الحالي.
بالإضافة إلى العناصر المشابهة لأنواع إدخال HTML المذكورة أعلاه، تُدعم أيضاً عناصر إدخال المستخدم التالية:
textarea- مكافئ لعنصر HTML textarea. يتيح للمستخدم إدخال نص متعدد الأسطر.select- مكافئ لعنصر HTML select، يتيح للمستخدم تجربة حقل على شكل "قائمة منسدلة". يجب أن تُعيد Action API قيمةoptionsكما هو موضح أدناه.
عندما يكون type مضبوطاً على select أو checkbox أو radio، يجب أن تتضمن Action API
مصفوفة من options، تُوفر كل منها على الأقل label وvalue.
قد تحتوي كل خيار أيضاً على قيمة selected لإعلام blink-client بالخيار الذي يجب تحديده افتراضياً للمستخدم
(راجع checkbox وradio للاطلاع على الفروقات).
يمكن تبسيط ActionParameterSelectable إلى تعريف النوع التالي:
/*** note: for ease of reading, this is a simplified type of the actual*/interface ActionParameterSelectable extends ActionParameter {options: Array<{/** displayed UI label of this selectable option */label: string;/** value of this selectable option */value: string;/** whether or not this option should be selected by default */selected?: boolean;}>;}
إذا لم يتم تعيين type أو تم تعيين قيمة غير معروفة/غير مدعومة، يجب على blink-clients
الرجوع إلى text افتراضياً وعرض حقل إدخال نصي بسيط.
لا تزال Action API مسؤولة عن التحقق من صحة جميع البيانات المُدخلة من المستخدم وتعقيمها، مع تطبيق أي إدخال مستخدم "مطلوب" حسب الضرورة.
بالنسبة للمنصات غير HTML/الويب (كالمنصات المحمولة الأصلية)، يجب استخدام مكوّن إدخال المستخدم الأصلي المكافئ لتحقيق التجربة ذاتها والتحقق من صحة البيانات على جانب العميل كما هو موصوف في أنواع إدخال HTML/الويب أعلاه.
مثال على استجابة GET
يوفر المثال التالي للاستجابة إجراءً واحداً "جذرياً" يُتوقع عرضه للمستخدم كزر واحد بعنوان "Claim Access Token":
{"title": "HackerHouse Events","icon": "<url-to-image>","description": "Claim your Hackerhouse access token.","label": "Claim Access Token" // button text}
يوفر المثال التالي للاستجابة 3 روابط إجراء مترابطة تتيح للمستخدم النقر على أحد 3 أزرار للتصويت على مقترح DAO:
{"title": "Realms DAO Platform","icon": "<url-to-image>","description": "Vote on DAO governance proposals #1234.","label": "Vote","links": {"actions": [{"label": "Vote Yes", // button text"href": "/api/proposal/1234/vote?choice=yes"},{"label": "Vote No", // button text"href": "/api/proposal/1234/vote?choice=no"},{"label": "Abstain from Vote", // button text"href": "/api/proposal/1234/vote?choice=abstain"}]}}
مثال على استجابة GET مع معاملات
توضح أمثلة الاستجابات التالية كيفية قبول إدخال نصي من المستخدم (عبر parameters) وتضمين هذا الإدخال في نقطة نهاية طلب POST النهائية (عبر حقل href داخل LinkedAction):
يوفر المثال التالي للاستجابة 3 إجراءات مرتبطة للمستخدم لتخزين SOL: زر بعنوان "Stake 1 SOL"، وزر آخر بعنوان "Stake 5 SOL"، وحقل إدخال نصي يتيح للمستخدم إدخال قيمة "amount" محددة سيتم إرسالها إلى Action API:
{"title": "Stake-o-matic","icon": "<url-to-image>","description": "Stake SOL to help secure the Solana network.","label": "Stake SOL", // not displayed since `links.actions` are provided"links": {"actions": [{"label": "Stake 1 SOL", // button text"href": "/api/stake?amount=1"// no `parameters` therefore not a text input field},{"label": "Stake 5 SOL", // button text"href": "/api/stake?amount=5"// no `parameters` therefore not a text input field},{"label": "Stake", // button text"href": "/api/stake?amount={amount}","parameters": [{"name": "amount", // field name"label": "SOL amount" // text input placeholder}]}]}}
يوفر المثال التالي للاستجابة حقل إدخال واحداً للمستخدم لإدخال amount الذي يُرسل مع طلب POST (يمكن استخدام معامل استعلام أو مسار فرعي):
{"icon": "<url-to-image>","label": "Donate SOL","title": "Donate to GoodCause Charity","description": "Help support this charity by donating SOL.","links": {"actions": [{"label": "Donate", // button text"href": "/api/donate/{amount}", // or /api/donate?amount={amount}"parameters": [// {amount} input field{"name": "amount", // input field name"label": "SOL amount" // text input placeholder}]}]}}
طلب POST
يجب على العميل إرسال طلب HTTP POST بصيغة JSON إلى عنوان URL الخاص بالإجراء مع حمولة نصية في الجسم تتضمن:
{"account": "<account>"}
account- يجب أن تكون القيمة المفتاح العام المشفر بنظام base58 لحساب قد يوقّع على المعاملة.
يجب على العميل إرسال الطلب مع ترويسة Accept-Encoding وقد يستجيب التطبيق بـ ترويسة Content-Encoding لضغط HTTP.
يجب على العميل عرض نطاق عنوان URL الخاص بالإجراء أثناء إرسال الطلب. إذا تم إرسال طلب GET، يجب على العميل أيضاً عرض title وعرض صورة icon من استجابة GET تلك.
استجابة POST
يجب أن تستجيب نقطة نهاية POST الخاصة بالإجراء باستجابة JSON بصيغة HTTP OK
(مع حمولة صحيحة في الجسم) أو بخطأ HTTP مناسب.
- يجب على العميل معالجة أخطاء العميل، وأخطاء الخادم، واستجابات إعادة التوجيه.
- يجب أن تستجيب نقطة النهاية بـ
ترويسة
Content-Typeبقيمةapplication/json.
يجب أن تُعيد استجابات الخطأ (أي رموز حالة HTTP 4xx و5xx) جسم استجابة JSON وفق ActionError لعرض رسالة خطأ مفيدة للمستخدمين. راجع أخطاء الإجراء.
جسم استجابة POST
يجب أن تتضمن استجابة POST بصيغة HTTP OK حمولة في الجسم تتضمن:
/*** Response body payload returned from the Action POST Request*/export interface ActionPostResponse<T extends ActionType = ActionType> {/** base64 encoded serialized transaction */transaction: string;/** describes the nature of the transaction */message?: string;links?: {/*** The next action in a successive chain of actions to be obtained after* the previous was successful.*/next: NextActionLink;};}
-
transaction- يجب أن تكون القيمة معاملة مُسلسَلة مشفرة بنظام base64. يجب على العميل فك تشفير المعاملة باستخدام base64 وإلغاء تسلسلها. -
message- يجب أن تكون القيمة سلسلة نصية بترميز UTF-8 تصف طبيعة المعاملة المضمّنة في الاستجابة. يجب على العميل عرض هذه القيمة للمستخدم. على سبيل المثال، قد تكون هذه القيمة اسم عنصر يتم شراؤه، أو خصم مطبّق على عملية شراء، أو رسالة شكر. -
links.next- قيمة اختيارية تُستخدم "لتسلسل" إجراءات متعددة معاً بشكل متتابع. بعد تأكيدtransactionالمضمّنة على السلسلة، يمكن للعميل جلب الإجراء التالي وعرضه. راجع تسلسل الإجراءات لمزيد من التفاصيل. -
يجب أن يسمح العميل والتطبيق بحقول إضافية في جسم الطلب وجسم الاستجابة، والتي قد تُضاف في تحديثات المواصفات المستقبلية.
قد يستجيب التطبيق بمعاملة موقّعة جزئياً أو كلياً. يجب على العميل والمحفظة التعامل مع المعاملة باعتبارها غير موثوقة.
استجابة POST - المعاملة
إذا كانت
signatures
للمعاملة فارغة أو لم تكن المعاملة موقّعة جزئياً:
- يجب على العميل تجاهل
feePayerفي المعاملة وتعيينfeePayerإلىaccountالوارد في الطلب. - يجب على العميل تجاهل
recentBlockhashفي المعاملة وتعيينrecentBlockhashإلى أحدث blockhash. - يجب على العميل تسلسل المعاملة وإلغاء تسلسلها قبل توقيعها. يضمن ذلك ترتيباً متسقاً لمفاتيح الحسابات، كحل بديل لـ هذه المشكلة.
إذا كانت المعاملة موقّعة جزئياً:
- يجب على العميل عدم تعديل
feePayerأوrecentBlockhashلأن ذلك سيُبطل أي توقيعات موجودة. - يجب على العميل التحقق من التوقيعات الموجودة، وإذا كان أي منها غير صالح، يجب على العميل رفض المعاملة باعتبارها مشوّهة.
يجب على العميل توقيع المعاملة فقط باستخدام account الوارد في الطلب، ويجب عليه القيام بذلك فقط إذا كان التوقيع المتعلق بـ account الوارد في الطلب مطلوباً.
إذا كان أي توقيع غير توقيع account الوارد في الطلب مطلوباً، يجب على العميل رفض المعاملة باعتبارها خبيثة.
أخطاء الإجراء
يجب على Actions APIs إعادة الأخطاء باستخدام ActionError لعرض رسائل خطأ مفيدة للمستخدم. اعتماداً على السياق، قد يكون هذا الخطأ قاطعاً أو غير قاطع.
export interface ActionError {/** simple error message to be displayed to the user */message: string;}
عندما تستجيب Actions API برمز حالة HTTP للخطأ (أي 4xx و5xx)، يجب أن يكون جسم الاستجابة حمولة JSON وفق ActionError. يُعتبر الخطأ قاطعاً ويجب عرض message المضمّنة للمستخدم.
بالنسبة لاستجابات API التي تدعم سمة error الاختيارية (مثل
ActionGetResponse)، يُعتبر الخطأ غير قاطع ويجب عرض message المضمّنة للمستخدم.
تسلسل الإجراءات
يمكن "تسلسل" إجراءات سولانا معاً في سلسلة متتابعة. بعد تأكيد معاملة الإجراء على السلسلة، يمكن الحصول على الإجراء التالي وعرضه للمستخدم.
يتيح تسلسل الإجراءات للمطورين بناء تجارب أكثر تعقيداً وديناميكية داخل blinks، بما في ذلك:
- توفير معاملات متعددة (وفي نهاية المطاف توقيع الرسائل) للمستخدم
- تخصيص بيانات الإجراء بناءً على عنوان محفظة المستخدم
- تحديث بيانات blink بعد معاملة ناجحة
- استقبال استدعاء API مع توقيع المعاملة للتحقق الإضافي والمنطق على خادم Action API
- رسائل "نجاح" مخصصة عن طريق تحديث البيانات المعروضة (مثلاً صورة جديدة ووصف)
لتسلسل إجراءات متعددة معاً، قم بتضمين links.next في أي ActionPostResponse من النوعين التاليين:
PostNextActionLink- رابط طلب POST مع عنوان URL لاستدعاء من نفس الأصل لاستقبالsignatureوaccountالخاص بالمستخدم في الجسم. يجب أن يستجيب عنوان URL للاستدعاء هذا بـNextAction.InlineNextActionLink- بيانات مضمّنة للإجراء التالي لعرضها للمستخدم فوراً بعد تأكيد المعاملة. لن يتم إجراء أي استدعاء.
export type NextActionLink = PostNextActionLink | InlineNextActionLink;/** @see {NextActionPostRequest} */export interface PostNextActionLink {/** Indicates the type of the link. */type: "post";/** Relative or same origin URL to which the POST request should be made. */href: string;}/*** Represents an inline next action embedded within the current context.*/export interface InlineNextActionLink {/** Indicates the type of the link. */type: "inline";/** The next action to be performed */action: NextAction;}
NextAction
بعد توقيع المستخدم على transaction المضمّنة في ActionPostResponse وتأكيدها على السلسلة، يجب على blink client إما:
- تنفيذ طلب الاستدعاء لجلب
NextActionوعرضه، أو - إذا كان
NextActionمتاحاً بالفعل عبرlinks.next، يجب على blink client تحديث البيانات المعروضة وعدم إرسال أي طلب استدعاء
إذا لم يكن عنوان URL للاستدعاء من نفس أصل طلب POST الأولي، فلا يجب إرسال أي طلب استدعاء. يجب على Blink clients عرض خطأ لإخطار المستخدم.
/** The next action to be performed */export type NextAction = Action<"action"> | CompletedAction;/** The completed action, used to declare the "completed" state within action chaining. */export type CompletedAction = Omit<Action<"completed">, "links">;
بناءً على type، يجب عرض الإجراء التالي للمستخدم عبر blink clients بإحدى الطرق التالية:
-
action- (افتراضي) إجراء قياسي يتيح للمستخدم رؤية بيانات الإجراء المضمّنة، والتفاعل معLinkedActionsالمتوفرة، ومواصلة تسلسل أي إجراءات لاحقة. -
completed- الحالة النهائية لسلسلة الإجراءات التي يمكنها تحديث واجهة blink ببيانات الإجراء المضمّنة، لكنها لن تتيح للمستخدم تنفيذ إجراءات إضافية.
إذا لم يتم توفير links.next، يجب على blink clients افتراض أن الإجراء الحالي هو الإجراء الأخير في السلسلة، وعرض حالة واجهة "مكتمل" بعد تأكيد المعاملة.
actions.json
الغرض من ملف actions.json هو السماح للتطبيق بإرشاد العملاء حول عناوين URL للمواقع التي تدعم إجراءات سولانا وتوفير تعيين يمكن استخدامه لإجراء طلبات GET إلى خادم Actions API.
ترويسات Cross-Origin مطلوبة
يجب أن تُعيد استجابة ملف actions.json أيضاً ترويسات Cross-Origin صالحة لطلبات
GET وOPTIONS، وتحديداً قيمة ترويسة Access-Control-Allow-Origin
بقيمة *.
راجع استجابة OPTIONS أعلاه لمزيد من التفاصيل.
يجب تخزين ملف actions.json وجعله متاحاً للجميع في جذر النطاق.
على سبيل المثال، إذا كان تطبيق الويب الخاص بك مُنشراً على my-site.com، فيجب أن يكون ملف actions.json متاحاً على https://my-site.com/actions.json.
يجب أن يكون هذا الملف أيضاً متاحاً عبر Cross-Origin من أي متصفح عن طريق تعيين قيمة ترويسة Access-Control-Allow-Origin إلى *.
القواعد
يتيح حقل rules للتطبيق تعيين مجموعة من مسارات المسارات النسبية للموقع إلى مجموعة من المسارات الأخرى.
النوع: Array من ActionRuleObject.
interface ActionRuleObject {/** relative (preferred) or absolute path to perform the rule mapping from */pathPattern: string;/** relative (preferred) or absolute path that supports Action requests */apiPath: string;}
-
pathPattern- نمط يطابق كل مسار URL وارد. -
apiPath- وجهة مسار محددة كمسار مطلق أو رابط URL خارجي.
القواعد - pathPattern
نمط يطابق كل مسار URL وارد. يمكن أن يكون مساراً مطلقاً أو نسبياً ويدعم الصيغ التالية:
-
مطابقة تامة: تطابق مسار URL بشكل دقيق.
- مثال:
/exact-path - مثال:
https://website.com/exact-path
- مثال:
-
مطابقة بالبدل: تستخدم أحرف البدل لمطابقة أي تسلسل من الأحرف في مسار URL. يمكنها مطابقة مقطع واحد (باستخدام
*) أو مقاطع متعددة (باستخدام**). (راجع مطابقة المسار أدناه).- مثال:
/trade/*ستطابق/trade/123و/trade/abc، مع التقاط المقطع الأول فقط بعد/trade/. - مثال:
/category/*/item/**ستطابق/category/123/item/456و/category/abc/item/def. - مثال:
/api/actions/trade/*/confirmستطابق/api/actions/trade/123/confirm.
- مثال:
القواعد - apiPath
مسار الوجهة لطلب الإجراء. يمكن تعريفه كمسار مطلق أو رابط URL خارجي.
- مثال:
/api/exact-path - مثال:
https://api.example.com/v1/donate/* - مثال:
/api/category/*/item/* - مثال:
/api/swap/**
القواعد - معاملات الاستعلام
يتم دائماً الحفاظ على معاملات الاستعلام من URL الأصلي وإلحاقها بعنوان URL المعيَّن.
القواعد - مطابقة المسار
يوضح الجدول التالي بناء الجملة لأنماط مطابقة المسار:
| المشغّل | يطابق |
|---|---|
* | مقطع مسار واحد، لا يتضمن أحرف فاصل المسار / المحيطة به. |
** | يطابق صفراً أو أكثر من الأحرف، بما في ذلك أي أحرف فاصل مسار / بين مقاطع مسار متعددة. إذا كانت هناك مشغّلات أخرى، فيجب أن يكون المشغّل ** هو الأخير. |
? | نمط غير مدعوم. |
أمثلة على القواعد
يوضح المثال التالي قاعدة مطابقة تامة لتعيين الطلبات الواردة إلى /buy من جذر موقعك إلى المسار الدقيق /api/buy نسبةً إلى جذر موقعك:
{"rules": [{"pathPattern": "/buy","apiPath": "/api/buy"}]}
يستخدم المثال التالي مطابقة المسار بالبدل لتعيين الطلبات إلى أي مسار (باستثناء المجلدات الفرعية) ضمن /actions/ من جذر موقعك إلى مسار مقابل ضمن /api/actions/ نسبةً إلى جذر موقعك:
{"rules": [{"pathPattern": "/actions/*","apiPath": "/api/actions/*"}]}
يستخدم المثال التالي مطابقة المسار بالبدل لتعيين الطلبات إلى أي مسار (باستثناء المجلدات الفرعية) ضمن /donate/ من جذر موقعك إلى مسار مطلق مقابل https://api.dialect.com/api/v1/donate/ على موقع خارجي:
{"rules": [{"pathPattern": "/donate/*","apiPath": "https://api.dialect.com/api/v1/donate/*"}]}
يستخدم المثال التالي مطابقة المسار بالبدل لقاعدة متكافئة لتعيين الطلبات إلى أي مسار (بما في ذلك المجلدات الفرعية) ضمن /api/actions/ من جذر موقعك إلى نفسه:
تتيح القواعد المتكافئة لعملاء Blink تحديد ما إذا كان مسار معين يدعم طلبات Action API بسهولة أكبر دون الحاجة إلى إضافة بادئة
solana-action:للـ URI أو إجراء اختبارات استجابة إضافية.
{"rules": [{"pathPattern": "/api/actions/**","apiPath": "/api/actions/**"}]}
هوية الإجراء
قد تتضمن نقاط نهاية الإجراء هوية إجراء في المعاملات التي يتم إرجاعها في استجابة POST للمستخدم لتوقيعها. يتيح ذلك للمفهرسين ومنصات التحليلات نسب النشاط على السلسلة بسهولة وبشكل قابل للتحقق إلى موفر إجراء محدد (أي خدمة) بطريقة قابلة للتحقق.
هوية الإجراء هي keypair تُستخدم لتوقيع رسالة بتنسيق خاص مضمَّنة في المعاملة باستخدام تعليمة Memo. يمكن نسب رسالة المُعرِّف هذه بشكل قابل للتحقق إلى هوية إجراء محددة، وبالتالي نسب المعاملات إلى موفر إجراء محدد.
لا يُشترط أن يوقّع keypair على المعاملة نفسها. يتيح ذلك للمحافظ والتطبيقات تحسين قابلية تسليم المعاملات عندما لا تكون هناك توقيعات أخرى على المعاملة المُعادة إلى المستخدم (راجع معاملة استجابة POST).
إذا كانت حالة استخدام موفر الإجراء تستلزم قيام خدمات الخلفية بالتوقيع المسبق على المعاملة قبل المستخدم، فينبغي له استخدام هذا keypair كهوية الإجراء الخاصة به. سيتيح ذلك تضمين حساب واحد أقل في المعاملة، مما يقلل الحجم الإجمالي للمعاملات بمقدار 32 بايت.
رسالة مُعرِّف الإجراء
رسالة مُعرِّف الإجراء هي سلسلة UTF-8 مفصولة بنقطتين مضمَّنة في معاملة باستخدام تعليمة SPL Memo واحدة.
protocol:identity:reference:signature
protocol- قيمة البروتوكول المستخدم (تُضبط علىsolana-actionوفقاً لـ مخطط URL أعلاه)identity- يجب أن تكون القيمة هي عنوان المفتاح العام المُرمَّز بـ base58 الخاص بـ keypair هوية الإجراءreference- يجب أن تكون القيمة مصفوفة 32 بايت مُرمَّزة بـ base58. قد تكون أو لا تكون مفاتيح عامة، على المنحنى أو خارجه، وقد تتوافق أو لا تتوافق مع حسابات على سولانا.signature- توقيع مُرمَّز بـ base58 تم إنشاؤه من keypair هوية الإجراء بتوقيع قيمةreferenceفحسب.
يجب استخدام قيمة reference مرة واحدة فقط وفي معاملة واحدة. لغرض ربط المعاملات بموفر الإجراء، يُعتبر الاستخدام الأول لقيمة reference فحسب صالحاً.
قد تحتوي المعاملات على تعليمات Memo متعددة. عند تنفيذ
getSignaturesForAddress، سيُعيد
حقل memo في النتائج رسالة كل تعليمة memo كسلسلة واحدة مفصولة بفاصلة منقوطة.
لا ينبغي تضمين أي بيانات أخرى مع تعليمة Memo الخاصة برسالة المُعرِّف.
ينبغي تضمين identity وreference كـ مفاتيح للقراءة فقط وغير موقِّعة
في المعاملة على تعليمة لا تكون تعليمة Memo الخاصة برسالة المُعرِّف.
يجب ألا تحتوي تعليمة Memo الخاصة برسالة المُعرِّف على أي حسابات. إذا تم تقديم أي حسابات، فإن برنامج Memo يشترط أن تكون هذه الحسابات موقِّعين صالحين. لأغراض تعريف الإجراءات، يُقيِّد ذلك المرونة وقد يُضعف تجربة المستخدم. لذلك يُعدّ هذا نمطاً مضاداً ويجب تجنبه.
التحقق من هوية الإجراء
يمكن ربط أي معاملة تتضمن حساب identity بموفر الإجراء بشكل قابل للتحقق من خلال عملية متعددة الخطوات:
- احصل على جميع المعاملات لـ
identityالمحددة. - حلِّل وتحقق من سلسلة memo الخاصة بكل معاملة، مع التأكد من أن
signatureصالح لـreferenceالمخزَّنة. - تحقق من أن المعاملة المحددة هي أول ظهور على السلسلة لـ
reference:- إذا كانت هذه المعاملة هي أول ظهور، فتُعتبر المعاملة مُتحقَّقاً منها ويمكن نسبها بأمان إلى موفر الإجراء.
- إذا كانت هذه المعاملة ليست أول ظهور، فتُعتبر غير صالحة وبالتالي لا تُنسب إلى موفر الإجراء.
نظراً لأن validator في سولانا يُفهرس المعاملات حسب مفاتيح الحسابات، يمكن استخدام طريقة RPC
getSignaturesForAddress
للعثور على جميع المعاملات التي تتضمن حساب identity.
تتضمن استجابة طريقة RPC هذه جميع بيانات Memo في حقل memo. إذا تم استخدام تعليمات Memo متعددة في المعاملة، فسيتم تضمين كل رسالة memo في حقل memo هذا ويجب على المُتحقِّق تحليلها وفقاً لذلك للحصول على رسالة التحقق من الهوية.
ينبغي في البداية اعتبار هذه المعاملات غير مُتحقَّق منها. ويعود ذلك إلى أن identity لا يُشترط توقيعها على المعاملة، مما يسمح لأي معاملة بتضمين هذا الحساب كغير موقِّع. مما قد يؤدي إلى تضخيم مصطنع لأعداد النسب والاستخدام.
ينبغي فحص رسالة التحقق من الهوية للتأكد من أن signature تم إنشاؤه بواسطة identity بتوقيع reference. إذا فشل التحقق من التوقيع، فتُعتبر المعاملة غير صالحة ولا ينبغي نسبها إلى موفر الإجراء.
إذا نجح التحقق من التوقيع، فينبغي على المُتحقِّق التأكد من أن هذه المعاملة هي أول ظهور على السلسلة لـ reference. إذا لم تكن كذلك، فتُعتبر المعاملة غير صالحة.
Is this page helpful?