From 0b5de877980b64354fa80919f117a5d9de5095d5 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 6 Nov 2026 07:41:21 +0100 Subject: [PATCH] AI: the invoice flow must not require wallet-core's deprecated talerUri Pressing "Request " showed a bare "Unknown error" and created no invoice. The app log named the cause: initiatePeerPullCredit failed after 436 ms DecodingError.keyNotFound: Key 'talerUri' not found in keyed decoding container. InitiatePeerPullCreditResponse declared `talerUri` as a non-optional String. wallet-core declares it optional and deprecated, and only fills it in when the purse record has already reached PendingReady by the time the call returns (pay-peer-pull-credit.ts); otherwise the key is absent, which is the common case because the purse is usually still being created. So a decoder that insists on the key turns an ordinary race into a failed flow, and because a DecodingError carries no localizedDescription of its own the user is told nothing beyond "Unknown error". Nothing needs the field: the only caller uses response.transactionId, and the URI the QR code renders comes from the transaction (TransactionSummaryList.QRCodeDetails reads detailsToShow()[TALERURI]), which wallet-core always populates. The sibling push struct already has the field commented out. Checked the other five response structs in this file against types-taler-wallet.ts: this is the only optionality mismatch. Assisted by LLM --- TalerWallet1/Model/Model+P2P.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/TalerWallet1/Model/Model+P2P.swift b/TalerWallet1/Model/Model+P2P.swift index 7cf461fd..b8d6dea9 100644 --- a/TalerWallet1/Model/Model+P2P.swift +++ b/TalerWallet1/Model/Model+P2P.swift @@ -154,7 +154,15 @@ extension WalletModel { // - - - - - - /// Initiate an outgoing peer pull payment, send a request(invoice) struct InitiatePeerPullCreditResponse: Codable { - let talerUri: String + /// Optional, and wallet-core marks it deprecated: `initiatePeerPullCredit` + /// only fills it in when the purse record has already reached + /// `PendingReady` by the time the call returns, so the key is simply absent + /// whenever the purse is still being created -- which is the common case. + /// Decoding it as non-optional turned that race into a user-visible + /// "Unknown error" and aborted the whole invoice flow. The URI the QR code + /// shows comes from the transaction (`detailsToShow()[TALERURI]`), which + /// always carries it, so nothing here needs this field. + let talerUri: String? let transactionId: String } fileprivate struct InitiatePeerPullCredit: WalletBackendFormattedRequest { -- 2.47.3