From 3a8d87e9c90ccada6f4b5a84857d9352236571a6 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Mon, 18 May 2026 12:07:01 -0400 Subject: [PATCH] fix(ui): wowcheckout login-form was checking XMR address shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isLikelyPrimaryAddress() required exactly 95 chars starting with "4" — that's the Monero primary-address shape. Wownero primaries are 97 chars starting with "Wo". This was inherited from the xmrcheckout fork and never updated. Effect: pasting a valid Wownero address into the login form silently failed isLikelyPrimaryAddress(), the validate API was never called, no green VALID indicator rendered, canSubmit stayed false, the Sign in button stayed greyed out. Suchshop sidestepped this because that tenant was provisioned via direct SQL/API, not through this form. Fix: 95 → 97, "4" → "Wo". One file, two lines. The backend cryptographic validation in routes.py: _validate_payment_address_and_view_key() was correct all along — it checks the 2-byte Wownero varint prefix (byte 0 == 178). The UI just wasn't asking it. --- ui/app/(app)/login/login-form.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ui/app/(app)/login/login-form.tsx b/ui/app/(app)/login/login-form.tsx index 02bb438..766251f 100644 --- a/ui/app/(app)/login/login-form.tsx +++ b/ui/app/(app)/login/login-form.tsx @@ -13,12 +13,19 @@ const base58Pattern = /^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvw const viewKeyPattern = /^[0-9a-fA-F]{64}$/; const validationDelayMs = 450; +// Wownero primary addresses are 97 base58 chars starting with "Wo". +// This guard was inherited from the xmrcheckout fork — XMR addresses +// are 95 chars starting with "4". The xmrcheckout-shape check +// silently rejected every Wownero address, leaving the Sign in +// button greyed out and the validate API never called. Suchshop +// avoided this because that tenant was provisioned via direct SQL, +// not via this form. const isLikelyPrimaryAddress = (value: string) => { const trimmed = value.trim(); - if (trimmed.length !== 95) { + if (trimmed.length !== 97) { return false; } - if (!trimmed.startsWith("4")) { + if (!trimmed.startsWith("Wo")) { return false; } return base58Pattern.test(trimmed);