The landed TaintConfig is a three-variant sum (PerSession / DataDir { dir, rpc_url, chain_id } / Custom(...)) at core/src/provider/persistence.rs:44-63. The design (issue #15) specified a struct-shaped config with four orthogonal axes:
persist: TaintPersistence — where it goes (in-memory / DataDir / custom).
scope: TaintScope — what taint is keyed by (per-RPC-URL / per-provider / global).
acknowledgement: AcknowledgementPolicy — does acknowledge_mismatch survive a restart, and for how long.
dismissable_after: Option<Duration> — escape-hatch time-based auto-clear.
Today only the persist axis is expressible.
Scope
Out of scope
- Encrypted/sealed taint storage. The current store is plaintext JSON; if that becomes a concern, a separate issue covers
Custom(Arc<dyn TaintStore>) consumers wrapping an encrypted store.
Done when
TaintConfig is a struct with persist/scope/acknowledgement/dismissable_after fields.
- Existing
builder_data_dir_preserves_taint_across_restart test still passes (semantically identical with acknowledgement = PerSession).
- New tests cover
PerProvider scope (cross-RPC taint), Persisted ack (survives restart), and dismissable_after (time-based auto-clear).
The landed
TaintConfigis a three-variant sum (PerSession/DataDir { dir, rpc_url, chain_id }/Custom(...)) atcore/src/provider/persistence.rs:44-63. The design (issue #15) specified a struct-shaped config with four orthogonal axes:persist: TaintPersistence— where it goes (in-memory / DataDir / custom).scope: TaintScope— what taint is keyed by (per-RPC-URL / per-provider / global).acknowledgement: AcknowledgementPolicy— doesacknowledge_mismatchsurvive a restart, and for how long.dismissable_after: Option<Duration>— escape-hatch time-based auto-clear.Today only the
persistaxis is expressible.Scope
TaintConfiginto a struct with the four named axes. Keep the existingPerSession/DataDir/Customsemantics asTaintPersistenceenum values.TaintScope::PerRpcUrl(current default, keyed by(chain_id, rpc_url)) andTaintScope::PerProvider(cross-RPC, keyed by chain only — for embedders who treat any tainted-mismatch on any RPC as a taint against the wallet itself).AcknowledgementPolicy::PerSession(current behaviour — ack clears in-memory, doesn't persist).AcknowledgementPolicy::Persisted { ttl: Option<Duration> }— ack persists across restart, optionally expiring afterttl. Storage piggybacks on the existingTaintStoreinterface (add a pairedacknowledged_atfield or a sibling record).dismissable_after: Option<Duration>— supervisor auto-clears Tainted onceInstant::now() - first_mismatch.at_unix_ms > dismissable_after, only when the embedder opted into time-based dismissal.TaintConfig::DataDir { dir, rpc_url, chain_id }usage in tests and any consumers should keep compiling via a builder /Fromimpl or via accepting the field via the new struct shape.Out of scope
Custom(Arc<dyn TaintStore>)consumers wrapping an encrypted store.Done when
TaintConfigis a struct withpersist/scope/acknowledgement/dismissable_afterfields.builder_data_dir_preserves_taint_across_restarttest still passes (semantically identical withacknowledgement = PerSession).PerProviderscope (cross-RPC taint),Persistedack (survives restart), anddismissable_after(time-based auto-clear).