Skip to content

[pull] main from MetaMask:main#657

Merged
pull[bot] merged 14 commits into
Reality2byte:mainfrom
MetaMask:main
Jun 16, 2026
Merged

[pull] main from MetaMask:main#657
pull[bot] merged 14 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull

@pull pull Bot commented Jun 16, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

cryptodev-2s and others added 14 commits June 16, 2026 08:20
…ext (#9138)

## Explanation

Phase B PR #11 of the [package migration process
guide](https://github.com/MetaMask/core/blob/main/docs/processes/package-migration-process-guide.md)
for
[\`@metamask/smart-transactions-controller\`](https://github.com/MetaMask/core/tree/main/merged-packages/smart-transactions-controller).

### Removed
- The stale "⚠️ PLEASE READ ⚠️ — migration in progress" notice (no
longer relevant — migration is in progress only on the source-repo
README).
- The standalone-repo \`Setup\` / \`Testing and Linting\` / \`Release &
Publishing\` / \`Preview Builds\` instructions — all handled at the
monorepo root.

### Added/preserved
- The standard "this package is part of a monorepo" pointer to the root
README (matches \`packages/transaction-controller/README.md\`).
- The package intro, the \`Installation\` block, and the \`Feature
Flags\` content — the LaunchDarkly flag schema docs are genuinely useful
for consumers, so they're preserved and promoted out of \`Contributing\`
into their own top-level section.

Net diff: −94 / +4.

This is the final Phase B step. Once it lands, Phase C PR #12 moves the
package from \`merged-packages/\` into \`packages/\` and wires it into
yarn workspaces.

## References

- Prior steps: history merge (#9130), CHANGELOG reset (#9131), strip
files (#9132), replace configs (#9134), align deps + scripts (#9136)
- Migration process:
[\`docs/processes/package-migration-process-guide.md\`](https://github.com/MetaMask/core/blob/main/docs/processes/package-migration-process-guide.md)

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
…types (#9094)

## Explanation

The mobile Perps leaderboard/position UX needs typed, validated access
to the perp metadata that social-api now returns for Hyperliquid (and
other perp) positions. Today `@metamask/social-controllers` drops those
fields on the floor because they aren't declared on the response types
or their superstruct schemas.

This PR extends the `SocialService` response types and validation
schemas with the optional perp fields:

- `Trade` (and `TradeStruct`): adds `classification` (`'spot' | 'perp' |
'send' | 'receive' | null`), `perpPositionType` (`'long' | 'short' |
null`), and `perpLeverage` (`number | null`).
- `Position` (and `PositionStruct`): adds `perpPositionType`,
`perpLeverage`, and `positionAmountWithLeverage` (the leveraged/notional
position size — Hyperliquid/perp only).

All fields are optional and nullable, so spot responses validate exactly
as before — this is a purely additive, non-breaking change. This is the
client-side half of the Hyperliquid perps work; the matching server-side
passthrough lives in social-api.

**Audit follow-up (TSA-726):** corrected the
`positionAmountWithLeverage` JSDoc — it is the leveraged/notional size
as reported by Clicker (**not** necessarily `positionAmount ×
perpLeverage`; the ratio varies across multi-fill positions) and is
notional exposure, **not** capital at risk (the margin/capital at risk
is `costBasis`). This keeps consumers from mis-deriving leverage or risk
from the field; the perp PnL fix that depends on this contract lives in
consensys-vertical-apps/va-mmcx-social-api#86.

## References

- TSA-629
- Part of: TSA-726 (perp PnL correctness — this PR clarifies the
`positionAmountWithLeverage` contract used by the fix)
- social-api passthrough PR:
consensys-vertical-apps/va-mmcx-social-api#86
- Consumer follow-up: metamask-mobile Perps leaderboard/position UI
(next step of this task)

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Additive optional/nullable fields and stricter validation only when
new perp keys are present; spot payloads without those fields behave as
before.
> 
> **Overview**
> Adds **optional, nullable perp/Hyperliquid metadata** to social
position and trade models so `SocialService` no longer strips fields the
API already returns.
> 
> **`Trade` / `TradeStruct`** now include `classification` (`spot` |
`perp` | `send` | `receive`), `perpPositionType`, and `perpLeverage`.
**`Position` / `PositionStruct`** add `perpPositionType`,
`perpLeverage`, and `positionAmountWithLeverage` (leveraged size /
capital at risk). Matching superstruct rules on `PositionStruct`
validate these on open/closed positions and `fetchPositionById`.
> 
> Tests cover passthrough of perp payloads, explicit `null` for spot,
and rejection of invalid enum values (e.g. bad `perpPositionType`).
Changelog documents the additive API surface for consumers (e.g. mobile
Perps UI).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
a3e0ef7. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Explanation

<!--
Thanks for your contribution! Take a moment to answer these questions so
that reviewers have the information they need to properly understand
your changes:

* What is the current state of things and why does it need to change?
* What is the solution your changes offer and how does it work?
* Are there any changes whose purpose might not obvious to those
unfamiliar with the domain?
* If your primary goal was to update one package but you found you had
to update another one along the way, why did you do so?
* If you had to upgrade a dependency, why did you do so?
-->

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
…icked event properties (#9121)

## Explanation

For this [core extension UX
ticket](https://consensyssoftware.atlassian.net/browse/CEUX-1092), we
want to embellish the Unified SwapBridge Button Clicked event with the
`environment_type` of the UI context. These metrics do already include
environment type, but they always have the value `background` as that is
the context used when they are emitted. We want to however have the UI
context for this metric so we can track `sidepanel` vs `popup` etc.

So this PR modifies the `Unified SwapBridge Button Clicked` event
properties (exported via `RequiredEventContextFromClient` in
`@metamask/bridge-controller`) to add optional `environment_type` to be
able to pass this data in directly at the call site where the values are
either `sidepanel`, `popup` or `fullscreen`. Client side PR
[here](MetaMask/metamask-extension#43540).

## References

* Part fixes: https://consensyssoftware.atlassian.net/browse/CEUX-1092

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
…ly signed once a quote is available (#9145)

## Explanation

### Current state

For every transaction that MM Pay produces a quote for,
`TransactionPayController` writes `batchTransactions`,
`batchTransactionsOptions`, and `metamaskPay` onto the transaction meta
inside `syncTransaction`. Submission is then driven by the strategy
publish hook (`TransactionPayPublishHook` → `RelayStrategy.execute` /
etc.) — the local RLP signature produced by
`TransactionController.#signTransaction` is discarded.

For accounts whose keyring **can** RLP-sign (HD, Simple Key Pair,
hardware), the wasted local sign is harmless. For `MoneyKeyring` it is
fatal: `@metamask/eth-money-keyring@^3.0.0` does not implement
`signTransaction` (only `signEip7702Authorization`, `signTypedData`,
`signPersonalMessage`). The publish path therefore throws
`KeyringController - The keyring for the current address does not
support the method signTransaction.` before the publish hook is ever
reached, so MM Pay never gets a chance to submit the transaction.

### Solution

Set `isExternalSign` in `syncTransaction` based on whether MM Pay
actually produced quotes:

```ts
tx.isExternalSign = hasQuotes;
```

This is the moment MM Pay commits to publishing the transaction via its
strategy hook, so it is also the moment the controller can opt out of
local RLP signing. `TransactionController.#signTransaction` already
short-circuits when `isExternalSign === true`, so this lets execution
flow straight into the publish hook chain.

When there are no quotes (e.g. the user selected the target token as the
payment token in a Predict flow) we clear the flag so the transaction
falls back to normal local signing.

### Effects per flow

| Flow | Before | After |
| --- | --- | --- |
| Money Account deposit / withdraw (quotes exist) | Throws
`UnsupportedSignTransaction` | Skips local sign, strategy publish hook
submits |
| Predict / Perps / Across / Relay / Polymarket / Hyperliquid (quotes
exist) | Sign locally, discard `rawTx`, strategy publishes | Skip local
sign, strategy publishes (mild speedup, no behavior change) |
| MM Pay tracked transaction but no viable quote returned (e.g. Predict
where payment token == target token) | Sign locally and publish |
Unchanged — flag is `false`, falls back to local signing |
| Transactions outside MM Pay | Unchanged | Unchanged — never reach
`syncTransaction` |

### Notes

- `hasQuotes` is derived from `quotes.length > 0`, which is the honest
signal of "MM Pay owns submission". `batchTransactions.length` is not
equivalent: `RelayStrategy` does not implement `getBatchTransactions`,
so it would be `0` on the happy path.
- Quote refresh re-runs `syncTransaction`, so the flag self-heals if the
user changes the payment token mid-flow.

## References

Fixes: MUL-1918

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
)

## Explanation

Previously we would inject `failoverRpcUrls` into the persisted state at
startup time in both clients. This PR removes the need for that by
introducing a `failoverUrls` constructor argument. This constructor
argument is used when creating network clients and overrides the
persisted configuration.

## References

https://consensyssoftware.atlassian.net/browse/WPC-1059

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

GitHub Actions limits a single job to 256 matrix combinations. As the
number of packages in the monorepo has grown, the combined matrix of
Node.js versions (18, 20, 22) and packages exceeds that limit, causing
the `test` job to fail before any tests run.

This PR splits the single `test` job into three jobs — `test-18`,
`test-20`, and `test-22` — each running the package matrix against a
single Node.js version. This keeps every job comfortably under the
256-combination limit while preserving identical test coverage across
Node.js versions.

## References

N/A

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

Release `1046.0.0` with minor version bump for:

- **`@metamask/transaction-pay-controller`** `23.7.0` → `23.8.0`

### `@metamask/transaction-pay-controller@23.8.0`

### Changed

- Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0`
([#9129](#9129))

### Fixed

- Mark MM Pay transactions as externally signed when quotes are
available ([#9145](#9145))

## References

- [#9145](#9145) —
fix(transaction-pay-controller): mark MM Pay transactions as externally
signed once a quote is available
- [#9129](#9129) — Bump
`@metamask/keyring-controller`

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

**Phase C PR #12** of the [package migration process
guide](https://github.com/MetaMask/core/blob/main/docs/processes/package-migration-process-guide.md)
for
[`@metamask/smart-transactions-controller`](https://github.com/MetaMask/core/tree/main/packages/smart-transactions-controller).

Final move from `merged-packages/` into `packages/` plus the wiring
needed for `yarn install`, `yarn workspace ... test`, `yarn
constraints`, and the README/CHANGELOG checks to pass.

### Changes

- **Moved**: `git mv merged-packages/smart-transactions-controller
packages/` (renames only, no content drift). Removed the now-empty
`merged-packages/` directory.
- **Root tsconfigs**: added `./packages/smart-transactions-controller`
and `./packages/smart-transactions-controller/tsconfig.build.json`
references (alphabetical).
- **Root `README.md`**: ran `yarn readme-content:update` to add the
package to the package list + the mermaid dependency graph.
- **`yarn.config.cjs`**: added `@metamask/smart-transactions-controller`
to the license-exception list. It carries a ConsenSys non-commercial
`LICENSE` we did not relicense to MIT.
- **`.github/CODEOWNERS`** + **`teams.json`**: registered ownership to
`@MetaMask/transactions` / `team-transactions` (added a new
"Transactions Team" section in `CODEOWNERS`).
- **`packages/smart-transactions-controller/package.json`**:
- Aligned `nock` from `^14.0.0-beta.7` → `^13.3.1` to match the rest of
the monorepo. The v14-beta mock incompatibilities we saw in the
source-repo context don't surface under the monorepo's
`jest.config.packages.js` setup — 196/196 tests pass on nock 13.
- Dropped 4 unused deps flagged by knip: `@ethereumjs/tx`,
`@ethereumjs/util`, `fast-json-patch` (runtime),
`@metamask/gas-fee-controller` (dev).
- `yarn constraints --fix` stripped the trailing period from
`description`.
- **`packages/smart-transactions-controller/jest.config.js`**: dropped
the `setupFiles: ['./setupJest.js']` override and the `testTimeout:
2500` override. Core's root `tests/setup.ts` already clears Node's
native fetch and loads `isomorphic-fetch` (a superset of what
`setupJest.js` did); Jest's default 5000ms timeout is more generous than
the previous 2500ms. Coverage thresholds kept at the source-repo's
originals (95% achieved comfortably exceeds them).
- **`packages/smart-transactions-controller/setupJest.js`**: deleted
(now redundant).
- **`packages/smart-transactions-controller/CHANGELOG.md`**: documented
the migration + dropped deps under `[Unreleased]` and added the
`[Unreleased]` link reference required by `auto-changelog` v6.
- **Formatting**: applied oxfmt fixes to `package.json` +
`SmartTransactionsController.test.ts`.

### Testing

- Preview Test in Mobile:
MetaMask/metamask-mobile#31804
- Preview Test in Extension:
MetaMask/metamask-extension#43610

### Verification

- ✅ `yarn install`
- ✅ `yarn workspace @metamask/smart-transactions-controller test` —
196/196 pass; ~95% coverage
- ✅ `yarn workspace @metamask/smart-transactions-controller build`
- ✅ `yarn constraints`
- ✅ `yarn lint:teams`
- ✅ `yarn knip --dependencies` (clean for this package)
- ✅ `yarn workspace @metamask/smart-transactions-controller
changelog:validate`
- ✅ `yarn lint:misc` (oxfmt)
- ✅ `yarn readme-content:check`

### Downstream

No core package currently depends on
`@metamask/smart-transactions-controller`, so this PR contains no
downstream version-bump or CHANGELOG updates.

## References

- Prior steps: history merge (#9130), CHANGELOG reset (#9131), strip
files (#9132), replace configs (#9134), align deps + scripts (#9136),
README update (#9138)
- Migration process:
[`docs/processes/package-migration-process-guide.md`](https://github.com/MetaMask/core/blob/main/docs/processes/package-migration-process-guide.md)

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [ ] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

Reverts #9146 due to CI issues. A new release PR will be created after
this is merged.

Reverts commit `c87f17161`.

## References

- #9146

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

Release `1046.0.0` with minor version bump for:

- **`@metamask/transaction-pay-controller`** `23.7.0` → `23.8.0`

### `@metamask/transaction-pay-controller@23.8.0`

### Changed

- Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0`
([#9129](#9129))

### Fixed

- Mark MM Pay transactions as externally signed when quotes are
available ([#9145](#9145))

## References

- [#9145](#9145) —
fix(transaction-pay-controller): mark MM Pay transactions as externally
signed once a quote is available
- [#9129](#9129) — Bump
`@metamask/keyring-controller`
- [#9151](#9151) — Revert of
previous aborted Release/1046.0.0

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

Reverts #9153 due to CI issues. A new release PR will be created after
this is merged.

Reverts commit `538b7d4f9`.

## References

- #9153

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

Release `1046.0.0` with minor version bump for:

- **`@metamask/transaction-pay-controller`** `23.7.0` → `23.8.0`

### `@metamask/transaction-pay-controller@23.8.0`

### Changed

- Bump `@metamask/keyring-controller` from `^27.0.0` to `^27.1.0`
([#9129](#9129))

### Fixed

- Mark MM Pay transactions as externally signed when quotes are
available ([#9145](#9145))

## References

- [#9145](#9145) —
fix(transaction-pay-controller): mark MM Pay transactions as externally
signed once a quote is available
- [#9129](#9129) — Bump
`@metamask/keyring-controller`
- [#9155](#9155) — Revert of
previous aborted Release/1046.0.0

## Checklist

- [ ] I've updated the test suite for new or updated code as appropriate
- [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them
## Explanation

`@metamask/wallet-cli` runs a background daemon that hosts a
`@metamask/wallet` instance. For controller state to survive daemon
restarts, it needs durable local storage. This PR adds that persistence
layer. It is purely additive and not yet wired into a daemon process —
the daemon entry point that consumes it lands in a follow-up.

- **`KeyValueStore`** — a synchronous `better-sqlite3`-backed key-value
store (a single `kv` table with a TEXT key and a JSON-serialized TEXT
value). Corrupt rows fail loud (a descriptive, key-scoped error) rather
than returning garbage.
- **`loadState(store)`** — rehydrates persisted state into the `{
[controllerName]: { [property]: value } }` shape accepted by the
`Wallet` constructor's `state` option.
- **`subscribeToChanges(messenger, controllerMetadata, store, log?)`** —
subscribes to every `<Controller>:stateChanged` event and writes
persist-flagged top-level properties through to the store (applying
`StateDeriver` persist functions, and deleting a key when its property
is removed from state). It returns an unsubscribe handle; teardown is
owned by the caller (a `dispose()` handle in a later PR), so there is no
package-level teardown event.

### `better-sqlite3` native addon

`better-sqlite3` ships a native C addon. The monorepo runs Yarn with
`enableScripts: false`, so the addon is not built during `yarn install`.
To handle this:

- a `test:prepare` step (`scripts/install-binaries.sh`) fetches a
matching prebuild via `prebuild-install` before tests run;
- `engines.node` is set to `>=20` (better-sqlite3 v12 only ships
prebuilt binaries for Node 20+);
- `@metamask/wallet-cli` is excluded from the Node 18.x CI test matrix;
- `yarn.config.cjs` exempts the package from the standard `test`-script
and `engines.node` constraints accordingly.

## References

- Closes #8682
- Builds on #9065 (the `@metamask/wallet-cli` package scaffold). This PR
targets that branch and should merge after it.

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md)
- [ ] I've introduced [breaking
changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md)
in this PR and have prepared draft pull requests for clients and
consumer packages to resolve them

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> New durable state path can diverge from in-memory state on disk write
failures (logged only today); native addon and Node 20+ requirement
affect install and CI.
> 
> **Overview**
> Adds **SQLite-backed persistence** in `@metamask/wallet-cli` so wallet
controller state can survive restarts (not yet wired into the daemon).
> 
> A synchronous **`KeyValueStore`** (`better-sqlite3`, JSON values in a
`kv` table) is the storage backend. **`loadState`** rebuilds `{
controllerName: { property: value } }` for `Wallet` construction,
honoring only properties still marked `persist` in controller metadata
so stale rows are not resurrected. **`subscribeToChanges`** listens on
`<Controller>:stateChanged`, writes persist-flagged top-level fields
from Immer patches (including `StateDeriver` transforms and deletes when
properties are removed), logs write failures without stopping the
process, and returns an unsubscribe handle.
> 
> **`better-sqlite3`** is added with **`engines.node` `>=20`**, a
**`test:prepare`** / **`install-binaries.sh`** prebuild step (monorepo
`enableScripts: false`), CI matrix exclusion for Node 18 on this
package, and **`yarn.config.cjs`** exceptions for the custom test script
and engines field. Dependencies on `@metamask/wallet`,
`@metamask/base-controller`, and `immer` are added with matching
tsconfig project references.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b9854de. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators Jun 16, 2026
@pull pull Bot added the ⤵️ pull label Jun 16, 2026
@pull pull Bot merged commit 408e040 into Reality2byte:main Jun 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants