Skip to content

refactor(wallet-cli): Replace { wallet, store } with { wallet, dispose }#8847

Draft
sirtimid wants to merge 1 commit into
rekm/wallet-clifrom
sirtimid/wallet-cli-dispose-handle
Draft

refactor(wallet-cli): Replace { wallet, store } with { wallet, dispose }#8847
sirtimid wants to merge 1 commit into
rekm/wallet-clifrom
sirtimid/wallet-cli-dispose-handle

Conversation

@sirtimid
Copy link
Copy Markdown

Summary

  • createWallet in daemon/wallet-factory now returns { wallet, dispose } instead of { wallet, store }. dispose is the single owner of teardown — it runs await wallet.destroy() then store.close(), with per-step failures forwarded to the supplied logger (or console.error if none).
  • The two daemon cleanup ladders in daemon-entry.ts (startup-failure catch block + SIGTERM/SIGINT shutdown closure) now both call dispose instead of inlining the order, so a future third call site or extra teardown step can't drift.
  • The disposer is idempotent (concurrent and sequential calls coalesce onto a single teardown promise), closes the store even when wallet.destroy() rejects, and survives a throwing user-supplied logger.
  • The pre-resolution catch block inside createWallet was tightened to route through the same reporter, so a store.close() throw during first-run cleanup can no longer mask the original failure (e.g. bad SRP).

Closes #8779. Builds on #8446 (the deferred refactor was tracked there).

Test plan

  • yarn workspace @metamask/wallet-cli run test — 250 passing, 100% statements/branches/funcs/lines on wallet-factory.ts and daemon-entry.ts.
  • yarn workspace @metamask/wallet-cli run build — clean.
  • yarn eslint packages/wallet-cli/src — clean.
  • yarn workspace @metamask/wallet-cli run changelog:validate — clean (no entry; the package is unreleased and this is internal).
  • New tests cover: destroy-before-close ordering, concurrent + sequential coalescence, store-closes-even-when-destroy-rejects, log routing for each step, console.error fallback when no logger supplied, console.error fallback when the supplied logger throws, and store.close throwing during first-run cleanup not masking the original error.

🤖 Generated with Claude Code

`createWallet` now returns a `dispose` callback that owns the
`wallet.destroy()` → `store.close()` ordering and reports per-step
failures through the supplied logger. Both daemon-entry cleanup
ladders (startup-failure catch and SIGTERM/SIGINT shutdown) call
`dispose` instead of inlining the order, so a future third call site
or extra teardown step (e.g. SQLite WAL flush) can't drift.

The disposer is idempotent across concurrent and sequential calls,
closes the store even when destroy rejects, and falls back to
`console.error` if no logger (or a throwing one) is supplied. The
pre-resolution catch block in `createWallet` was also tightened to
route through the same reporter so a `store.close()` throw can't
mask the original failure (e.g. bad SRP).

Closes #8779

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant