070-alias-directory-mailbox.rst (14785B)
1 DD 70: Alias Lookup and Mailbox 2 ############################### 3 4 :Design status: Accepted 5 :Implementation status: Partial 6 :DD shepherd: TBD 7 :Historical contributors: Martin Schanzenbach 8 :First published: 2025-09-19 9 :Last substantive change: 2025-11-10 10 :Implementation evidence: ``taler-typescript-core`` (2025-11-07; 2026-07-14; 2026-07-16; 2026-08-20) 11 :Normative references: ``core/api-mailbox.rst`` and ``core/mailbox/get-H_MAILBOX.rst`` 12 13 Summary 14 ======= 15 16 GNU Taler is a payment system that makes privacy-contactly online transactions 17 fast and easy. 18 This project will facilitate the support of peer-to-peer payments (P2P) for the 19 GNU Taler payment system between users by implementing a privacy-contactly 20 directory service and lightweight inbox service (TALer DIRectory). 21 The services will allow users to securely associate their 22 online identities (such as email addresses, phone numbers, X/Twitter/Mastodon handles or other suitable verifiable addresses and accounts) with their wallet 23 public keys and the URL of an inbox service and use it for P2P payments. 24 Storage and retrieval may also be offloaded to distributed directory services 25 such as DNS or GNS (RFC 9498) instead of a database 26 and web service while maintaining the respective privacy guarantees. 27 28 Motivation 29 ========== 30 31 The Digital Euro is currently in development and as a part of it the 32 so-called "Alias Lookup Service" is being developed for at least 33 28 Millon Euros (Tender "PRO-009485"). 34 35 To enable peer-to-peer payments for the GNU Taler payment system 36 between users such a directory service and lightweight inbox service are also required. 37 We believe that the estimated development costs from the ECB tender 38 are unreasonably and unexplicably high. We can demostrate how an efficient, 39 privacy-contactly and lean service that offers this kind of functionality can be 40 developed within this proposal at a fraction of the cost of the 41 "Alias Lookup Service": 42 43 The directory service will allow users to securely associate their 44 online identities (such as email addresses, phone numbers, X/Twitter/Mastodon handles or other suitable verifiable addresses and accounts) with their wallet 45 public keys and the URL of an inbox service. 46 Additionally we found that storage and retrieval may also be offloaded to distributed directory services such as DNS or GNS (RFC 9498) instead of a database 47 and web service while maintaining the respective privacy guarantees. 48 We have added such a task to the estimate. 49 50 In order to facilitate fund transfers in the P2P context, we 51 will extend the Taler wallet (in particular, the browser-based 52 WebExtension) to allow users to associate the wallet with one or more 53 (wallet) addresses, to query the directory to send money or invoices, to 54 encrypt the payment messages to the public key obtained from the 55 directory, to transmit the message via the lightweight inbox service, 56 and to poll the inbox service for incoming requests and show them to 57 the user. 58 Both the key directory service and the inbox service may provide their 59 services for a fee to compensate the operator for operational costs 60 including the validation of addresses. 61 62 Requirements 63 ============ 64 65 The implementation must take great care to ensure the privacy and 66 integrity of the mappings from the identity to the wallet keys. 67 For this, plain text identity information such as email addresses should 68 only be processed as part of the validation and registration processes. 69 The actual mappings will be indexed using salted hashes. 70 71 Queries for wallet keys also should require the caller to provide the 72 already hashed identity to minimize data leakage from requests. 73 74 This minimizes the handling of personally identifyable information (PII) 75 at the service and limits exposure in case of data leaks at the operator. 76 77 The service must be suitable to be operated at very high availability constraints. 78 As such, the service must be scalable and ideally have a small footprint and 79 computing base. 80 81 User Stories 82 ============ 83 84 Both the Mailbox server URI and the Taldir server URI have hard-coded defaults that can be overriden in expert settings. 85 In the user stories, we use the placeholders ``$MAILBOX_SERVER`` and 86 ``$TALDIR_SERVER`` for those URIs. 87 88 Alias Registration 89 ------------------ 90 91 Prerequisites: Alice has installed Taler Wallet 92 93 Alice opens the Taler Wallet and browses to ``Settings -> Aliases``. 94 The interface offers registration of any Alias type supported by the Taldir instance through 95 a ``+`` button and suitable follow-up screens. 96 97 **Technical Note**: Alice registers an Alias with the Mailbox URI that corresponds to her Wallet ID (See also :ref:`Mailbox API <api-mailbox>`). The interface does not require Alice to input the URI manually, the Wallet can synthesize the Mailbox URI from an address: ``$MAILBOX_SERVER/SHA512(WalletPublicKey)``. 98 99 100 **Technical Note**: Supported alias types are found in the ``$TALDIR_SERVER/config`` endpoint. 101 102 103 Alice chooses an alias type and is then prompted to provide her type-specific alias, e.g. *alice@example.com* would be an alias of type *email*. 104 This initiates the Alias validation procedure. 105 106 **Technical Note**: This initiates the alias registration flow provided in :ref:`Taldir API <api-taldir>`. 107 108 The registration procedure may succeed or fail. 109 Alice may retry on failure to register the same Alias. 110 Alice may also register other Aliases. 111 112 .. _dd-70-us-alias-mgmt: 113 114 Alias Management 115 ---------------- 116 117 Prerequisites: Alice has registered one or more aliases 118 119 Alice opens ``Settings -> Aliases`` to manage her aliases. 120 The UI shows all registered aliases with expiration times. 121 The UI allows Alice to delete registrations (or disable auto-renewal) and renew a registration pre-emptively before it expires. 122 Alice may use this screen to display a QR code (an ``add-contact`` Taler URI) of her own contact, see also :ref:`Contacts Management <dd-70-us-contacts-mgmt>`. 123 124 This may require separation into two or three stories. 125 126 Send Payment Request 127 -------------------- 128 129 Prerequisites: Bob has installed Taler Wallet, Bob knows one of Alice's aliases 130 131 Bob wants to request money from Alice. 132 He opens his Taler wallet and opens ``Taler Button->Receive`` screen from the menu. 133 A screen that allows to create a payment request is shown to Bob. 134 Once Bob has entered all necessary details, a payment request (:ref:`DD 13 <dd-13>`) is 135 created and the screen with QR code is shown. 136 This screen now also allows to send the request to a contact by using the contact list. 137 The *Request from Contact* screen brings up the contacts list to select a contact. 138 (Optional): Bob may also import a contact here ad-hoc, see :ref:`Contacts Management <dd-70-us-contacts-mgmt>`. 139 Bob selects the contact and the request is sent to Alice. 140 141 **Technical Note**: This will trigger the wallet to send the payment request to Alice's Mailbox URI through the :ref:`Mailbox API <api-mailbox>`. 142 143 The request may fail, for example if Alice's Mailbox is full. 144 145 **Note**: Sending messages via Mailbox API may incur fees. 146 147 148 Receive Payment Request 149 ----------------------- 150 151 Prerequisites: Alice has installed Taler Wallet, Alice has registered an Alias, Bob has sent a payment request. 152 153 **Technical Note**: The Wallet periodically checks Mailboxes using the :ref:`Mailbox API <api-mailbox>` for new payment requests and downloads the messages locally. Remote messages are deleted after download. 154 155 156 The new payment request by Bob is received by the Wallet and it notifies Alice. 157 158 **Technical Note**: Notice request is *NEW*. This requires requests to have unique IDs. Also, maybe notifications should happen even if the ID is already seen, but the message is new. 159 160 Alice interacts with the notification or manually browses to ``Settings->Mailbox``. 161 162 There, the wallet provides a screen with payment request overviews (e.g. list of messages 163 in the local mailbox). 164 Alice selects Bob's payment request either through the notification or from the list 165 of payment requests. 166 The messages contain Taler URIs, so the application may simply offer to process the respective 167 URI as is usually done. 168 169 **Note**: When are local messages deleted? 170 171 .. _dd-70-us-contacts-mgmt: 172 173 Contacts Management 174 ------------------- 175 176 Prerequisites: Alice has installed Taler Wallet 177 178 Alice opens ``Settings->Contacts``. 179 The list of contacts is empty in the beggining. 180 There is a button to *Add a contact* which opens a UI. 181 The UI consists of a search input and an Alias type selector. 182 Alice selects the Alias type (e.g. GitHub or Email) and inputs a contacts Alias. 183 184 **Technical Note**: This will initiate a lookup request using the :ref:`Taldir API <api-taldir>`. 185 186 If no results were found, Alice cannot import this contact. 187 If found, Alice will be able to import this contact into the contact list. 188 189 Alternatively, the contact can also be imported using an ``add-contact`` Taler 190 URI, see :ref:`Alias Management <dd-70-us-alias-mgmt>`. 191 192 **Technical Note**: The wallet periodically performs lookups for contacts where their Taldir registrations have expired and refresh accordingly. 193 194 Send Money 195 ---------- 196 197 Prerequisites: Alice has installed Taler Wallet, Alice has registered an Alias. 198 199 Bob wants to directly send money to Alice (e.g. PayPal style). 200 He opens his Taler wallet and opens ``Taler Button->Send``. 201 A screen that allows to create a payment offer is shown to Bob. 202 Once Bob has entered all necessary details, the payment offer is created and the screen with the QR code is shown. 203 There, he selects the *Send to Contact*. 204 The *Send to Contact* screen consists of a search input and an Alias type selector. 205 This screen now also allows to send the request to a contact by using the contact list. 206 Bob selects *Send to Contact*. 207 The *Send to Contact* screen brings up the contacts list to select a contact. 208 209 **Note**: At this point, Bob may now also import a contact here ad-hoc, see :ref:`Contacts Management <dd-70-us-contacts-mgmt>`. 210 211 Bob selects the contact and the payment offer is sent to Alice. 212 213 **Technical Note**: The offer is sent to Alice's Mailbox URI through the :ref:`Mailbox API <api-mailbox>`. 214 215 This request may fail, for example if Alice's Mailbox is full. 216 217 **Note**: Sending messages via Mailbox API may incur fees. So does creating a purse in the offer. This should probably be done in a single user action. 218 219 Resend Payment Request 220 ---------------------- 221 222 Prerequisites: Bos has already sent a payment request to Alice 223 224 Bob may want to resend a payment request if it expired or if Alice lost the request. 225 226 **Technical Note**: This does not mean that the request can get lost in transit. It means that it is possible that Alice lost her phone and needed to setup her Wallet again. 227 228 Bob opens the open payment request and selects the contact to send it to again. 229 230 **Technical Note**: This likely implies the creation of a new payment request, with the same detail of the already sent request. Sending the same request again is probably not a good idea. This, however, requires a new field to the contract terms (``idempotency_nonce``?) that we keep identical between both requests. That way, the receiving wallet can detect that it is a duplicate and act accordingly --- if already paid, ignore, if hard-rejected/banned ignore, and if merely expired show again. 231 232 233 Open Questions 234 ============== 235 236 237 Proposed Solution 238 ================= 239 240 The directory and mailbox services will be implemented as two distinct services. 241 Both with have an open REST API which will be specified as part of the protocol. 242 243 Directory 244 --------- 245 246 The directory will support an extensible interface for alias *validators*. 247 Validators will ensure that users that want to register mailbox URIs under an alias 248 are actually the owner/in control over the particular alias. 249 For example, in order to use an email address as the alias a verification link will be 250 sent to that address and the user needs to confirm registration. 251 252 In addition to the REST API, the directory will support an extensible interface for 253 alias *disseminators*. 254 Disseminators will publish the alias-mailbox mapping. 255 For example, DNS or GNS validators will publish the mappings under zones of the operator. 256 257 Mailbox 258 ------- 259 260 .. note:: 261 262 The normative mailbox API now specifies exactly 256-byte messages beginning 263 with the sender's ephemeral public key; see 264 :ref:`api-mailbox`. The type-prefixed framing below records an earlier 265 proposal and is not the current wire format. 266 267 Messages are retuned from the API with a fixed length. 268 The configured messages length must be obtained through the 269 mailbox service configuration endpoint. 270 The first two bytes of the message are 16 bit unsigned integers 271 in network byte order that specify the message type. 272 The remaining bytes contain the encrypted message (including the MAC). 273 Messages are encrypted using HPKE (X25519 with ChaChaPoly1305 as AEAD). 274 The proposed outer framing has a single message type carrying a Taler URI; 275 after decryption, the payload is one of the two URI variants defined below. 276 This type is identified by the bytes ``0x00 0x00``. 277 This message type number is in network byte order prefixed before the HPKE ciphertext. 278 The HPKE ciphertext starts with a 32 byte 279 encapsulation followed by the encrypted URI. 280 The encrypted URI is followed by a 16 byte MAC. 281 The message type is part of the MAC (the additional data portion of the AEAD scheme). 282 283 Wire format MailboxMessage: 284 285 .. _MailboxMessage: 286 .. ts:def:: MailboxMessage 287 288 type MailboxMessage = (PaymentInvoiceMessage | MoneyTransferMessage) & MailboxMessageCommon 289 290 291 .. _PaymentInvoiceMessage: 292 .. ts:def:: PaymentInvoiceMessage 293 294 interface PaymentInvoiceMessage { 295 // Message type 296 type: "payment-invoice"; 297 298 // Pay pull URI. 299 payPullUri: string; 300 301 302 } 303 304 .. _MoneyTransferMessage: 305 .. ts:def:: MoneyTransferMessage 306 307 interface MoneyTransferMessage { 308 // Message type 309 type: "money-transfer"; 310 311 // Pay push URI. 312 payPushUri: string; 313 314 315 } 316 317 .. ts:def:: MailboxMessageCommon 318 319 interface MailboxMessageCommon { 320 // Message type 321 messageType: string; 322 323 // Message identifier 324 messageId: string; 325 326 // Freeform text from sender. 327 senderHint: string; 328 329 } 330 331 Definition of Done 332 ================== 333 334 (Only applicable to design documents that describe a new feature. While the 335 DoD is not satisfied yet, a user-facing feature **must** be behind a feature 336 flag or dev-mode flag.) 337 338 - :ref:`Taldir API <api-taldir>` implemented and deployed with at least SMS and Email validators. (DONE) 339 - :ref:`Mailbox API <api-mailbox>` implemented and deployed. 340 - Wallet functionality to support user stories implemented. 341 342 Alternatives 343 ============ 344 345 Drawbacks 346 ========= 347 348 Discussion / Q&A 349 ================ 350 351 (This should be filled in with results from discussions on mailing lists / personal communication.)