069-exchange-base-url-completion.rst (4975B)
1 DD 69: Exchange Base URL Completion 2 ################################### 3 4 :Design status: Accepted 5 :Implementation status: Implemented 6 :DD shepherd: TBD 7 :Historical contributors: Vlada Svirsh 8 :First published: 2025-09-16 9 :Last substantive change: 2025-11-22 10 :Implementation evidence: ``taler-typescript-core`` (2025-09-15; 2026-07-31) 11 :Normative references: ``wallet/wallet-core.md`` (exchange-base-URL completion operation) 12 :Upstream follow-up: Regenerate/fix ``wallet/wallet-core.md``: its operation comment incorrectly describes coin refresh, and the generated request/result omit ``progressToken``/``suggestions`` that are present in the implementation. Do not treat the generated text as the authoritative completion algorithm until corrected. 13 14 Summary 15 ======= 16 17 Define the request, which turns user-provided input (like ``exchange.example.com`` or just ``example.com``) into a canonical, 18 validated **HTTPS** exchange base URL. Validation requires that ``GET <base>/config`` returns a valid 19 `ExchangeVersionResponse <https://docs.taler.net/core/api-exchange.html#get--config>`__ object. 20 21 Motivation 22 ========== 23 24 Users may provide incomplete or ambiguous input when configuring an exchange. For example, they may type just 25 ``example.com`` instead of the full ``https://exchange.example.com/``. 26 The system must normalize, complete, and validate such inputs to ensure that only valid exchanges are accepted. 27 This improves robustness and user experience while preventing misconfiguration. 28 29 Requirements 30 ============ 31 32 * Accepts a single string from the user (host or URL). 33 * Supports inputs like ``exchange.example.com``, ``example.com``, 34 or ``https://exchange.example.com/``. 35 * Always enforces HTTPS. 36 * Base URL must end with a single ``/`` and omit ports. 37 * Must validate by requesting ``GET <base>/config`` and checking for a valid 38 `ExchangeVersionResponse <https://docs.taler.net/core/api-exchange.html#get--config>`__ object. 39 * Must support a local list of trusted exchanges for resolution of ambiguous 40 inputs or typos (70% Levenshtein similarity). 41 42 Proposed Solution 43 ================= 44 45 Process: 46 47 1. **Clean up locally** 48 49 * Trim spaces and lowercase scheme/host. 50 * Default scheme to ``https://`` if missing. 51 * Reject non-HTTPS schemes. 52 * Remove explicit port and strip query/fragment. 53 * Ensure a trailing slash. 54 55 2. **Candidate base URLs** 56 57 * If input host starts with ``exchange.``, use directly. 58 * If input is a bare domain, construct 59 ``https://exchange.<domain>/`` as a second candidate. 60 61 3. **Network check (keys)** 62 63 * For each candidate, perform ``GET <base>/config``. 64 * Follow HTTPS redirects within limits. 65 * Accept if the final response is a valid 66 `ExchangeVersionResponse <https://docs.taler.net/core/api-exchange.html#get--config>`__. 67 * Otherwise, treat as protocol failure. 68 69 4. **List of trusted exchanges** 70 71 * Check the input against a local list of trusted exchanges. 72 * Match by exact part match of hostname and fuzzy match (≥70% Levenshtein). 73 * Return ``bad-exchange`` and, if trusted entries are found, return them in 74 the ``suggestions`` array. 75 76 Outcome values 77 -------------- 78 79 * **ok** — Keys validated; return canonical base. 80 * **bad-syntax** — Input invalid (e.g., non-HTTPS scheme). 81 * **bad-network** — Network failure (DNS/connect/TLS/timeout). 82 * **bad-exchange** — Response received but not a valid exchange. 83 84 Canonicalization of output 85 -------------------------- 86 87 * Always return in the form ``https://<lowercased-host>/``. 88 * No ports, queries, or fragments. 89 90 Examples 91 -------- 92 93 * ``exchange.example.com`` -> **ok**, returns ``https://exchange.example.com/``. 94 * ``example.com`` -> try ``https://example.com/config`` first. 95 If not valid, then try ``https://exchange.example.com/config``. 96 If that works → **ok**, returns ``https://exchange.example.com/``. 97 * ``https://exchange.example.com/`` with ``/config`` returning something other 98 than a valid `ExchangeVersionResponse <https://docs.taler.net/core/api-exchange.html#get--config>`__ object -> **bad-exchange**. 99 * ``http://exchange.example.com`` -> **bad-syntax** (HTTPS required). 100 * ``example.com`` where ``/config`` redirects to 101 ``https://api.example.com/config`` and returns valid data -> **ok**, returns 102 ``https://api.example.com/``. 103 * DNS failure -> **bad-network**. 104 105 106 Definition of Done 107 ================== 108 109 * [x] Request implemented and documented. 110 * Unit tests cover: 111 - valid inputs, 112 - redirects, 113 - trusted exchange fallback, 114 - failure cases (syntax, network, protocol). 115 * [x] Feature is enabled by default. 116 117 Alternatives 118 ============ 119 120 Drawbacks 121 ========= 122 123 * Requires maintaining a local list of trusted exchanges and fuzzy matching. 124 * Adds network overhead (``GET /config`` probes). 125 * Possible user confusion if multiple trusted exchanges are suggested 126 as fuzzy matches. 127 128 Discussion / Q&A 129 ================ 130 131 (To be filled in with results from discussions on mailing lists / personal communication.)