Skip to content

feat(perps): myx write integrations#27460

Open
abretonc7s wants to merge 63 commits intomainfrom
feat/perps/myx-write-integration
Open

feat(perps): myx write integrations#27460
abretonc7s wants to merge 63 commits intomainfrom
feat/perps/myx-write-integration

Conversation

@abretonc7s
Copy link
Copy Markdown
Contributor

@abretonc7s abretonc7s commented Mar 13, 2026

Description

Add MYX as the second perpetual futures provider alongside HyperLiquid. This PR implements all write operations (place/close/cancel/edit orders, TP/SL, margin adjustment) and completes the full provider integration using @myx-trade/sdk v1.0.6.

MYX is a permissionless perpetual futures DEX on BNB Chain (mainnet) and Linea Sepolia (testnet). All provider-specific logic is encapsulated in MYXProvider.ts, following the same AggregatedPerpsProvider architecture as HyperLiquid.

What's included

Core provider layer:

  • MYXProvider -- 39 fully implemented PerpsProvider interface methods (market/limit orders, TP/SL, cancel, close, margin, batch operations)
  • MYXClientService -- SDK wrapper for REST calls, auth, price polling, WebSocket klines
  • MYXWalletService -- signing integration via MetaMask KeyringController
  • myxAdapter -- SDK type to PerpsProvider type adapters
  • myxConfig -- constants (fees, contracts, collateral config)

