Skip to content

feat: remove all MYX protocol from core - #10038

Open
abretonc7s wants to merge 8 commits into
mainfrom
TAT-3892-feat-remove-myx-protocol-core
Open

feat: remove all MYX protocol from core#10038
abretonc7s wants to merge 8 commits into
mainfrom
TAT-3892-feat-remove-myx-protocol-core

Conversation

@abretonc7s

@abretonc7s abretonc7s commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Explanation

@metamask/perps-controller shipped a full MYX protocol implementation alongside HyperLiquid and
Lighter. MYX is being dropped as a venue, and keeping it cost real weight: an optional
@myx-trade/sdk dependency, a dynamic-import + webpackIgnore workaround plus three
!dist/*MYX* files exclusions so extension bundles could skip the provider, and 'myx'
branches threaded through the controller, the provider router, and the provider-type unions.

This PR removes MYX from the package. It deletes MYXProvider, MYXClientService,
MYXWalletService, the MYX adapter, and the MYX config and type modules along with their test
suites; drops the @myx-trade/sdk dependency and the packaging exclusions it required; and
de-wires the controller — #isMYXProviderEnabled, the dynamic-import registration path,
registerMYXProvider, handleMYXImportError, resolveMyxAuthConfig, and the 'myx' routing and
cache-key branches all go. Net: ~8,700 lines removed across 42 files.

Notable API effects, all breaking for consumers that used MYX:

  • PerpsProviderType is now 'hyperliquid' | 'lighter'. switchProvider('myx') returns
    { success: false, error: 'Provider myx not available' }. A 'myx' value restored from
    persisted state falls back to 'hyperliquid' and rewrites the persisted value, so existing
    MYX users self-heal on next launch rather than getting a broken perps tab.
  • The MYXCredentials type and providerCredentials.myx option are gone.
  • All MYX_* constants, getMYXChainId / getMYXHttpEndpoint, the fromMYX* / toMYX*
    converters, and the MYX-only USDT_BNB_TESTNET / USDT_BNB_MAINNET collateral addresses are no
    longer exported.
  • PROVIDER_CONFIG.MYX_TESTNET_ONLY is removed; buildProviderCacheKey no longer special-cases
    'myx'.
  • The perpsMyxProviderEnabled remote flag and MM_PERPS_MYX_PROVIDER_ENABLED env override are
    no longer read, so clients can retire both.

Two changes may not be obvious:

  • packages/authenticated-user-storage is touched deliberately. PerpsWatchlistMarkets.myx
    is a server-persisted preference schema, not protocol code, and blobs already stored remotely
    contain a myx key. Deleting the required field would have failed validation on that existing
    data. It is instead made optional() and @deprecated: nothing writes it any more, stored
    blobs still validate, and perps-controller is left with zero MYX references.
  • The files field is now plain ["dist/"]. With the MYX exclusions gone, everything emitted
    into dist/ publishes — so a stale dist/ from a previous build would ship MYX artifacts. The
    validation below uses yarn build:clean (which wipes packages/*/dist first) and asserts the
    emitted tree contains no MYX file at all.

HyperLiquid and Lighter behavior is unchanged. Where MYX served only as "a second provider" in
multi-provider aggregation, routing, and cache tests, those cases were repointed at Lighter rather
than deleted, so multi-provider coverage is preserved.

Validation

  • yarn workspace @metamask/perps-controller run test79 suites, 3399 passed, 0 failures,
    coverage thresholds met (89.4% lines vs 80% required, 81.54% branches vs 69%, 85.58% functions
    vs 78%).
  • yarn workspace @metamask/authenticated-user-storage run jest44 passed, 0 failures.
  • yarn build:clean (root ts-bridge) — exit 0, "Project built successfully"; the emitted
    packages/perps-controller/dist contains no MYX file, and dist/index.d.cts / dist/index.cjs
    export no MYX symbol.
  • ESLint over changed files — 0 errors. Prettier — clean. yarn changelog:validate — passes.
  • An end-to-end proof recipe asserts the removal (no MYX in src//tests/, none in the manifest,
    none in the built dist/) and then reads live HyperLiquid testnet positions, orders, and
    account state through the de-wired controller to show the removal caused no regression. The
    assertions were confirmed to fail against the pre-change tree, so a revert of this diff breaks
    the recipe.

References

Client follow-ups needed before/alongside adoption:

  • Mobile and extension must drop any providerCredentials.myx, activeProvider: 'myx', or
    providerId: 'myx' usage and remove MYX from provider pickers.
  • The perpsMyxProviderEnabled remote feature flag can be retired once clients are updated.
  • A future AUS schema migration can drop the deprecated myx watchlist key entirely once no
    stored blob relies on it.

Checklist

  • I've updated the test suite for new or updated code as appropriate
    • MYX-only suites deleted; shared multi-provider tests repointed at Lighter so aggregation,
      routing, and cache coverage is preserved.
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
    • JSDoc examples that used 'myx' as a sample provider now use 'lighter'; comments in the
      Lighter provider, wallet service, and adapter that referenced MYX as their template were
      rewritten to stand alone.
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
    • perps-controller (Removed, **BREAKING:**) and authenticated-user-storage (Changed).
  • I've introduced breaking changes in this PR and have prepared draft pull requests for
    clients and consumer packages to resolve them
    • Breaking changes are introduced and documented above, but the client draft PRs are not yet
      open. They are listed under References and should land before this is adopted.

Screenshots/Recordings


Note

Medium Risk
Large breaking removal across public types and exports; clients must drop MYX usage, though persisted stale provider state is handled with a HyperLiquid fallback.

Overview
Removes MYX as a perps venue across @metamask/perps-controller and aligned user-preference types. The MYX provider stack (MYXProvider, client/wallet services, adapters, config, types), the optional @myx-trade/sdk dependency, and dynamic-import / dist packaging workarounds are deleted (~8k+ lines).

Breaking API surface: PerpsProviderType is now 'hyperliquid' | 'lighter'; MYXCredentials, providerCredentials.myx, all MYX_* exports, and MYX-specific cache/config behavior are gone. The controller no longer registers MYX or reads perpsMyxProviderEnabled / MM_PERPS_MYX_PROVIDER_ENABLED. Persisted activeProvider: 'myx' self-heals to HyperLiquid instead of failing init. Multi-provider tests and docs examples that used MYX are repointed to Lighter.

Authenticated user storage: PerpsWatchlistMarkets drops the required myx key from types and validation; existing remote blobs with a myx field should still validate because unknown keys are ignored.

HyperLiquid and Lighter paths are otherwise unchanged.

Reviewed by Cursor Bugbot for commit 56a972d. Bugbot is set up for automated code reviews on this repo. Configure here.

@abretonc7s abretonc7s changed the title chore: prepare farmslot publication pkg-d01ea91d-mti36iqj feat: remove all MYX protocol from core Sep 1, 2026
@abretonc7s
abretonc7s marked this pull request as ready for review September 1, 2026 05:59
@abretonc7s
abretonc7s requested review from a team as code owners September 1, 2026 05:59
@abretonc7s
abretonc7s deployed to default-branch September 1, 2026 05:59 — with GitHub Actions Active
@cursor
cursor Bot requested review from geositta and michalconsensys September 1, 2026 06:02
abretonc7s added a commit that referenced this pull request Sep 1, 2026
MYX was an unused protocol, so its removal is filed as a plain Removed
entry rather than a breaking change.

Point both changelog links at the real PR (#10038); they were written
against a guessed number before the PR existed.
michalconsensys
michalconsensys previously approved these changes Sep 1, 2026
geositta
geositta previously approved these changes Sep 1, 2026
MYX is no longer a supported perps venue. Removing it drops the optional
@myx-trade/sdk dependency, the dynamic-import plus webpackIgnore workaround,
and the three !dist/*MYX* packaging exclusions that existed only to keep the
provider out of published bundles.

Deletes MYXProvider, MYXClientService, MYXWalletService, the MYX adapter, and
the MYX config and type modules with their test suites, and de-wires the
controller: #isMYXProviderEnabled, the dynamic import, registerMYXProvider,
handleMYXImportError, resolveMyxAuthConfig, and every 'myx' routing and
cache-key branch. PerpsProviderType narrows to 'hyperliquid' | 'lighter'.

BREAKING CHANGE: removes the MYXCredentials type, the providerCredentials.myx
option, PROVIDER_CONFIG.MYX_TESTNET_ONLY, and all MYX_* constant, endpoint,
converter, and asset-config exports. Setting activeProvider: 'myx' or passing
providerId: 'myx' now throws Unsupported provider.

PerpsWatchlistMarkets.myx in authenticated-user-storage is made optional and
deprecated rather than removed: it is a server-persisted schema, and blobs
already stored with a myx watchlist must keep validating. Nothing writes it
any more. A regression test pins both shapes.

Where MYX served only as a second provider in aggregation, routing, and cache
tests, those cases were repointed at Lighter so multi-provider coverage is
preserved. HyperLiquid and Lighter behavior is unchanged.
`activeProvider` is persisted, and before this fix a value restored from an
older version whose venue has since been removed — notably 'myx' — fell
through to the `Unsupported provider` throw. That throw happens inside
performInitialization, so it was caught by the retry loop, burned every
attempt with backoff, and ended at InitializationState.Failed without ever
rewriting the persisted value. Perps stayed broken on every launch, not just
the first, until the client cleared state.

Make the fallback the default branch instead: any direct provider that is not
registered falls back to hyperliquid and rewrites the persisted value, which
is how 'myx' behaved before it was removed. The compile-time break is
unaffected — PerpsProviderType still does not admit 'myx'.

Also corrects the changelog, which claimed the controller throws for 'myx':
switchProvider returns { success: false, error: 'Provider myx not available' }
and persisted state now self-heals.
Remove the removed venue's name from the two explanatory comments left by
the self-heal fix; the fallback is generic, so the comments describe it
generically. The one remaining 'myx' literal is the regression test's
input — it reproduces the value real users have in persisted state, so
replacing it would stop the test proving upgrade behaviour.

Condense the changelog entry from implementation narration to migration
instructions, and drop the nested BREAKING prefixes now that the parent
entry carries one.
MYX was an unused protocol, so its removal is filed as a plain Removed
entry rather than a breaking change.

Point both changelog links at the real PR (#10038); they were written
against a guessed number before the PR existed.
The previous commit kept `myx` on `PerpsWatchlistMarkets` as an optional,
`@deprecated` member, on the theory that preference blobs already stored
server-side would stop validating if the key were removed outright.

That was wrong. `PerpsWatchlistMarketsSchema` is a superstruct `type()`,
which ignores unknown keys — only `object()` rejects them. Stored blobs
carrying a `myx` watchlist validate exactly the same with the key gone,
so the declaration bought nothing and left dead code in a removal.

Remove the type member and the schema entry. The compat test stays, no
longer referencing the removed type: it pins that pre-removal blobs keep
validating, and records that this depends on `type()` over `object()`.
The test asserted that a preference blob carrying a `myx` watchlist still
validates after the key was removed from `PerpsWatchlistMarkets`. That is
superstruct's own `type()` behaviour — unknown keys pass, `object()` would
reject them — not behaviour this package defines, and the suite still
reports 100% coverage without it.

The reasoning it documented is kept in the changelog entry for the removal,
which is where a maintainer tightening the schema would look.
The removal narrows `PerpsProviderType` to `'hyperliquid' | 'lighter'` and
drops public exports (`MYXCredentials`, the `MYX_*` constants, the
`getMYX*` / `fromMYX*` / `toMYX*` helpers, `PROVIDER_CONFIG.MYX_TESTNET_ONLY`),
which is breaking under the repo's changelog rules regardless of how widely
the venue was used. Restore the prefix dropped in 84496d2, keeping the
corrected PR link.
The Scale price-ladder tests merged from main use 'myx' as the stand-in
second provider. That id no longer exists in PerpsProviderType, so point
them at 'lighter' instead, which keeps each case's intent (default route,
explicit route, not implemented, not registered, misattributed ladder).
@abretonc7s
abretonc7s force-pushed the TAT-3892-feat-remove-myx-protocol-core branch from 4e1d1fd to 56a972d Compare September 2, 2026 00:41
@abretonc7s

Copy link
Copy Markdown
Contributor Author

Rebased onto origin/main (93d1ecb86) to clear the merge conflict — the PR was showing mergeable_state: dirty. Pushed as 56a972d11.

Two things needed resolving, both from main, neither from review feedback (there were no open review comments or unresolved threads on this PR):

1. packages/perps-controller/CHANGELOG.md conflict. main's #10021 entry and this PR's MYX-removal entry landed on the same ## [Unreleased] anchor. Kept both, ordered per Keep a Changelog (### Added, then ### Removed). Nothing dropped or reworded; yarn changelog:validate passes.

2. 'myx' came back via #10021's tests. The new Scale price-ladder tests use 'myx' as the stand-in second provider for routing cases. Since this PR removes 'myx' from PerpsProviderType, after the rebase those tests referenced a removed union member and the deleted mockMYXProvider. Git merged it textually with no conflict marker, so it only showed up as type errors.

Retargeted those cases at 'lighter', preserving each one's intent (default route, explicit route, not-implemented, not-registered, misattributed ladder). This matches the approach already used everywhere else in the PR — where MYX served only as "a second provider", the case was repointed at Lighter rather than deleted. Three test files touched, no src/ change:

  • tests/src/providers/AggregatedPerpsProvider.test.ts
  • tests/src/PerpsController.operations.test.ts
  • tests/src/providers/HyperLiquidProvider.strategy-orders.test.ts

PerpsController.providers-cache.test.ts still contains the literal 'myx' on purpose — that's the regression test asserting init() self-heals a persisted activeProvider naming a removed venue. The literal is the assertion.

Validation on the post-rebase tree:

  • perps-controller — 79/79 suites, 3417 passed, 0 failed; coverage 89.43% lines / 81.59% branches / 85.62% functions, all above thresholds.
  • authenticated-user-storage — 44 passed, 0 failed.
  • Root yarn build (ts-bridge) — exit 0, "Project built successfully". Emitted packages/perps-controller/dist contains zero MYX files and index.d.cts / index.cjs export zero MYX symbols (worth re-asserting since files is now plain ["dist/"]).
  • ESLint on changed files — 0 errors. Prettier — clean. yarn changelog:validate — passes.
  • The PR's proof recipe re-run post-rebase — pass: the removal assertions still hold, and the de-wired controller still reads live HyperLiquid testnet positions, orders, and account state.

Only the changelog needed a real merge decision; the rest was mechanical. Re-approval needed since the push reset it.

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.

3 participants