0xMiden / 0xMiden/wallet

Feature: user-configurable spending limits (daily/weekly) with biometric/password confirmation

Đang mở
#646 0 bình luận 0 reaction 1 người được giao Được @WiktorStarczewski nhận Xem trên GitHub
enhancement
Ngôn ngữ chính
TypeScript
Star
5
Fork
28
Merge trung bình
9 giờ 50 phút
Pull request đã merge (30 ngày)
123

Mô tả

## Summary

Let users set **spending limits** — a daily and/or weekly cap on outgoing value — directly in the wallet, as a self-custody guardrail. When a transaction would push cumulative spend over the configured limit within the window, require an extra **biometric / password confirmation** to proceed (or block until the window resets). Changing or disabling a limit requires the same confirmation, so a briefly-unlocked session can't simply raise it.

## Motivation

- Guards against the two most common ways self-custody users lose funds: fat-finger mistakes, and a casual attacker who gets a briefly-unlocked session.
- Feature-parity expectation — most consumer wallets offer per-period limits.
- Complements the Guardian co-signer: a lightweight, always-on guardrail the user controls themselves, no second party required.

## Proposed behaviour

**Configuration** — a new **Settings → "Spending limits"** sub-screen:
- Enable/disable, and set a **daily** and/or **weekly** cap.
- Denomination: **per-asset native amount** as the robust default (see Open questions re: fiat).
- Enabling, raising, or disabling a limit requires a **step-up confirmation** (biometric on mobile, password on extension/desktop). Lowering a limit can be allowed without step-up (strictly safer) — TBD.

**Enforcement** — at send/swap/bridge/earn-deposit time:
- Before submitting an outgoing transaction, compute cumulative spend in the window; if this tx would exceed the limit, require the step-up confirmation to proceed. If the user can't/won't confirm, block with a clear message ("Daily limit reached — resets in Xh, or raise it in Settings").

## Security — please read

**This is a client-side UX guardrail, not a cryptographic limit.** The account's OpenZeppelin multisig / Guardian enforces **signature-count** thresholds per procedure (`openzeppelin::multisig::procedure_thresholds`) and has **no notion of transferred value** — there is no on-chain amount/limit policy today (`src/lib/miden/guardian/account.ts`, enforced during proof per `src/lib/miden/transaction/index.ts:1127`). Consequences that shape the design:

- The limit protects against mistakes and a casual attacker with a briefly-unlocked session. It does **not** stop a determined attacker who has the unlocked wallet + on-device keys (they can bypass the UI and drive the SDK directly).
- The check must therefore live at the **transaction-initiation chokepoint**, not just in the UI, and the step-up must gate **both** exceeding the limit **and** changing/disabling it — otherwise it's trivially bypassed.
- A **true, enforced** limit would need new account-component logic (a value-aware procedure/guardian policy) that doesn't exist in the current integration — see Out of scope.

## Suggested implementation (integration points)

- **Step-up confirmation:** reuse `confirmSensitiveAction(reason)` — `src/lib/biometric/index.ts:183`. It already gates send (`src/screens/send-flow/ReviewTransaction.tsx:209`) and swap (`src/screens/swap-flow/SwapManager.tsx:207`), and its own doc invites callers to "layer their own policy on top." Password-reconfirm pattern for the extension/desktop fallback: `src/app/templates/RevealSecret.tsx`.
- **Chokepoint (covers ALL spend flows):** add the limit check in the `initiate*Transaction` layer — `initiateSendTransaction` / `initiateSwapTransaction` / `initiateBridgedSendTransaction` / `initiateEarnDepositTransaction` in `src/lib/miden/transaction/initiate.ts` (each has a clean `amount: bigint` + `faucetId`). A **UI-only** step-up would miss dApp programmatic send (`src/lib/miden/back/dapp.ts:1260,1301`), earn (`src/lib/epoch/earn-note.ts`), and bridge (`src/lib/epoch/miden-note.ts`, `src/lib/agglayer/b2agg/index.ts`), none of which call `confirmSensitiveAction` today — centralizing at `initiate*` covers them (and correctly excludes incoming/auto-consume).
- **Spend aggregation:** sum `amount` over the `transactions` Dexie table where `type ∈ {send, swap, bridged-send, earn-deposit}` and `completedAt`/`initiatedAt` is within the window, grouped by `faucetId` (`src/lib/miden/repo.ts`; `ITransaction` in `src/lib/miden/db/types.ts`). Amounts are per-faucet native base units.
- **Fiat option:** a Binance price feed exists (`src/lib/prices/binance.ts`, surfaced as `token.fiatPrice`) for mapped tokens (MIDEN etc.), but unmapped/DEX tokens default to `$1` — a USD limit is only reliable for mapped tokens, so per-asset native limits are the safer primary design.
- **Settings storage:** `setSetting/getSetting` + `mirrorSetting` (so the extension service worker can read it) in `src/lib/settings/helpers.ts`; keys/defaults in `src/lib/settings/constants.ts`. `SettingToggle` is boolean-only, so this wants a small new sub-screen with numeric inputs rather than a toggle row.

## Open questions (need a decision)

1. **Denomination:** per-asset native amount (robust, all tokens) vs USD-equivalent (intuitive, only reliable for price-mapped tokens). Recommend native first; USD later.
2. **Window:** rolling 24h/7d vs calendar day/week (rolling is simpler and harder to game).
3. **On limit reached:** hard block until reset vs allow with mandatory step-up — i.e. speed-bump or wall? (The ask implies step-up-to-exceed.)
4. **Which flows count:** send, swap, bridged-send, earn-deposit — include earn-deposit (moving funds into a vault)? include dApp programmatic sends (recommend yes)?
5. **Cross-device / reinstall:** spend history + limit config are local; after a reinstall the running total resets. Acceptable, or reconstruct from on-chain history?
6. **Biometrics unavailable/disabled:** `confirmSensitiveAction` short-circuits to `true` when biometrics are off — for a spend limit we probably want to fall back to **password** rather than silently allow. Confirm.

## Acceptance criteria

- [ ] Settings surface to enable and set daily and/or weekly limits (per-asset native amount).
- [ ] Enabling/raising/disabling a limit requires biometric or password confirmation.
- [ ] Outgoing transactions exceeding the active limit require a step-up confirmation (or are blocked), enforced at the `initiate*` chokepoint so dApp/earn/bridge are covered.
- [ ] Clear messaging when a limit is hit (amount over, time to reset, how to raise).
- [ ] Cumulative spend computed correctly over the window per asset; incoming/consume excluded.
- [ ] Documented explicitly that this is a client-side guardrail, not a cryptographic limit.
- [ ] Tests: limit math (window boundaries, per-asset), step-up-required paths, settings persistence.

## Out of scope / follow-ups

- True on-chain enforcement via a value-aware account/Guardian policy (much larger; needs account-component work).
- USD-denominated limits across all tokens (needs broader price coverage).
- Per-recipient allowlists.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.