View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0011984 | Taler | wallet (iOS App) | public | 2026-11-09 21:07 | 2026-11-09 21:07 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0011984: Deposit offers an amount the destination cannot receive: getMaxDepositAmount is sent without depositPaytoUri, so the maximum ignores the exchange's wire methods | ||||
| Description | The deposit amount screen tells the user how much they can deposit without ever asking where to. The number it shows is the most the wallet could deposit *somewhere*, and it is presented as the most they can deposit to the account they just picked -- which for an account the exchange cannot settle to is zero. **The missing argument.** `GetMaxDepositAmount.Args` (TalerWallet1/Model/Model+Deposit.swift) sends two fields, and the one that would answer the question is commented out in the source: struct Args: Encodable { var currency: String var restrictScope: ScopeInfo // var depositPaytoUri: String } wallet-core uses `req.depositPaytoUri` to derive `restrictWireMethod` and to filter the eligible exchanges (`getMaxDepositAmount` -> `getDepositExchangeEligibilityInTx`, taler-wallet-core/src/coinSelection.ts). Without it, nothing in the request names the destination, so nothing in the answer accounts for it. **What the user sees.** Measured 2026-11-09, iOS 27.2 simulator, with a KUDOS 25 wallet funded from the demo exchange and an IBAN account added through Settings -> Bank Accounts: staticText "Available: KUDOS 25.00" button "Deposit KUDOS 5.00" enabled button "Shortcut KUDOS 5.00" enabled button "Shortcut KUDOS 10.00" enabled button "Shortcut KUDOS 25.00" enabled Every one of those is impossible. Pressing Deposit produces: createDepositGroup{"amount":"KUDOS:5", "depositPaytoUri":"payto://iban/CH9300762011623852957…"} -> code 7026 WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE causeHint: "merchant-deposit-insufficient" balance: { material: "KUDOS:25", pendingRefresh: "KUDOS:0", available: "KUDOS:25" } maximumPayableAmount: "KUDOS:0" reasons: [ { "type": "wire-method-unsupported", "wireMethod": "iban" } ] The wallet holds 25 by both measures. The exchange settles over x-taler-bank, the account is an IBAN, and the payable maximum is zero -- which `getMaxDepositAmount` would have said if it had been told where the money was going. **Two defects, one cause.** The offer is wrong, and the refusal is unreadable: the error reaches the user as "Internal core error" over a "Copy the error JSON" button (noted on 11934), and the one hint wallet-core does supply for this code -- `merchantDepositInsufficient`, "Balance insufficient!" -- would be wrong in its own way here, since the balance is not the problem. **Not the same as 11964**, which was the decode of this call's reply and is fixed; this is what the call asks in the first place. The decode fix is what made this visible: before it, `getMaxDepositAmount` threw and the flow died at the amount screen, so nobody had ever pressed Deposit. | ||||
| Steps To Reproduce | 1. Fund a wallet with demo cash (KUDOS 25) from the empty-wallet screen. 2. Settings -> Bank Accounts -> + -> IBAN, with a label, an account holder and any valid IBAN (e.g. CH9300762011623852957). 3. Actions -> Deposit -> that account. Observed: the heading reads "Available: KUDOS 25.00" and the KUDOS 5, 10 and 25 shortcuts are all enabled. Entering any amount and pressing "Deposit <amount>" fails with "Internal core error"; the os_log carries the 7026 above with `wire-method-unsupported`. Expected: the maximum reflects the selected account -- KUDOS 0.00 for this pair, with the shortcuts disabled and a sentence saying that this account cannot receive KUDOS from this payment service. wallet-core supplies both the number and the reason once it is told the destination. The same wallet CAN deposit to an x-taler-bank account at that exchange, which is what makes this a wrong offer rather than a missing feature. | ||||
| Additional Information | Fix: pass the payto URI the screen already holds. `DepositAmountAction` has `paytoUri` (it is what the account row selected and what `createDepositGroup` is given), so the request becomes GetMaxDepositAmount(scope: scope, depositPaytoUri: paytoUri) with the field uncommented in `Args`. The reply's `exchangeDiagnostics[<exchange>].reasons` then carries the eligibility failures in deterministic order, which is the material for the sentence the screen is missing. Worth checking at the same time: the Send/Request screens take their maximum from `getMaxPeerPushDebitAmount`, which has no destination to restrict by, so they are not affected. The *withdrawal* screen's maximum comes from the bank's own limits and is likewise unrelated. Found by the deterministic `deposit` scenario in the fuzzing harness. It is also why that scenario cannot be green as written, and the harness's own bank-add prelude will be changed to add an x-taler-bank account for the demo exchange instead of an IBAN one -- a change to the test, not evidence about the app. | ||||
| Tags | No tags attached. | ||||
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-09 21:07 | bot-cg | New Issue |