feat: v2 — view-key payment confirmation with live monitoring

- Payment monitor: enter private view key to track incoming payments
- Scans mempool + last 100 blocks via PHP proxy with 4-node failover
- Lightweight crypto: 30KB noble-curves bundle (Ed25519 + Keccak-256)
- Subaddress support (network byte 42 detection, a*D validation)
- Confirmation progress bar (0-10 confirmations)
- Underpayment detection
- Deadline badges (7/14/30 days) replacing minutes input
- QR code: standard colors (black on white) for wallet scanner compatibility
- QR hint positioned below QR code
- View key masked input, never stored or transmitted
This commit is contained in:
Alexander Schmidt
2026-03-25 09:09:46 +01:00
parent 35552b7dff
commit 1acf990943
9 changed files with 1062 additions and 31 deletions

52
i18n.js
View File

@@ -14,8 +14,9 @@ var I18n = (function () {
label_amount: 'Betrag',
label_desc: 'Beschreibung (optional)',
placeholder_desc: 'z.B. Rechnung #42, Freelance-Arbeit...',
label_timer: 'Zahlungsfrist in Minuten (optional)',
placeholder_timer: 'z.B. 30',
label_timer: 'Zahlungsfrist (optional)',
days: 'Tage',
placeholder_timer_custom: 'Tage',
btn_generate: 'Zahlungsanforderung erstellen',
btn_open_wallet: 'In Wallet öffnen',
btn_copy_addr: 'Adresse kopieren',
@@ -25,8 +26,25 @@ var I18n = (function () {
btn_new_request: 'Neue Zahlungsanforderung',
toast_copied: 'Kopiert!',
countdown_expired: 'Zahlungsfrist abgelaufen',
countdown_remaining: 'Zahlungsfrist: ',
rates_offline: 'Kurse nicht verfügbar — nur XMR-Betrag möglich'
countdown_remaining_days: 'Zahlungsfrist: {d} Tage, {h}:{m}:{s}',
countdown_remaining_hours: 'Zahlungsfrist: {h}:{m}:{s}',
rates_offline: 'Kurse nicht verfügbar — nur XMR-Betrag möglich',
btn_monitor: 'Zahlung überwachen',
label_view_key: 'Privater View-Key',
placeholder_view_key: '64 Hex-Zeichen...',
hint_view_key: 'Der View-Key verlässt nie deinen Browser',
btn_start_monitor: 'Überwachung starten',
btn_stop_monitor: 'Überwachung beenden',
monitor_connecting: 'Verbinde mit Node...',
monitor_scanning: 'Scanne Mempool...',
monitor_waiting: 'Warte auf Zahlung...',
monitor_mempool: 'Zahlung erkannt (unbestätigt)',
monitor_confirmed: 'Zahlung bestätigt',
monitor_confirmations: '{n}/10 Bestätigungen',
monitor_underpaid: 'Unterzahlung erkannt',
monitor_underpaid_detail: 'Erwartet: {expected} XMR — Erhalten: {received} XMR',
monitor_node_error: 'Node nicht erreichbar — versuche nächsten...',
monitor_loading: 'Lade Kryptografie-Modul...'
},
en: {
subtitle: 'Monero payment request in seconds',
@@ -35,8 +53,9 @@ var I18n = (function () {
label_amount: 'Amount',
label_desc: 'Description (optional)',
placeholder_desc: 'e.g. Invoice #42, freelance work...',
label_timer: 'Payment deadline in minutes (optional)',
placeholder_timer: 'e.g. 30',
label_timer: 'Payment deadline (optional)',
days: 'days',
placeholder_timer_custom: 'Days',
btn_generate: 'Create payment request',
btn_open_wallet: 'Open in wallet',
btn_copy_addr: 'Copy address',
@@ -46,8 +65,25 @@ var I18n = (function () {
btn_new_request: 'New payment request',
toast_copied: 'Copied!',
countdown_expired: 'Payment deadline expired',
countdown_remaining: 'Payment deadline: ',
rates_offline: 'Rates unavailable — XMR amount only'
countdown_remaining_days: 'Deadline: {d} days, {h}:{m}:{s}',
countdown_remaining_hours: 'Deadline: {h}:{m}:{s}',
rates_offline: 'Rates unavailable — XMR amount only',
btn_monitor: 'Monitor payment',
label_view_key: 'Private view key',
placeholder_view_key: '64 hex characters...',
hint_view_key: 'Your view key never leaves your browser',
btn_start_monitor: 'Start monitoring',
btn_stop_monitor: 'Stop monitoring',
monitor_connecting: 'Connecting to node...',
monitor_scanning: 'Scanning mempool...',
monitor_waiting: 'Waiting for payment...',
monitor_mempool: 'Payment detected (unconfirmed)',
monitor_confirmed: 'Payment confirmed',
monitor_confirmations: '{n}/10 confirmations',
monitor_underpaid: 'Underpayment detected',
monitor_underpaid_detail: 'Expected: {expected} XMR — Received: {received} XMR',
monitor_node_error: 'Node unreachable — trying next...',
monitor_loading: 'Loading crypto module...'
}
};