diff --git a/src/locales/ar.json b/src/locales/ar.json index 0f8af64e..3c023b8c 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "استقبال البيتكوين", "description": "شارك عنواناً لاستقبال البيتكوين.", - "onChain": "على السلسلة", - "silentPayment": "دفع صامت", - "onChainIntro": "عنوان جديد في كل مرة. انتقل إلى فهرس جديد بعد المشاركة للحفاظ على الخصوصية.", "addressIndex": "العنوان رقم {{index}}", "newAddress": "عنوان جديد", - "silentIntro": "معرّف استقبال ثابت. شاركه مرة واحدة وأعد استخدامه إلى الأبد — يشتقّ المرسلون عنواناً فريداً على السلسلة لكل دفعة.", - "noIndexer": "تم تعطيل المسح — لا يوجد مفهرس BIP-352 مُهيّأ. اضبط <0>bip352IndexerUrl في إعدادات التطبيق لاكتشاف المدفوعات الصامتة الواردة.", - "silentBalance": "رصيد الدفع الصامت: <0>{{amount}}", "scanForNew": "فحص المدفوعات الجديدة", "scanForPayments": "فحص المدفوعات" }, diff --git a/src/locales/en.json b/src/locales/en.json index c58bb6db..479bcbcb 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1177,14 +1177,8 @@ "receiveDialog": { "title": "Receive Bitcoin", "description": "Share an address to receive bitcoin.", - "onChain": "On-chain", - "silentPayment": "Silent payment", - "onChainIntro": "Fresh address each time. Bump to a new index after sharing for privacy.", "addressIndex": "Address #{{index}}", "newAddress": "New address", - "silentIntro": "Static receive identifier. Share once and reuse forever — senders derive a unique on-chain address per payment.", - "noIndexer": "Scanning disabled — no BIP-352 indexer configured. Set <0>bip352IndexerUrl in your app config to detect incoming silent payments.", - "silentBalance": "Silent payment balance: <0>{{amount}}", "scanForNew": "Scan for new payments", "scanForPayments": "Scan for payments" }, diff --git a/src/locales/es.json b/src/locales/es.json index 3220441b..397a4c39 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "Recibir Bitcoin", "description": "Comparte una dirección para recibir bitcoin.", - "onChain": "En cadena", - "silentPayment": "Pago silencioso", - "onChainIntro": "Dirección nueva cada vez. Pasa a un nuevo índice después de compartirla para preservar tu privacidad.", "addressIndex": "Dirección n.º {{index}}", "newAddress": "Nueva dirección", - "silentIntro": "Identificador de recepción estático. Compártelo una vez y reutilízalo para siempre: los remitentes derivan una dirección única en cadena para cada pago.", - "noIndexer": "Escaneo desactivado: no hay indexador BIP-352 configurado. Define <0>bip352IndexerUrl en la configuración de tu aplicación para detectar pagos silenciosos entrantes.", - "silentBalance": "Saldo de pago silencioso: <0>{{amount}}", "scanForNew": "Buscar nuevos pagos", "scanForPayments": "Buscar pagos" }, diff --git a/src/locales/fa.json b/src/locales/fa.json index 71566763..a232fa48 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "دریافت بیت‌کوین", "description": "برای دریافت بیت‌کوین، یک نشانی به اشتراک بگذارید.", - "onChain": "روی زنجیره", - "silentPayment": "پرداخت خاموش", - "onChainIntro": "هر بار نشانی تازه. پس از اشتراک‌گذاری، برای حفظ حریم خصوصی به یک نمایه جدید بروید.", "addressIndex": "نشانی شمارهٔ {{index}}", "newAddress": "نشانی جدید", - "silentIntro": "شناسهٔ دریافت ایستا. یک‌بار به اشتراک بگذارید و برای همیشه استفاده کنید — فرستندگان برای هر پرداخت یک نشانی منحصربه‌فرد روی زنجیره مشتق می‌کنند.", - "noIndexer": "پویش غیرفعال است — هیچ ایندکس‌کنندهٔ BIP-352 پیکربندی نشده است. برای شناسایی پرداخت‌های خاموش ورودی، <0>bip352IndexerUrl را در پیکربندی برنامه تنظیم کنید.", - "silentBalance": "موجودی پرداخت خاموش: <0>{{amount}}", "scanForNew": "پویش پرداخت‌های جدید", "scanForPayments": "پویش پرداخت‌ها" }, diff --git a/src/locales/fr.json b/src/locales/fr.json index b1b9bede..e8f2559e 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1177,14 +1177,8 @@ "receiveDialog": { "title": "Recevoir du Bitcoin", "description": "Partagez une adresse pour recevoir du bitcoin.", - "onChain": "Sur la chaîne", - "silentPayment": "Paiement silencieux", - "onChainIntro": "Nouvelle adresse à chaque fois. Passez à un nouvel index après partage pour la confidentialité.", "addressIndex": "Adresse n°{{index}}", "newAddress": "Nouvelle adresse", - "silentIntro": "Identifiant de réception statique. Partagez une fois et réutilisez à vie — les expéditeurs dérivent une adresse on-chain unique par paiement.", - "noIndexer": "Scan désactivé — aucun indexeur BIP-352 configuré. Définissez <0>bip352IndexerUrl dans votre configuration d'application pour détecter les paiements silencieux entrants.", - "silentBalance": "Solde des paiements silencieux : <0>{{amount}}", "scanForNew": "Scanner les nouveaux paiements", "scanForPayments": "Scanner les paiements" }, diff --git a/src/locales/hi.json b/src/locales/hi.json index c9c2b34a..1ae88823 100644 --- a/src/locales/hi.json +++ b/src/locales/hi.json @@ -1177,14 +1177,8 @@ "receiveDialog": { "title": "Bitcoin पाएँ", "description": "Bitcoin पाने के लिए एक एड्रेस शेयर करें।", - "onChain": "ऑन-चेन", - "silentPayment": "साइलेंट पेमेंट", - "onChainIntro": "हर बार नया एड्रेस। प्राइवेसी के लिए शेयर करने के बाद नए index पर बढ़ाएँ।", "addressIndex": "एड्रेस #{{index}}", "newAddress": "नया एड्रेस", - "silentIntro": "स्थिर रिसीव पहचानकर्ता। एक बार शेयर करें और हमेशा के लिए दोहराते रहें — भेजने वाले हर भुगतान के लिए एक अनूठा ऑन-चेन एड्रेस derive करते हैं।", - "noIndexer": "Scanning अक्षम है — कोई BIP-352 indexer कॉन्फ़िगर नहीं है। आने वाले साइलेंट पेमेंट का पता लगाने के लिए अपनी ऐप कॉन्फ़िग में <0>bip352IndexerUrl सेट करें।", - "silentBalance": "साइलेंट पेमेंट बैलेंस: <0>{{amount}}", "scanForNew": "नए भुगतान के लिए scan करें", "scanForPayments": "भुगतान के लिए scan करें" }, diff --git a/src/locales/id.json b/src/locales/id.json index 2db55946..f7991bb9 100644 --- a/src/locales/id.json +++ b/src/locales/id.json @@ -1186,14 +1186,8 @@ "receiveDialog": { "title": "Terima Bitcoin", "description": "Bagikan alamat untuk menerima bitcoin.", - "onChain": "On-chain", - "silentPayment": "Silent payment", - "onChainIntro": "Alamat baru setiap saat. Naikkan ke indeks baru setelah berbagi untuk privasi.", "addressIndex": "Alamat #{{index}}", "newAddress": "Alamat baru", - "silentIntro": "Pengenal penerima statis. Bagikan sekali dan gunakan kembali selamanya — pengirim menurunkan alamat on-chain unik per pembayaran.", - "noIndexer": "Pemindaian dinonaktifkan — tidak ada indexer BIP-352 yang dikonfigurasi. Setel <0>bip352IndexerUrl di konfigurasi aplikasi Anda untuk mendeteksi silent payment masuk.", - "silentBalance": "Saldo silent payment: <0>{{amount}}", "scanForNew": "Pindai pembayaran baru", "scanForPayments": "Pindai pembayaran" }, diff --git a/src/locales/km.json b/src/locales/km.json index ca39751f..5ab052a8 100644 --- a/src/locales/km.json +++ b/src/locales/km.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "ទទួល Bitcoin", "description": "ចែករំលែកអាសយដ្ឋានដើម្បីទទួល Bitcoin។", - "onChain": "លើខ្សែសង្វាក់", - "silentPayment": "ការទូទាត់ស្ងាត់", - "onChainIntro": "អាសយដ្ឋានថ្មីរាល់ពេល។ បន្ទាប់ពីចែករំលែករួច សូមផ្លាស់ទៅសន្ទស្សន៍ថ្មីដើម្បីការពារភាពឯកជន។", "addressIndex": "អាសយដ្ឋាន #{{index}}", "newAddress": "អាសយដ្ឋានថ្មី", - "silentIntro": "អត្តសញ្ញាណទទួលនៅស្ងៀម។ ចែករំលែកម្ដងហើយប្រើឡើងវិញជារៀងរហូត — អ្នកផ្ញើបង្កើតអាសយដ្ឋានពិសេសលើខ្សែសង្វាក់សម្រាប់ការទូទាត់នីមួយៗ។", - "noIndexer": "ការស្កេនត្រូវបានបិទ — គ្មានអ្នកធ្វើលិបិក្រម BIP-352 បានកំណត់ទេ។ កំណត់ <0>bip352IndexerUrl ក្នុងការកំណត់កម្មវិធីរបស់អ្នកដើម្បីរកការទូទាត់ស្ងាត់ដែលចូលមក។", - "silentBalance": "សមតុល្យការទូទាត់ស្ងាត់៖ <0>{{amount}}", "scanForNew": "ស្កេនការទូទាត់ថ្មី", "scanForPayments": "ស្កេនការទូទាត់" }, diff --git a/src/locales/ps.json b/src/locales/ps.json index eafc1500..c2c3dede 100644 --- a/src/locales/ps.json +++ b/src/locales/ps.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "د بټکوین ترلاسه کول", "description": "د بټکوین د ترلاسه کولو لپاره یوه پته شریکه کړئ.", - "onChain": "په زنځیر کې", - "silentPayment": "چوپه ورکړه", - "onChainIntro": "هر ځل نوې پته. د شریکولو وروسته د محرمیت لپاره یوې نوې شمارلیکې ته لاړ شئ.", "addressIndex": "پته #{{index}}", "newAddress": "نوې پته", - "silentIntro": "د ترلاسه کولو ثابته پېژند. یوځل شریکه کړئ او د تل لپاره بیا یې کاروئ — لیږونکي د هرې ورکړې لپاره په زنځیر کې یوه ځانګړې پته راپیدا کوي.", - "noIndexer": "سکن غیرفعال دی — د BIP-352 ایندکس کوونکی نه دی تنظیم شوی. د راتلونکو چوپو ورکړو د کشف لپاره ستاسو د اپلیکیشن تنظیماتو کې <0>bip352IndexerUrl وټاکئ.", - "silentBalance": "د چوپې ورکړې بیلانس: <0>{{amount}}", "scanForNew": "د نوو ورکړو لپاره سکن", "scanForPayments": "د ورکړو لپاره سکن" }, diff --git a/src/locales/pt.json b/src/locales/pt.json index c406c705..11f1b2ba 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -1177,14 +1177,8 @@ "receiveDialog": { "title": "Receber Bitcoin", "description": "Compartilhe um endereço para receber bitcoin.", - "onChain": "On-chain", - "silentPayment": "Pagamento silencioso", - "onChainIntro": "Endereço novo a cada vez. Avance para um novo índice após compartilhar para privacidade.", "addressIndex": "Endereço n.º {{index}}", "newAddress": "Novo endereço", - "silentIntro": "Identificador de recebimento estático. Compartilhe uma vez e reutilize para sempre — remetentes derivam um endereço on-chain único por pagamento.", - "noIndexer": "Escaneamento desativado — nenhum indexador BIP-352 configurado. Defina <0>bip352IndexerUrl na sua configuração do app para detectar pagamentos silenciosos recebidos.", - "silentBalance": "Saldo de pagamentos silenciosos: <0>{{amount}}", "scanForNew": "Escanear novos pagamentos", "scanForPayments": "Escanear pagamentos" }, diff --git a/src/locales/ru.json b/src/locales/ru.json index 24caf03d..2907c3ae 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -1177,14 +1177,8 @@ "receiveDialog": { "title": "Получить Bitcoin", "description": "Поделитесь адресом для получения bitcoin.", - "onChain": "В блокчейне", - "silentPayment": "Тихий платёж", - "onChainIntro": "Свежий адрес каждый раз. Переходите на новый индекс после публикации для конфиденциальности.", "addressIndex": "Адрес №{{index}}", "newAddress": "Новый адрес", - "silentIntro": "Статический идентификатор получения. Поделитесь один раз и используйте навсегда — отправители получают уникальный адрес в блокчейне на каждый платёж.", - "noIndexer": "Сканирование отключено — индексер BIP-352 не настроен. Установите <0>bip352IndexerUrl в конфигурации вашего приложения, чтобы обнаруживать входящие тихие платежи.", - "silentBalance": "Баланс тихих платежей: <0>{{amount}}", "scanForNew": "Сканировать новые платежи", "scanForPayments": "Сканировать платежи" }, diff --git a/src/locales/sn.json b/src/locales/sn.json index 4315ecbe..5238794e 100644 --- a/src/locales/sn.json +++ b/src/locales/sn.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "Gamuchira Bitcoin", "description": "Govera kero yokugamuchira bitcoin.", - "onChain": "PaCheni", - "silentPayment": "Mubhadharo wakanyararira", - "onChainIntro": "Kero itsva nguva dzese. Chinjira kune index itsva mushure mokugovera kuti uchengetedze privacy.", "addressIndex": "Kero #{{index}}", "newAddress": "Kero itsva", - "silentIntro": "Chiratidzo chokugamuchira chakamira. Govera kamwe woshandisazve nokusingaperi — vatumiri vanobvisa kero yakasiyana pacheni pamubhadharo woga woga.", - "noIndexer": "Kuongorora kwadzimwa — hapana muongorori weBIP-352 wakaiswa. Isa <0>bip352IndexerUrl mukurongedzwa kweapp yako kuti uone mibhadharo yakanyararira inopinda.", - "silentBalance": "Bharanzi remubhadharo wakanyararira: <0>{{amount}}", "scanForNew": "Tsvaga mibhadharo mitsva", "scanForPayments": "Tsvaga mibhadharo" }, diff --git a/src/locales/tr.json b/src/locales/tr.json index b4795980..37d1620a 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -1186,14 +1186,8 @@ "receiveDialog": { "title": "Bitcoin Al", "description": "Bitcoin almak için bir adres paylaşın.", - "onChain": "Zincir üstü", - "silentPayment": "Sessiz ödeme", - "onChainIntro": "Her seferinde yeni adres. Gizlilik için paylaşımdan sonra yeni bir dizine geçin.", "addressIndex": "Adres #{{index}}", "newAddress": "Yeni adres", - "silentIntro": "Sabit alım tanımlayıcısı. Bir kez paylaşın ve sonsuza dek tekrar kullanın — göndericiler her ödeme için benzersiz bir zincir üstü adres türetir.", - "noIndexer": "Tarama devre dışı — BIP-352 indeksleyici yapılandırılmamış. Gelen sessiz ödemeleri algılamak için uygulama yapılandırmanızda <0>bip352IndexerUrl ayarını yapın.", - "silentBalance": "Sessiz ödeme bakiyesi: <0>{{amount}}", "scanForNew": "Yeni ödemeler için tara", "scanForPayments": "Ödemeler için tara" }, diff --git a/src/locales/zh-Hant.json b/src/locales/zh-Hant.json index 4e48db29..cfa7a8aa 100644 --- a/src/locales/zh-Hant.json +++ b/src/locales/zh-Hant.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "接收比特幣", "description": "分享一個地址以接收比特幣。", - "onChain": "鏈上", - "silentPayment": "靜默支付", - "onChainIntro": "每次都生成新地址。分享後請切換到新索引以保護隱私。", "addressIndex": "地址 #{{index}}", "newAddress": "新地址", - "silentIntro": "靜態接收識別符號。一次分享,永久複用——傳送方為每筆支付派生唯一的鏈上地址。", - "noIndexer": "掃描已停用——未配置 BIP-352 索引器。在應用配置中設定 <0>bip352IndexerUrl 以檢測傳入的靜默支付。", - "silentBalance": "靜默支付餘額:<0>{{amount}}", "scanForNew": "掃描新支付", "scanForPayments": "掃描支付" }, diff --git a/src/locales/zh.json b/src/locales/zh.json index dec68ee1..6726101a 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -754,14 +754,8 @@ "receiveDialog": { "title": "接收比特币", "description": "分享一个地址以接收比特币。", - "onChain": "链上", - "silentPayment": "静默支付", - "onChainIntro": "每次都生成新地址。分享后请切换到新索引以保护隐私。", "addressIndex": "地址 #{{index}}", "newAddress": "新地址", - "silentIntro": "静态接收标识符。一次分享,永久复用——发送方为每笔支付派生唯一的链上地址。", - "noIndexer": "扫描已禁用——未配置 BIP-352 索引器。在应用配置中设置 <0>bip352IndexerUrl 以检测传入的静默支付。", - "silentBalance": "静默支付余额:<0>{{amount}}", "scanForNew": "扫描新支付", "scanForPayments": "扫描支付" }, diff --git a/src/pages/WalletPage.tsx b/src/pages/WalletPage.tsx index 6a2fa9ca..106e94c4 100644 --- a/src/pages/WalletPage.tsx +++ b/src/pages/WalletPage.tsx @@ -1,7 +1,7 @@ import { useRef, useState } from 'react'; import { Link } from 'react-router-dom'; import { useSeoMeta } from '@unhead/react'; -import { useTranslation, Trans } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; import { Copy, Check, @@ -34,7 +34,6 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { HDSendBitcoinDialog } from '@/components/HDSendBitcoinDialog'; import { HDSilentPaymentScanDialog } from '@/components/HDSilentPaymentScanDialog'; import { WalletBackupMnemonicDialog } from '@/components/WalletBackupMnemonic'; @@ -64,8 +63,7 @@ export function WalletPage() { const sp = useHdWalletSp(); const { data: btcPrice } = useHdBtcPrice(); - const [copiedAddress, setCopiedAddress] = useState(false); - const [copiedSp, setCopiedSp] = useState(false); + const [copiedPayload, setCopiedPayload] = useState(false); const [txOpen, setTxOpen] = useState(false); const [sendOpen, setSendOpen] = useState(false); const [receiveOpen, setReceiveOpen] = useState(false); @@ -80,36 +78,30 @@ export function WalletPage() { const address = currentReceiveAddress?.address ?? ''; const spAddress = silentPaymentAddress?.address ?? ''; - const copyAddress = async () => { - if (!address) return; + // Combined BIP-21 payload: `bitcoin:?sp=` when both are + // available, falling back to the single endpoint that exists. + // Mirrors the campaign donate panel's QR payload so BIP-352-aware + // wallets pick the `sp=` parameter and legacy wallets fall back to + // the on-chain address. + const qrPayload = address && spAddress + ? `bitcoin:${address}?sp=${spAddress}` + : address + ? `bitcoin:${address}` + : spAddress + ? `bitcoin:?sp=${spAddress}` + : ''; + + const copyPayload = async () => { + if (!qrPayload) return; try { - await navigator.clipboard.writeText(address); - setCopiedAddress(true); - setTimeout(() => setCopiedAddress(false), 2000); + await navigator.clipboard.writeText(qrPayload); + setCopiedPayload(true); + setTimeout(() => setCopiedPayload(false), 2000); } catch { // clipboard unavailable } }; - const copySpAddress = async () => { - if (!spAddress) return; - try { - await navigator.clipboard.writeText(spAddress); - setCopiedSp(true); - setTimeout(() => setCopiedSp(false), 2000); - } catch { - // clipboard unavailable - } - }; - - const truncatedAddress = address - ? `${address.slice(0, 12)}...${address.slice(-8)}` - : ''; - - const truncatedSpAddress = spAddress - ? `${spAddress.slice(0, 12)}...${spAddress.slice(-8)}` - : ''; - // ── Logged out ──────────────────────────────────────────────── if (availability.status === 'logged-out') { return ( @@ -185,6 +177,14 @@ export function WalletPage() { {t('walletSettings.backup.label')} + {sp.enabled && spAddress && ( + setSpScanOpen(true)} className="cursor-pointer"> + + {sp.storage?.scanHeight && sp.storage.scanHeight > 0 + ? t('wallet.receiveDialog.scanForNew') + : t('wallet.receiveDialog.scanForPayments')} + + )} @@ -291,115 +291,45 @@ export function WalletPage() { - - - {t('wallet.receiveDialog.onChain')} - - {t('wallet.receiveDialog.silentPayment')} - - + {qrPayload && ( +
+ {/* Combined BIP-21 QR. BIP-352-aware wallets pick the + `sp=` parameter; legacy wallets fall back to the + on-chain address. Mirrors CampaignWalletDonatePanel. */} +
+ +
+ + {/* Copyable row showing the full payment URI. */} + - {/* ── On-chain (BIP86 single-use) ──────────────── */} - {address && ( -
-

- {t('wallet.receiveDialog.onChainIntro')} -

- -
- -
- +
+ {t('wallet.receiveDialog.addressIndex', { index: currentReceiveAddress?.index ?? 0 })} + · - -
- {t('wallet.receiveDialog.addressIndex', { index: currentReceiveAddress?.index ?? 0 })} - · - -
)} - - - {/* ── Silent payment (BIP-352 static) ──────────── */} - - {spAddress && ( -
-

- {t('wallet.receiveDialog.silentIntro')} -

- -
- -
- - - - {sp.unavailableReason === 'no-indexer' ? ( -

- }} - /> -

- ) : sp.enabled ? ( -
- {sp.balance > 0 && ( -

- }} - /> -

- )} - -
- ) : null} -
- )} -
- +
+ )}