feat: add P2P deposit/withdraw flow for Telegram mini app

- New request-withdraw-telegram edge function (session token auth)
- New DepositWithdrawModal component with deposit/withdraw tabs
- Deposit: platform wallet display, TX hash verification, on-chain check
- Withdraw: token select, amount, fee display, balance validation
- BalanceCard: deposit/withdraw buttons always visible
- P2P section: modal state management and balance refresh on success
- p2p-api: verifyDeposit and requestWithdraw functions
- i18n: 24 new translation keys across all 6 languages
This commit is contained in:
2026-02-26 20:33:31 +03:00
parent 0606f93146
commit b711524d57
14 changed files with 1142 additions and 10 deletions
+25
View File
@@ -395,6 +395,31 @@ const ar: Translations = {
fake_payment_proof: 'إثبات دفع مزور',
other: 'أخرى',
},
// Deposit / Withdraw
deposit: 'إيداع',
withdraw: 'سحب',
platformWallet: 'عنوان محفظة المنصة',
txHash: 'هاش المعاملة',
txHashPlaceholder: '0x...',
blockNumber: 'رقم الكتلة',
optional: 'اختياري',
verifyDeposit: 'تحقق من الإيداع',
verifying: 'جارٍ التحقق...',
verifyingDesc: 'يتم فحص المعاملة على السلسلة. قد يستغرق هذا حتى ٦٠ ثانية.',
depositSuccess: 'تم الإيداع بنجاح!',
depositFailed: 'فشل الإيداع',
depositInstructions: 'أرسل التوكنات إلى عنوان محفظة المنصة أدناه، ثم الصق هاش المعاملة للتحقق.',
depositInvalidAmount: 'يرجى إدخال مبلغ صالح',
selectToken: 'اختر التوكن',
withdrawAmount: 'مبلغ السحب',
networkFee: 'رسوم الشبكة',
netAmount: 'المبلغ المستلم',
withdrawSuccess: 'تم طلب السحب!',
withdrawProcessing: 'يتم معالجة سحبك. سيتم إرسال التوكنات إلى محفظتك قريباً.',
withdrawing: 'جارٍ المعالجة...',
minWithdraw: 'الحد الأدنى للسحب',
maxAvailable: 'الحد الأقصى',
walletAddress: 'عنوان المحفظة',
noTrades: 'لا توجد صفقات بعد',
},
+25
View File
@@ -397,6 +397,31 @@ const ckb: Translations = {
fake_payment_proof: 'بەڵگەی پارەدانی ساختە',
other: 'هی تر',
},
// Deposit / Withdraw
deposit: 'پارە دابنێ',
withdraw: 'پارە دەربهێنە',
platformWallet: 'ناونیشانی جزدانی پلاتفۆرم',
txHash: 'هاشی مامەڵە',
txHashPlaceholder: '0x...',
blockNumber: 'ژمارەی بلۆک',
optional: 'ئارەزوومەندانە',
verifyDeposit: 'پشتڕاستکردنەوەی پارەدانان',
verifying: 'پشتڕاستدەکرێتەوە...',
verifyingDesc: 'مامەڵە لەسەر زنجیرە پشکنین دەکرێت. ئەمە دەکرێت تا ٦٠ چرکە بخایەنێت.',
depositSuccess: 'پارەدانان سەرکەوتوو بوو!',
depositFailed: 'پارەدانان سەرنەکەوت',
depositInstructions: 'تۆکن بنێرە بۆ ناونیشانی جزدانی پلاتفۆرمی خوارەوە، پاشان هاشی مامەڵە بلکێنە بۆ پشتڕاستکردنەوە.',
depositInvalidAmount: 'تکایە بڕێکی دروست بنووسە',
selectToken: 'تۆکن هەڵبژێرە',
withdrawAmount: 'بڕی دەرهێنان',
networkFee: 'کرێی تۆڕ',
netAmount: 'وەردەگریت',
withdrawSuccess: 'داواکاری دەرهێنان دروستکرا!',
withdrawProcessing: 'دەرهێنانەکەت لە پرۆسەدایە. تۆکنەکان بەم زووانە دەنێردرێن بۆ جزدانەکەت.',
withdrawing: 'لە پرۆسەدایە...',
minWithdraw: 'کەمترین دەرهێنان',
maxAvailable: 'زۆرترین',
walletAddress: 'ناونیشانی جزدان',
noTrades: 'هێشتا بازرگانی نییە',
},
+25
View File
@@ -396,6 +396,31 @@ const en: Translations = {
fake_payment_proof: 'Fake payment proof',
other: 'Other',
},
// Deposit / Withdraw
deposit: 'Deposit',
withdraw: 'Withdraw',
platformWallet: 'Platform Wallet Address',
txHash: 'Transaction Hash',
txHashPlaceholder: '0x...',
blockNumber: 'Block Number',
optional: 'optional',
verifyDeposit: 'Verify Deposit',
verifying: 'Verifying...',
verifyingDesc: 'Checking on-chain transaction. This may take up to 60 seconds.',
depositSuccess: 'Deposit Successful!',
depositFailed: 'Deposit Failed',
depositInstructions: 'Send tokens to the platform wallet address below, then paste the transaction hash to verify.',
depositInvalidAmount: 'Please enter a valid amount',
selectToken: 'Select Token',
withdrawAmount: 'Withdrawal Amount',
networkFee: 'Network Fee',
netAmount: 'You Receive',
withdrawSuccess: 'Withdrawal Requested!',
withdrawProcessing: 'Your withdrawal is being processed. Tokens will be sent to your wallet shortly.',
withdrawing: 'Processing...',
minWithdraw: 'Min Withdrawal',
maxAvailable: 'Max',
walletAddress: 'Wallet Address',
noTrades: 'No trades yet',
},
+25
View File
@@ -396,6 +396,31 @@ const fa: Translations = {
fake_payment_proof: 'مدرک پرداخت جعلی',
other: 'سایر',
},
// Deposit / Withdraw
deposit: 'واریز',
withdraw: 'برداشت',
platformWallet: 'آدرس کیف پول پلتفرم',
txHash: 'هش تراکنش',
txHashPlaceholder: '0x...',
blockNumber: 'شماره بلاک',
optional: 'اختیاری',
verifyDeposit: 'تایید واریز',
verifying: 'در حال تایید...',
verifyingDesc: 'تراکنش روی زنجیره بررسی می‌شود. این ممکن است تا ۶۰ ثانیه طول بکشد.',
depositSuccess: 'واریز موفق!',
depositFailed: 'واریز ناموفق',
depositInstructions: 'توکن‌ها را به آدرس کیف پول پلتفرم زیر ارسال کنید، سپس هش تراکنش را برای تایید جایگذاری کنید.',
depositInvalidAmount: 'لطفا مقدار معتبری وارد کنید',
selectToken: 'انتخاب توکن',
withdrawAmount: 'مقدار برداشت',
networkFee: 'کارمزد شبکه',
netAmount: 'دریافتی شما',
withdrawSuccess: 'درخواست برداشت ثبت شد!',
withdrawProcessing: 'برداشت شما در حال پردازش است. توکن‌ها به زودی به کیف پول شما ارسال می‌شوند.',
withdrawing: 'در حال پردازش...',
minWithdraw: 'حداقل برداشت',
maxAvailable: 'حداکثر',
walletAddress: 'آدرس کیف پول',
noTrades: 'هنوز معامله‌ای نیست',
},
+25
View File
@@ -408,6 +408,31 @@ const krd: Translations = {
fake_payment_proof: 'Belgeya dravdanê ya sexte',
other: 'Yên din',
},
// Deposit / Withdraw
deposit: 'Depo Bike',
withdraw: 'Derxe',
platformWallet: 'Navnîşana Cûzdanê ya Platformê',
txHash: 'Hash ya Danûstandinê',
txHashPlaceholder: '0x...',
blockNumber: 'Hejmara Blokê',
optional: 'ne mecbûrî',
verifyDeposit: 'Depoyê Verast Bike',
verifying: 'Tê verast kirin...',
verifyingDesc: 'Danûstandin li ser zincîrê tê kontrol kirin. Ev dikare heya 60 çirkeyan bigire.',
depositSuccess: 'Depo Serkeftî!',
depositFailed: 'Depo Serneket',
depositInstructions: 'Token bişîne navnîşana cûzdanê ya platformê ya jêrîn, paşê hash ya danûstandinê bişkoje ji bo verastkirin.',
depositInvalidAmount: 'Ji kerema xwe mîqdarek derbasdar binivîsin',
selectToken: 'Token Hilbijêrin',
withdrawAmount: 'Mîqdara Derxistinê',
networkFee: 'Heqê Torê',
netAmount: 'Hûn Digirin',
withdrawSuccess: 'Daxwaza Derxistinê Hat Afirandin!',
withdrawProcessing: 'Derxistina we tê pêvajokirin. Token dê di demeke kurt de bên şandin bo cûzdanê we.',
withdrawing: 'Tê pêvajokirin...',
minWithdraw: 'Kêmtirîn Derxistin',
maxAvailable: 'Herî zêde',
walletAddress: 'Navnîşana Cûzdanê',
noTrades: 'Hê bazirganî tune',
},
+25
View File
@@ -396,6 +396,31 @@ const tr: Translations = {
fake_payment_proof: 'Sahte ödeme kanıtı',
other: 'Diğer',
},
// Deposit / Withdraw
deposit: 'Yatır',
withdraw: 'Çek',
platformWallet: 'Platform Cüzdan Adresi',
txHash: 'İşlem Hash',
txHashPlaceholder: '0x...',
blockNumber: 'Blok Numarası',
optional: 'isteğe bağlı',
verifyDeposit: 'Yatırmayı Doğrula',
verifying: 'Doğrulanıyor...',
verifyingDesc: 'Zincir üzerinde işlem kontrol ediliyor. Bu 60 saniyeye kadar sürebilir.',
depositSuccess: 'Yatırma Başarılı!',
depositFailed: 'Yatırma Başarısız',
depositInstructions: 'Aşağıdaki platform cüzdan adresine token gönderin, ardından doğrulamak için işlem hash yapıştırın.',
depositInvalidAmount: 'Geçerli bir miktar girin',
selectToken: 'Token Seçin',
withdrawAmount: 'Çekim Miktarı',
networkFee: 'Ağ Ücreti',
netAmount: 'Alacağınız',
withdrawSuccess: 'Çekim Talebi Oluşturuldu!',
withdrawProcessing: 'Çekim işleminiz işleniyor. Tokenler kısa sürede cüzdanınıza gönderilecek.',
withdrawing: 'İşleniyor...',
minWithdraw: 'Min Çekim',
maxAvailable: 'Maks',
walletAddress: 'Cüzdan Adresi',
noTrades: 'Henüz işlem yok',
},
+25
View File
@@ -406,6 +406,31 @@ export interface Translations {
fake_payment_proof: string;
other: string;
};
// Deposit / Withdraw
deposit: string;
withdraw: string;
platformWallet: string;
txHash: string;
txHashPlaceholder: string;
blockNumber: string;
optional: string;
verifyDeposit: string;
verifying: string;
verifyingDesc: string;
depositSuccess: string;
depositFailed: string;
depositInstructions: string;
depositInvalidAmount: string;
selectToken: string;
withdrawAmount: string;
networkFee: string;
netAmount: string;
withdrawSuccess: string;
withdrawProcessing: string;
withdrawing: string;
minWithdraw: string;
maxAvailable: string;
walletAddress: string;
// No data
noTrades: string;
};