البدء
1. تشغيل الشبكة كاملةً محليًا (المختبر)
ملف docker compose واحد يُنشئ شبكة مغلقة. ولا يتصل بالإنترنت.
- مرحّلا Nostr
- مرحّل libp2p
- bitcoind على signet مخصّصة، وواجهة API متوافقة مع Esplora
- anvil (EVM) مع Safe وبقية العقود
- أربعة متاجر وهمية وبوابة دفع بطاقات وهمية
- متسوّقان (shoppers)، وثلاثة وسطاء ضامنين (escrows) (أحدهم خلف NAT)، ومشغّلان (operators)
- تطبيق الويب العام وتطبيق العرض التوضيحي
المتطلبات: Docker (نحو 8 GB من الذاكرة).
ضع proxy-shopping-go وproxy-shopping-web جنبًا إلى جنب في المجلد الأب نفسه ثم شغّل:
git clone https://github.com/pad01g/proxy-shopping-go
git clone https://github.com/pad01g/proxy-shopping-web
cd proxy-shopping-go
docker compose up -d --build
للبدء من جديد، شغّل أولًا docker compose down -v لحذف البيانات المخزّنة للعُقد والمرحّلات أيضًا
(فالسلاسل تبدأ من الصفر في كل تشغيل، لذا ستتعارض بيانات الطلبات المتبقية معها).
تشغيل اختبارات e2e
docker compose run --rm runner # all scenarios (about 10 minutes)
docker compose run --rm runner a e # pick some
تُكتب النتائج إلى e2e/results/e2e-latest.md. يعمل الـ runner من داخل NAT (شبكة home)،
لذا تفترض كل السيناريوهات أن المستخدم خلف NAT.
| id | السيناريو |
|---|---|
| a | المسار الناجح: BTC (متجر بالين الياباني) وUSDC (متجر بالدولار). يُتحقَّق من سعر الصرف في عرض السعر، ويحصل الوسيط الضامن على رسمه المقدّم، ويتقاضى المتسوّق أجره. عرض السعر الذي يبتعد سعره كثيرًا يتلقّى تحذيرًا شديدًا |
| b | يفشل التسليم ويفتح المستخدم نزاعًا. يحكم وسيط ضامن نزيه بالاسترداد ويوقّع المستخدم توقيعًا مقابلًا (BTC). يستطيع الوسيط الضامن فك تشفير العنوان ويتلقّى لقطة الشاشة كمرفق |
| c | يحكم وسيط ضامن بغير نزاهة. يبلّغ المستخدم عنه؛ فيزيله المشغّل من القائمة، ووفق شروطهما، يصادر ضمانته تعويضًا (USDC) |
| d | يسحب منسّق (coordinator) تفويض أحد المشغّلين، فتختفي تركيبات تلك القائمة من العروض |
| e | متصفح خلف NAT يطلب عبر تطبيق الويب العام (تمرّ الرسائل الثنائية 1:1 عبر مرحّلات Nostr). ويصل استعلام الحالة إلى عقدة الوسيط الضامن خلف NAT عبر circuit relay في libp2p |
| f | يرفض متسوّق متجرًا يقيّمه بأنه خطر، ومتجرًا نقديًا فقط خارج منطقته. ويقبل متسوّق داخل المنطقة الطلب النقدي ويسلّمه |
| g | بعد T1، يستطيع المتسوّق أخذ الأموال وحده (BTC) |
| h | إذا اختفى المتسوّق، يستردّ المستخدم الأموال وحده بعد T2 (USDC) |
| i | نزاع USDC مع وسيط ضامن نزيه. يُنفَّذ الاسترداد حتى لو أرسل أحدهم مبلغًا صغيرًا إلى الـ Safe قبل الحكم |
| j | طلب لم يستطع المتجر تلبيته (نفدت الكمية). يعرض المتسوّق استردادًا تعاونيًا؛ فيتحقّق منه المستخدم ويقبله |
| k | إذا اختفى المتسوّق، يستردّ المستخدم الأموال وحده بعد T2 (BTC) |
جرّب المسار كاملًا في العرض التوضيحي
جرّبه في متصفحك: https://pad01g.github.io/proxy-shopping-web/ (كل شيء محاكى داخل الصفحة).
والمختبر يعمل، افتح العرض التوضيحي على http://localhost:8888/ (لا حاجة إلى ملف hosts أو شهادات).
على شاشة واحدة، لكلٍّ من المستخدم والوسيط الضامن والمشغّل والمنسّق مفتاحه الخاص (في التخزين المحلي للمتصفح)،
أما المتسوّق فهو عقدة Go نفسها المتصلة دائمًا. المسارات حقيقية: مرحّلات Nostr، وbitcoind، وanvil، وعُقد Go.
- اختر سيناريو من الأعلى. يوضّح الدليل على اليسار من يفعل ماذا بعد ذلك، ولماذا.
- ينقلك “Go to this step” إلى تبويب ذلك الدور ويشير إلى الزر الذي يجب ضغطه. النماذج معبّأة مسبقًا للسيناريو، فلا يبقى لك إلا الضغط والتأكيد.
- السيناريوهات: المسار الناجح (BTC / USDC)، والتسليم الفاشل والاسترداد، ونفاد الكمية والاسترداد التعاوني، ورفض متجر خطر، ووسيط ضامن غير نزيه يُبلَّغ عنه ويُزال من القائمة، واسترداد بعد T2 عند اختفاء المتسوّق.
- يمكنك أيضًا فتح نافذة لكل دور، مثل
?role=userو?role=escrow,operator,coordinator(نوافذ المتصفح نفسه تتشارك المفاتيح والتقدّم). - في الواقع كل دور في مكان مختلف، في متصفحه الخاص. أما العرض التوضيحي فيفصل المفاتيح فقط.
- للمختبر فقط: أي شخص يستطيع الوصول إلى المنفذ 8888 يمكنه استخدام الـ faucet والتعدين والقفز الزمني وواجهة API الإدارية للمتسوّق (وهو مربوط بـ 127.0.0.1 فقط).
وهناك أيضًا اختبار e2e يقود العرض التوضيحي باتباع دليله: docker compose run --rm runner demo.
استخدام تطبيق الويب
أسماء المختبر (*.test) لا تُحَلّ إلا داخل الحاويات.
لاستخدام تطبيق الويب من متصفحك:
- اكشف المنفذ 443 من الحاوية
edgeمحليًا (مثلًا فيcompose.override.yaml:services: {edge: {ports: ["127.0.0.1:443:443"]}}). هذا يكشف أيضًاfaucet.testوevm.testالخاصين بالمختبر (يستطيع أي أحد صكّ أرصدة وتقديم الوقت)، لذا اكشفه على localhost فقط. - وجّه
app.testوبقية الأسماء إلى 127.0.0.1 في ملف hosts لديك.
الشهادات موقّعة ذاتيًا.
- افتح
https://app.test/واختر “create new” أو “restore from words”. اختر عبارة مرور (8 محارف أو أكثر) تشفّر المفتاح (يمكنك أيضًا أن تختار صراحةً عدم تشفيره، أو استخدام إضافة NIP-07). في المرة التالية، افتح المفتاح بعبارة المرور. - تحت “order”، أدخل رابط المتجر (مثلًا
https://safe-shop.test/)، ومنطقة المتجر (مثلًاJP-13-13104) والسلعة (مثلًاA-100)، وابحث عن العروض. - اختر تركيبة متسوّق × وسيط ضامن، وأدخل عنوان التسليم وقدّم الطلب.
- عند وصول عرض السعر، تحقّق من فرق سعر الصرف ونتيجة فحص عنوان المحفظة متعددة التوقيع، ثم اقبل.
- في المختبر، املأ محفظتك عبر “get from the faucet”، ثم اضغط “fund the multisig”. كل إجراء ينقل المال (التمويل، والدفع، والتوقيع المقابل) يمرّ عبر شاشة تعرض المبلغ والمستلم.
- عند وصول السلعة، اضغط “received” للدفع إلى المتسوّق. لا تظهر “Completed” إلا بعد تأكيد الدفعة على السلسلة.
2. التشغيل على شبكة عامة
البنية هي نفسها في المختبر. الفروق:
- استخدم شهادات ACME؛
- لا تستخدم المفاتيح الموجودة في
lab/keys؛ - استخدم signet حقيقية وسلسلة EVM حقيقية.
المتسوّق
متصل دائمًا؛ يشغّل عقدة Go وshopper-bot.
role: shopper
name: my-shopper
network: ps-main
mnemonic_file: /keys/shopper.mnemonic
nostr: {relays: ["wss://relay.example"], k: 2}
trust: {coordinators: ["<coordinator public key>"]}
chain:
btc: {network: signet, esplora: "https://mempool.space/signet/api"}
shopper:
bot_url: "http://shopper-bot:7000"
cash_regions: [JP-13]
risk: {allowlist: [shop.example], known_gateways: [pay.example], threshold: 70}
- بيانات البطاقة توضع فقط في ملف إعدادات shopper-bot (
BOT_CARDS_FILE)؛ ولا تحصل عليها العقدة أبدًا. - تُكتب خطوات كل متجر كـ driver لـ shopper-bot. والـ driver الذي يستخدم الذكاء الاصطناعي لتشغيل المتاجر له المدخلات والمخرجات نفسها (
PurchaseRequest/PurchaseResult).
الوسيط الضامن / المشغّل / المنسّق
لا تحتاج هذه الأدوار إلى الاتصال الدائم.
- يمكنها استخدام شاشات “Escrow” و”Operator” و”Coordinator” في تطبيق الويب.
- للتشغيل المتواصل، شغّل عقدة Go باستخدام
role: escrow/role: operator. - وللتوقيع فقط، يكفي
psctlأيضًا.
الإصدار (v) يساوي افتراضيًا وقت UNIX، لذا لا تمرّره عادةً.
psctl keys --mnemonic-file coordinator.mnemonic
psctl delegate --network ps-main --mnemonic-file coordinator.mnemonic --operator <operator public key> --publish wss://relay.example
psctl list --network ps-main --mnemonic-file operator.mnemonic --file list.json --publish wss://relay.example
3. شغّل دورك الخاص في الشبكة، من أي مكان، دون إذن من أحد
ليس لـ proxy-shopping مشغّل مركزي ولا شيء يتطلب التسجيل. سلسلة الثقة ليست سوى مفاتيح وأحداث Nostr موقّعة، لذا تستطيع أنت (أو وكيل ذكاء اصطناعي يعمل لحسابك) أن تبدأ سوقًا محلية في مدينتك:
- كن منسّقًا: أنشئ مفتاحًا (
psctl keys --mnemonic-file coordinator.mnemonic). هذا كل ما يعنيه أن تكون منسّقًا. - فوّض مشغّلًا (مفتاحك الثاني، أو شخصًا تثق به):
psctl delegate --network ps-main --mnemonic-file coordinator.mnemonic --operator <operator pk> --publish wss://relay.damus.io,wss://nos.lol,wss://relay.primal.net - أدرج متسوّقين ووسطاء ضامنين لمنطقتك — نفسك متسوّقًا، وصديقًا وسيطًا ضامنًا:
psctl list --network ps-main --mnemonic-file operator.mnemonic --file list.json --publish … - اطلب من الناس أن يثقوا بمفتاح منسّقك (أضِفه في إعدادات تطبيق الويب، أو عبر
PS_COORDINATORSلخادم MCP). ليعثر عليك الجميع، افتح طلب سحب إلى السجلّ يضيفcoordinators/<name>.json؛ ولإدارة الموافقات لمجتمعك الخاص بالطريقة نفسها، انسخ السجلّ (fork).
أين تشغّله: جهاز في المنزل يكفي. لا تُنشئ العقدة إلا اتصالات صادرة (مرحّلات Nostr، وcircuit relay في libp2p عندما تكون خلف NAT)، لذا لا تفتح أي منافذ. استخدم Tailscale أو أي VPN للوصول إلى واجهة API الإدارية لعقدتك وإلى تطبيق الويب من هاتفك وأنت خارج المنزل؛ ويصلح أيضًا خادم VPS صغير.
ما الذي يستطيع وكيل الذكاء الاصطناعي فعله: يستطيع الوكيل أداء الروتين اليومي للمشغّل والمتسوّق — مراقبة الطلبات عبر واجهة API الإدارية
للعقدة أو عبر خادم MCP، وتحديث القوائم، وتشغيل shopper-bot لمتاجر البطاقات، والإبلاغ عن المشكلات — أما معرفتك
المحلية (أي المتاجر، وأي المناطق، والمتاجر النقدية التي تستطيع الوصول إليها سيرًا) فهي الجزء الذي لا يستطيع أحد غيرك تقديمه.
المهارة proxy-shopper (npx skills add pad01g/proxy-shopping-go) ترشد الوكيل خطوةً بخطوة.
كن صادقًا مع مستخدميك: الشبكة العامة جديدة وتعمل على BTC signet (عملات اختبارية)، لذا تأتي الأرباح حين يبدأ الناس باستخدامها.
المساهمة
طلبات السحب (pull requests) مرحَّب بها — في كل المستودعات: drivers المتاجر لـ shopper-bot، ووسائل الدفع والسلاسل الجديدة، وترجمات هذا التوثيق، ومراجعات البروتوكول، وإصلاح الأخطاء، والإدراج في السجلّ. افتح issue أو pull request على GitHub.