Key architectural decisions:

  • On-chain transactions for every trade (vs HL's off-chain matching engine)
  • REST polling (5s) for positions/orders/account (MYX WS doesn't push account data -- documented in tracker)
  • Hybrid REST + WS for candle charts
  • TP/SL implemented as separate trigger orders (vs HL's position-attached TP/SL)
  • Broker revenue via referral rebate model (tagging done, activation pending MYX team)

Validation:

  • 14 agentic recipes covering reads, market orders, position management, limit orders, and full lifecycle
  • All 14 recipes passed 3-tier validation (PoC, CDP, human review)
  • Full tracker: docs/perps/myx/MYX-INTEGRATION-TRACKER.md

Tests:

  • 86% new code coverage (763/888 changed lines)
  • 165 new tests across MYXProvider, MYXClientService, MYXWalletService, myxAdapter
  • All existing tests fixed and passing

Changelog

CHANGELOG entry: null

Related issues

Fixes: TAT-2461, TAT-2462, TAT-2471, TAT-2472, TAT-2473, TAT-2474, TAT-2475, TAT-2477, TAT-2478, TAT-2508, TAT-2524, TAT-2531, TAT-2532, TAT-2533, TAT-2534, TAT-2580

Manual testing steps

Feature: MYX perpetual futures trading

  Scenario: user places a market order on MYX
    Given app is on testnet with MYX provider selected
    And wallet has sufficient USDC balance

    When user navigates to a MYX market (e.g. META)
    And presses Long
    And enters $110 order size
    And presses Place Order
    Then order is submitted on-chain
    And position appears in positions list after block confirmation (~10-15s)

  Scenario: user closes a position
    Given user has an open MYX position

    When user presses Close on the position
    And confirms the close
    Then position is removed after block confirmation

  Scenario: user sets TP/SL on a position
    Given user has an open MYX position

    When user presses Auto Close on the position
    And sets Take Profit and Stop Loss prices
    And presses Set
    Then TP/SL trigger orders are created
    And position shows TP/SL prices

  Scenario: user places and cancels a limit order
    Given app is on testnet with MYX provider selected

    When user places a limit order at a price below market
    Then order appears in open orders list
    When user cancels the order
    Then order is removed from open orders

Screenshots/Recordings

Before

N/A -- MYX provider did not exist before this PR.

After

01-read-markets.mp4
02-read-account.mp4
03-calculate-fees.mp4
04-validate-order.mp4
05-read-fills.mp4
06-place-market-order.mp4
07-update-tpsl.mp4
08-add-margin.mp4
09-close-position.mp4
10-place-and-close-all.mp4
11-place-limit-order.mp4
12-cancel-order.mp4
13-edit-order.mp4

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

High Risk
High risk because it adds on-chain MYX order execution/cancel/edit/close and margin/TP-SL flows, plus new validation and polling logic that directly affects trading correctness and user funds.

Overview
Adds full MYX write-path support in MYXProvider (place/edit/cancel/batch cancel/close/batch close, TP/SL trigger orders, and margin adjustment), including authenticated context setup, per-pool min order sizing with buffer, dynamic fee-rate fetching, and hybrid WS-triggered refresh + REST polling for orders/positions/account.

Expands MYX configuration (myxConfig) with network-specific collateral decimals/addresses, contract + explorer metadata, CAIP asset IDs, contract-price conversions, caching TTLs, and fee precision defaults; exports new API parsing helpers for MYX REST values.

Tightens order validation plumbing by returning minimumRequired from validateOrder through PerpsController/UI hooks, updates UI formatting/fallback displays (position size formatting, oracle price display fallback, market stats -- defaults), and adjusts close-position sizing semantics (treat full close as size: undefined).

Written by Cursor Bugbot for commit 287571e. This will update automatically on new commits. Configure here.

Implements MYX order placement via SDK createIncreaseOrder and fixes a
critical decimal scaling bug in the read path. Validated end-to-end on
Linea Sepolia testnet (standalone script + in-app CDP).

Write path:
- MYXProvider.placeOrder(): symbol→pool→market→fees→order flow
- MYXClientService: createIncreaseOrder/DecreaseOrder, getUserTradingFeeRate
- MYXWalletService: EIP-1193 transport with gas param passthrough,
  sync getAddress() (SDK calls without await)
- Metro resolver: force @myx-trade/sdk ethers imports to bundled v6
  (project uses v5, SDK needs v6 BrowserProvider/Contract)

Decimal fix:
- REST API returns human-readable strings ("73485.10", "0.00136"),
  not 18-decimal scaled integers
- Switched read path from fromMYXSize/fromMYXCollateral (÷10^18)
  to fromMYXApiSize/fromMYXApiCollateral (parseFloat)
- Collateral decimals now per-network: USDT/BNB=18, USDC/Linea=6
  (verified on-chain)

Key SDK gotchas addressed:
- positionId must be '' (falsy) for new positions, not '0'
- Market order price must not be zero — fetch ticker + 5% buffer
- Gas params from SDK must be passed through transport to chain
Consolidated key findings from MYX SDK integration: ethers v5/v6
conflict, decimal scaling, gas params, and other SDK gotchas.
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-perps Perps team label Mar 13, 2026
Validated MYX write integration on testnet:
- showAccount: correct balance formula (freeAmount + walletBalance)
- closeOrder: close position via createDecreaseOrder + cancel via cancelOrder
- placeOrder: open position via createIncreaseOrder
- listMarkets/listOrders: market discovery and order listing
- SDK reference docs and inconsistency notes
Balance fix (3 bugs):
- getAccountInfo returns 7-element tuple, not keyed object
- First pool may return 0x (no deposits) — iterate pools until valid
- Tuple values in token-native decimals — use fromMYXCollateral not parseFloat
- subscribeToAccount was hardcoded to zeros — now REST polls via getAccountState

closePosition: mirrors placeOrder via createDecreaseOrder with 5% slippage
cancelOrder: wraps SDK client.order.cancelOrder
MYXClientService: added cancelOrder, fixed getAccountInfo return type
@abretonc7s abretonc7s changed the title Feat/perps/myx write integration feat(perps): myx write integrations Mar 17, 2026
- adaptMarketFromMYX: use Math.max(poolMin, static floor) * buffer for
  minimumOrderSize, preventing unreliable pool config values from
  setting too-low minimums
- MYXProvider.getMarkets: fetch per-pool configs in parallel, pass to adapter
- usePerpsOrderForm: default amount = max(networkDefault, market minimum),
  reset hasSetInitialAmount when market data loads async
- Documented testnet finding: getPoolLevelConfig reports $10 min but
  on-chain rejects below ~$55 notional — $100 static floor is correct
- Fix hallucinated LevelConfig property access (level/levelName are on
  PoolLevelConfig, not LevelConfig)
- Add scripts/perps/myx-poc to .eslintignore (PoC scripts use their
  own tsconfig, not the root one)
- Remove Metro ethers v5→v6 resolution hack (SDK no longer bundles ethers)
- Use SignerLike type for auth (remove as any casts)
- Fix recent activity decimal formatting (formatPositionSize)
- Fix oracle price fallback (pipe markPrice through stats)
- Fix volume to use USD from getBaseDetail (not token-denominated ticker)
- Fix fallback display values (-- instead of $0.00)
- Fix account balance (SDK renamed freeAmount → freeMargin)
- Add getOraclePrice, createPositionTpSlOrder, adjustCollateral, cancelOrders
- Implement updatePositionTPSL, updateMargin, batchCancelOrders
- Fix getTradeFlow namespace (Account → Api in SDK 1.0.2)
- Update test mocks for SDK 1.0.2 type changes
MYX has no exchange-defined size step (unlike HyperLiquid). Use
DECIMAL_PRECISION_CONFIG.FallbackSizeDecimals (6) for szDecimals
instead of the on-chain 18-decimal precision. Fixes raw 18-decimal
sizes showing in close position screen and other size displays.
…ions

SDK 1.0.2 uses viem getContract() which calls client.request() for
estimateContractGas/writeContract. Our adapter only had transport.request.

Add request, getAddresses, signMessage, sendTransaction to satisfy
WalletClientLike + viem Client interface. Also add MYX agentic recipes,
validation flows doc, PerpsCard size formatting fix, and websocket gaps update.
SDK 1.0.2 + viem pass BigInt values through JSON.stringify internally.
Add BigInt.prototype.toJSON polyfill to common.ts for PoC script compat.
Controller returns providerId (not provider) on market/position/order
objects. Also align field names: margin→marginUsed, volume24h→volume,
add leverage to position snapshots.
…ion fix

- Switch getOpenOrders() from filtering getOrderHistory() to using
  getPoolOpenOrders() API — returns only pending limit/trigger orders
  (TP/SL), matching Hyperliquid parity. Fixes stale PartialFilled
  market orders showing permanently in the UI.
- Add PartialFilled → 'filled' status mapping in adaptOrderFromMYX
  so partially-filled orders no longer fall through to 'open' in
  order history views.
- Fix string precision in closePosition/placeOrder: pass size as
  string through toMYXSize() to avoid parseFloat precision loss that
  caused dust on 18-decimal reconstruction.
- Fix nullish coalescing (|| → ??) for closeSizeStr.
@socket-security
Copy link
Copy Markdown

socket-security bot commented Mar 18, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​@​myx-trade/​sdk@​0.1.265 ⏵ 1.0.685 +610073 -398100

View full report

@github-actions github-actions bot added size-XL risk-high Extensive testing required · High bug introduction risk and removed size-L labels Mar 18, 2026
…integration

# Conflicts:
#	app/controllers/perps/utils/myxAdapter.ts
- Add 9 CDP validation recipes (myx-validation/) for sequential write flow testing
- Fix validate-recipe.sh recipe_ref to support namespaced refs (myx/auth)
- Add addMargin.ts PoC script (adjustCollateral SDK path)
- Add editOrder.ts PoC script (updateOrderTpSl SDK path)
- Add validation tracker with double-validation approach (PoC + CDP)
…document broker revenue

Replace magic fee fallback values (1000, 55000) with named constants
(MYX_DEFAULT_TAKER_FEE_RATE, MYX_FEE_RATE_PRECISION). Make calculateFees()
fetch dynamic rates from the MYX API with static fallback. Fix fee rate from
incorrect 0.05% to actual 0.055%. Document the broker referral rebate model
in MYX-SDK-REFERENCE.md. Also includes MYXClientService enhancements,
editOrder PoC updates, and tracker updates.
@github-actions github-actions bot added the risk-high Extensive testing required · High bug introduction risk label Mar 26, 2026
…ons and cache errors

- Add MYX_PROVIDER_ID constant; replace 'myx' literals with this.protocolId / MYX_PROVIDER_ID
- Use CLOSE_POSITION_CONFIG.UsdDecimalPlaces instead of magic .toFixed(2)
- closePositions: omit size param so closePosition resolves fresh position via #resolvePositionForSymbol
- #refreshMarketDetails: delete stale cache on fetch error instead of keeping indefinitely
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 26, 2026
The MYX SDK returns on-chain contract data with bigint fields
(e.g. freeMargin: 553959075n). parseAccountTuple's str() helper
only handled string and number types, causing all BigInt values
to fall through to '0' — resulting in zero balances displayed.
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 26, 2026
PerpsCancelAllOrdersView references this key but it was never added
to the locale file, showing a raw key string in the UI.
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 26, 2026
…ubscriptions

MYX WS subscriptions for positions and orders were not receiving events
due to incorrect auth pattern. The SDK expects walletClient-only auth
(no signer, no getAccessToken callback, no sdk. token prefix).

Production changes:
- MYXClientService: simplify auth to walletClient-only, remove dead
  token generation code (#generateAccessToken, #sha256Hex, sdk. prefix)
- MYXProvider: replace hybrid WS+REST polling with WS-only push for
  positions and orders. WS events trigger a full REST fetch to deliver
  complete data to callbacks. OrderFills and Account remain REST-polled
  (no WS channel exists for those).

PoC changes:
- common.ts: authenticateClient() uses walletClient-only auth
- wsSubscriptions.ts: added WS diagnostics, ticker control group,
  inline trade placement for end-to-end validation

Validated via PoC (3 WS events received) and agentic recipe 15
(9/9 steps passed including full trade cycle).
…criptions

MYX WS does not send initial snapshot on subscribe and does not push
continuous position updates (mark price, PnL). REST polling handles
continuous data refresh. WS fires instantly on state changes (trade
placed, filled, closed) triggering an immediate extra fetch so the
UI updates without waiting for the next poll cycle.

Also adds WS open event listener for reconnect tracking and fixes
test mock to include subscription.on/off methods.
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 26, 2026
Truthy check treated 0 as missing data, showing "--" instead of "$0.00"
for markets with genuinely zero volume or open interest.
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 27, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

…in spec

- Update WebSocket status: positions/orders confirmed working (event-driven, no
  initial snapshot), account has no WS (MYX confirmed polling only)
- Document EIP-712 domain spec from MYX team: name="Broker", version="1.0"
- Add setUserFeeData PoC script with corrected domain (still NotBrokerSigner on
  testnet — awaiting MYX team for testnet-specific guidance)
- Update fee model: 1e8 precision confirmed stable
- Update comparison table and protocol limitations to reflect WS status
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 27, 2026
…cdf1)

Add Number.isFinite() guard before the inline usdAmount comparison in
placeOrder so that NaN values from non-numeric params.usdAmount are
caught instead of silently bypassing the minimum order size validation.
@github-actions github-actions bot added risk-high Extensive testing required · High bug introduction risk and removed risk-high Extensive testing required · High bug introduction risk labels Mar 31, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: high
  • AI Confidence: 85%
click to see 🤖 AI reasoning details

E2E Test Selection:
This PR introduces a major MYX perpetuals trading integration with the following key changes:

  1. MYX SDK major version bump (0.1.265 → 1.0.6): Breaking API changes requiring significant refactoring throughout the MYX provider and client service layers.

  2. PerpsController.ts: Minor type enhancement - validateOrder return type now includes minimumRequired?: number to surface per-pool minimum order sizes to the UI.

  3. MYXProvider.ts: Massive implementation - previously all trading operations (placeOrder, editOrder, cancelOrder, closePosition, closePositions, updatePositionTPSL, updateMargin, withdraw) were stubbed with MYX_NOT_SUPPORTED_ERROR. They are now fully implemented with the new SDK v1.0.6 API.

  4. MYXClientService.ts: Major refactor - new authentication flow (walletClient-only auth, WS auth), new order write operations (createIncreaseOrder, createDecreaseOrder, cancelOrder, cancelOrders, updateOrderTpSl, adjustCollateral), new market data methods (getBaseDetail, getOraclePrice, getMarketDetail, getPoolLevelConfig, getUserTradingFeeRate), and WebSocket subscriptions for positions/orders.

  5. myxAdapter.ts: Significant data transformation changes - corrected API size/collateral parsing (human-readable strings vs 18-decimal scaled integers), position PnL/liquidation price calculations, leverage from SDK runtime field.

  6. myxConfig.ts: New constants, contract addresses, collateral token address change (mainnet USDT address updated), network-aware collateral decimals.

Tag Selection Rationale:

  • SmokePerps: Primary tag - the existing perps-add-funds.spec.ts test exercises the Perps Add Funds flow. The PerpsController changes (validateOrder type, MYX provider implementation) must be validated. This is the most directly impacted test.
  • SmokeWalletPlatform: Required by SmokePerps tag description - Perps is a section inside the Trending tab, and changes to Perps views affect Trending.
  • SmokeConfirmations: Required by SmokePerps tag description - Add Funds deposits are on-chain transactions that go through the confirmation flow.

No other test suites are impacted - changes are isolated to the Perps feature area (MYX provider, PerpsController, Perps UI hooks). No changes to Engine initialization, navigation, shared modals, or other controller systems that would affect other test suites.

Performance Test Selection:
The MYX provider now implements real trading operations with parallel pool config fetching, market detail caching (60s TTL), WebSocket subscriptions for positions/orders, and oracle price polling. These additions could impact perps market loading, position management, and add funds flow performance. The @PerformancePreps tag covers perps market loading, position management, add funds flow, and order execution - all directly affected by this PR's changes.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
17 value mismatches detected (expected — fixture represents an existing user).
View details

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk-high Extensive testing required · High bug introduction risk size-XL team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants