feat(web): add PEZMessage on-chain E2E encrypted messaging UI

- x25519 ECDH + XChaCha20-Poly1305 encryption via @noble libs
- Key derivation from wallet signRaw, private key held in memory only
- Messaging pallet integration (registerEncryptionKey, sendMessage, inbox)
- Inbox polling every 12s, auto-decrypt when key unlocked
- ComposeDialog with recipient key validation and 512-byte limit
- Settings moved from grid to nav bar gear icon, PEZMessage takes its slot
- i18n translations for all 6 languages (en, tr, kmr, ckb, ar, fa)
This commit is contained in:
2026-03-03 08:29:16 +03:00
parent 86433a88ff
commit a9cb2972b9
17 changed files with 1429 additions and 19 deletions
+30
View File
@@ -3727,4 +3727,34 @@ export default {
'websocket.liveUpdates': 'التحديثات المباشرة مفعلة',
'websocket.offlineMode': 'وضع عدم الاتصال',
// Navigation - Messaging
'nav.message': 'رسالة',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'ربط المحفظة',
'messaging.connectWalletDesc': 'قم بربط محفظتك لاستخدام الرسائل المشفرة.',
'messaging.setupTitle': 'إعداد مفتاح التشفير',
'messaging.setupDesc': 'سجّل مفتاح التشفير الخاص بك على السلسلة لبدء إرسال واستقبال الرسائل المشفرة.',
'messaging.unlockTitle': 'فتح رسائلك',
'messaging.unlockDesc': 'وقّع بمحفظتك لتمكين فك تشفير الرسائل لهذه الجلسة.',
'messaging.setupKey': 'إعداد المفتاح',
'messaging.unlock': 'فتح',
'messaging.signing': 'جاري التوقيع...',
'messaging.newMessage': 'جديد',
'messaging.messages': 'رسائل',
'messaging.sent': 'مرسلة',
'messaging.emptyInbox': 'لا توجد رسائل بعد.',
'messaging.sendFirst': 'أرسل رسالتك الأولى',
'messaging.encrypted': '[مشفّرة]',
'messaging.compose': 'رسالة جديدة',
'messaging.composeDesc': 'أرسل رسالة مشفرة من طرف إلى طرف على السلسلة.',
'messaging.recipient': 'عنوان المستلم',
'messaging.message': 'الرسالة',
'messaging.typePlaceholder': 'اكتب رسالتك...',
'messaging.tooLong': 'الرسالة تتجاوز الحد الأقصى (512 بايت)',
'messaging.noRecipientKey': 'المستلم ليس لديه مفتاح تشفير مسجّل',
'messaging.checkingKey': 'جاري التحقق من مفتاح التشفير...',
'messaging.send': 'إرسال',
'messaging.sending': 'جاري الإرسال...',
};
+30
View File
@@ -3717,4 +3717,34 @@ export default {
'websocket.liveUpdates': 'نوێکردنەوەی ڕاستەوخۆ چالاکە',
'websocket.offlineMode': 'دۆخی ئۆفلاین',
// Navigation - Messaging
'nav.message': 'نامە',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'جزدان ببەستە',
'messaging.connectWalletDesc': 'بۆ بەکارهێنانی نامەی شفرکراو جزدانەکەت ببەستە.',
'messaging.setupTitle': 'کلیلی شفرکردن دابنێ',
'messaging.setupDesc': 'بۆ ناردن و وەرگرتنی نامەی شفرکراو کلیلەکەت لەسەر زنجیرە تۆمار بکە.',
'messaging.unlockTitle': 'نامەکانت بکەرەوە',
'messaging.unlockDesc': 'بۆ کردنەوەی شفری نامەکان لەم دانیشتنەدا بە جزدانەکەت واژۆ بکە.',
'messaging.setupKey': 'کلیل دابنێ',
'messaging.unlock': 'بکەرەوە',
'messaging.signing': 'واژۆدەکرێت...',
'messaging.newMessage': 'نوێ',
'messaging.messages': 'نامە',
'messaging.sent': 'نێردراو',
'messaging.emptyInbox': 'هێشتا نامەیەک نییە.',
'messaging.sendFirst': 'یەکەم نامەکەت بنێرە',
'messaging.encrypted': '[شفرکراو]',
'messaging.compose': 'نامەی نوێ',
'messaging.composeDesc': 'نامەیەکی شفرکراوی سەرەتاوەکۆتایی لەسەر زنجیرە بنێرە.',
'messaging.recipient': 'ناونیشانی وەرگر',
'messaging.message': 'نامە',
'messaging.typePlaceholder': 'نامەکەت بنووسە...',
'messaging.tooLong': 'نامە لە قەبارەی زۆرینە تێپەڕیوە (٥١٢ بایت)',
'messaging.noRecipientKey': 'وەرگر کلیلی شفرکردنی تۆمارکراوی نییە',
'messaging.checkingKey': 'کلیلی شفرکردن پشکنین دەکرێت...',
'messaging.send': 'بنێرە',
'messaging.sending': 'دەنێردرێت...',
};
+32 -1
View File
@@ -3763,5 +3763,36 @@ export default {
'proposalCard.proposalClosedDesc': 'Proposal has been closed',
'proposalCard.executeFailed': 'Execution Failed',
'proposalCard.executeSuccess': 'Proposal Executed!',
'proposalCard.executeKycApproved': 'KYC approved and NFT minted successfully!'
'proposalCard.executeKycApproved': 'KYC approved and NFT minted successfully!',
// Navigation - Messaging
'nav.message': 'Message',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'Connect Wallet',
'messaging.connectWalletDesc': 'Connect your wallet to use encrypted messaging.',
'messaging.setupTitle': 'Set Up Encryption Key',
'messaging.setupDesc': 'Register your encryption key on-chain to start sending and receiving encrypted messages.',
'messaging.unlockTitle': 'Unlock Your Messages',
'messaging.unlockDesc': 'Sign with your wallet to unlock message decryption for this session.',
'messaging.setupKey': 'Setup Key',
'messaging.unlock': 'Unlock',
'messaging.signing': 'Signing...',
'messaging.newMessage': 'New',
'messaging.messages': 'messages',
'messaging.sent': 'sent',
'messaging.emptyInbox': 'No messages yet.',
'messaging.sendFirst': 'Send your first message',
'messaging.encrypted': '[Encrypted]',
'messaging.compose': 'New Message',
'messaging.composeDesc': 'Send an end-to-end encrypted message on-chain.',
'messaging.recipient': 'Recipient Address',
'messaging.message': 'Message',
'messaging.typePlaceholder': 'Type your message...',
'messaging.tooLong': 'Message exceeds maximum size (512 bytes)',
'messaging.noRecipientKey': 'Recipient has no encryption key registered',
'messaging.checkingKey': 'Checking encryption key...',
'messaging.send': 'Send',
'messaging.sending': 'Sending...',
}
+30
View File
@@ -3761,4 +3761,34 @@ export default {
'websocket.liveUpdates': 'به‌روزرسانی زنده فعال',
'websocket.offlineMode': 'حالت آفلاین',
// Navigation - Messaging
'nav.message': 'پیام',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'اتصال کیف پول',
'messaging.connectWalletDesc': 'برای استفاده از پیام‌رسانی رمزنگاری‌شده کیف پول خود را متصل کنید.',
'messaging.setupTitle': 'تنظیم کلید رمزنگاری',
'messaging.setupDesc': 'کلید رمزنگاری خود را روی زنجیره ثبت کنید تا بتوانید پیام‌های رمزنگاری‌شده ارسال و دریافت کنید.',
'messaging.unlockTitle': 'باز کردن پیام‌ها',
'messaging.unlockDesc': 'برای فعال‌سازی رمزگشایی پیام‌ها در این نشست با کیف پول خود امضا کنید.',
'messaging.setupKey': 'تنظیم کلید',
'messaging.unlock': 'باز کردن',
'messaging.signing': 'در حال امضا...',
'messaging.newMessage': 'جدید',
'messaging.messages': 'پیام',
'messaging.sent': 'ارسال شده',
'messaging.emptyInbox': 'هنوز پیامی نیست.',
'messaging.sendFirst': 'اولین پیام خود را ارسال کنید',
'messaging.encrypted': '[رمزنگاری‌شده]',
'messaging.compose': 'پیام جدید',
'messaging.composeDesc': 'یک پیام رمزنگاری‌شده سرتاسری روی زنجیره ارسال کنید.',
'messaging.recipient': 'آدرس گیرنده',
'messaging.message': 'پیام',
'messaging.typePlaceholder': 'پیام خود را بنویسید...',
'messaging.tooLong': 'پیام از حداکثر اندازه فراتر رفته (۵۱۲ بایت)',
'messaging.noRecipientKey': 'گیرنده کلید رمزنگاری ثبت‌شده ندارد',
'messaging.checkingKey': 'بررسی کلید رمزنگاری...',
'messaging.send': 'ارسال',
'messaging.sending': 'در حال ارسال...',
};
+30
View File
@@ -3744,4 +3744,34 @@ export default {
'websocket.liveUpdates': 'Nûvekirinên zindî çalak in',
'websocket.offlineMode': 'Moda Negirêdayî',
// Navigation - Messaging
'nav.message': 'Peyam',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'Berîka Xwe Girêbide',
'messaging.connectWalletDesc': 'Ji bo bikaranîna peyamên şîfrekirî berîka xwe girêbide.',
'messaging.setupTitle': 'Mifteya Şîfrekirinê Saz Bike',
'messaging.setupDesc': 'Ji bo şandina û wergirtina peyamên şîfrekirî mifteya xwe li ser zincîrê tomar bike.',
'messaging.unlockTitle': 'Peyamên Xwe Veke',
'messaging.unlockDesc': 'Ji bo vekirina şîfreya peyaman di vê danişînê de bi berîka xwe re îmze bike.',
'messaging.setupKey': 'Mifteyê Saz Bike',
'messaging.unlock': 'Veke',
'messaging.signing': 'Tê îmzekirin...',
'messaging.newMessage': 'Nû',
'messaging.messages': 'peyam',
'messaging.sent': 'hatine şandin',
'messaging.emptyInbox': 'Hîn peyam tune.',
'messaging.sendFirst': 'Peyama xwe ya yekem bişîne',
'messaging.encrypted': '[Şîfrekirî]',
'messaging.compose': 'Peyama Nû',
'messaging.composeDesc': 'Li ser zincîrê peyamek şîfrekirî ji destpêk heta dawiyê bişîne.',
'messaging.recipient': 'Navnîşana Wergir',
'messaging.message': 'Peyam',
'messaging.typePlaceholder': 'Peyama xwe binivîse...',
'messaging.tooLong': 'Peyam ji mezinahiya herî zêde derbas dibe (512 byte)',
'messaging.noRecipientKey': 'Wergir mifteya şîfrekirinê tune ye',
'messaging.checkingKey': 'Mifteya şîfrekirinê tê kontrol kirin...',
'messaging.send': 'Bişîne',
'messaging.sending': 'Tê şandin...',
};
+31
View File
@@ -3746,4 +3746,35 @@ export default {
'websocket.reconnecting': 'Yeniden bağlanıyor...',
'websocket.liveUpdates': 'Canlı güncellemeler etkin',
'websocket.offlineMode': 'Çevrimdışı mod',
// Navigation - Messaging
'nav.message': 'Mesaj',
// Messaging
'messaging.title': 'PEZMessage',
'messaging.connectWallet': 'Cüzdan Bağla',
'messaging.connectWalletDesc': 'Şifreli mesajlaşmayı kullanmak için cüzdanınızı bağlayın.',
'messaging.setupTitle': 'Şifreleme Anahtarı Oluştur',
'messaging.setupDesc': 'Şifreli mesaj gönderip almak için şifreleme anahtarınızı zincire kaydedin.',
'messaging.unlockTitle': 'Mesajlarınızı Açın',
'messaging.unlockDesc': 'Bu oturum için mesaj şifre çözümünü etkinleştirmek üzere cüzdanınızla imzalayın.',
'messaging.setupKey': 'Anahtar Oluştur',
'messaging.unlock': 'Kilidi Aç',
'messaging.signing': 'İmzalanıyor...',
'messaging.newMessage': 'Yeni',
'messaging.messages': 'mesaj',
'messaging.sent': 'gönderildi',
'messaging.emptyInbox': 'Henüz mesaj yok.',
'messaging.sendFirst': 'İlk mesajınızı gönderin',
'messaging.encrypted': '[Şifreli]',
'messaging.compose': 'Yeni Mesaj',
'messaging.composeDesc': 'Zincir üzerinde uçtan uca şifreli mesaj gönderin.',
'messaging.recipient': 'Alıcı Adresi',
'messaging.message': 'Mesaj',
'messaging.typePlaceholder': 'Mesajınızı yazın...',
'messaging.tooLong': 'Mesaj maksimum boyutu aşıyor (512 bayt)',
'messaging.noRecipientKey': 'Alıcının kayıtlı şifreleme anahtarı yok',
'messaging.checkingKey': 'Şifreleme anahtarı kontrol ediliyor...',
'messaging.send': 'Gönder',
'messaging.sending': 'Gönderiliyor...',
};