Skip to content

wallet-cli: Replace { wallet, store } with { wallet, dispose } #8779

@sirtimid

Description

@sirtimid

Surfaced as a deferred follow-up from PR #8446.

Problem

`createWallet` in `packages/wallet-cli/src/daemon/wallet-factory.ts` returns `{ wallet, store }`. The close-after-destroy ordering invariant is encoded only in the function's JSDoc:

> Close `store` only **after** `await wallet.destroy()` has resolved; closing earlier will cause persistence writes during teardown to fail.

Today the invariant is consumed in two distinct cleanup ladders in `packages/wallet-cli/src/daemon/daemon-entry.ts` (the startup-failure `catch` block and the SIGTERM/SIGINT `shutdown` closure). Both implement the order correctly today, but if a third site is added — or if either ladder grows a new step (e.g. flushing the SQLite WAL) — the JSDoc isn't enforcement, and the two paths can drift.

Proposed direction

Have `createWallet` return `{ wallet, dispose }` instead of `{ wallet, store }`. `dispose` is the single owner of teardown:

```ts
export type CreateWalletResult = {
wallet: Wallet;
dispose: () => Promise<void>;
};
```

`dispose` encapsulates `await wallet.destroy()` then `store.close()` (with per-step error logging) so neither call site can get the order wrong.

Acceptance

  • `wallet-factory.ts` no longer exposes `store` to consumers.
  • `daemon-entry.ts`'s two cleanup ladders both call `dispose` instead of inlining `wallet.destroy()` + `store.close()`.
  • Tests in `wallet-factory.test.ts` cover `dispose` semantics (idempotent, handles destroy failure, closes the store even when destroy throws).
  • Coverage stays at 100%.

Context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions