Skip to content

feat(mango): extract mango client#1087

Open
rogaldh wants to merge 17 commits into
solana-foundation:masterfrom
hoodieshq:feat/extract-mango-client
Open

feat(mango): extract mango client#1087
rogaldh wants to merge 17 commits into
solana-foundation:masterfrom
hoodieshq:feat/extract-mango-client

Conversation

@rogaldh

@rogaldh rogaldh commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Description

Extracts the Mango program decoder out of the app into a dedicated @explorer/decoder-mango pnpm workspace package, and wires that package into the root tooling.

  • Decode / detection / market logic and fixtures now live in packages/decoder-mango (with its own tests, tsconfig, and vitest config); the app consumes it via @explorer/decoder-mango.
  • Mango instruction cards moved into a new FSD feature app/features/instruction-program-mango; market lookups moved behind useMangoPerpMarket / useMangoSpotMarket hooks, with the data sourced from the decoder package.
  • Root scripts now cover workspace packages: build / test / typecheck delegate to their *:packages counterparts, while lint / format already traverse packages/* through the shared config (built output excluded).

No user-facing behaviour change — the cards render identically.

Type of change

  • Bug fix
  • New feature
  • Protocol integration
  • Documentation update
  • Other (please describe):

Internal refactor — extracting a self-contained workspace package and integrating it into the build/test/lint/typecheck tooling. No behavioural change.

Screenshots

No visual changes — the Mango instruction cards keep their existing markup and render identically; this is an internal extraction.

Testing

  • packages/decoder-mango ships unit tests for the config, decoder, detection, and market logic (46 tests), plus tests for the use-mango-market hooks.
  • Ran pnpm lint, pnpm typecheck, pnpm build, and pnpm test:packages locally; the app tsc --noEmit is clean.
  • Verified the recursive package scripts (typecheck:packages, etc.) run the package's own checks.

Related Issues

HOO-452

Checklist

  • My code follows the project's style guidelines
  • I have added tests that prove my fix/feature works
  • All checks pass locally (pnpm test, pnpm lint, pnpm typecheck)
  • I have run build:info script to update build information
  • CI/CD checks pass on the PR

@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

@rogaldh is attempting to deploy a commit to the Solana Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
explorer Ready Ready Preview, Comment Jun 16, 2026 1:28pm

Request Review

@greptile-apps

greptile-apps Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extracts the Mango v3 program decoder into a self-contained @explorer/decoder-mango pnpm workspace package and rewires the app to consume it, with no user-facing behaviour change. The Mango instruction UI cards are moved into a new FSD feature (app/features/instruction-program-mango), market lookups are encapsulated behind useMangoPerpMarket / useMangoSpotMarket hooks, and root scripts now delegate build/test/typecheck to workspace packages.

  • packages/decoder-mango introduces all decoder, detection, config, market, and program-ID logic with 46 unit tests; the previous review's cache-poisoning and null-guard issues on perp market fetching are fully addressed.
  • Spot market loading (getSpotMarketFromSpotMarketConfig) creates a new Connection and fires a fresh Market.load RPC call on every hook invocation — unlike perp markets which benefit from a module-level accountInfoCache.
  • ChangePerpMarketParamsDetailsCard has a stray {} empty JSX expression in the MNGO per period cell, likely a leftover unit-label placeholder.

Confidence Score: 5/5

Safe to merge — this is a pure internal extraction with no user-facing behaviour change and all prior review concerns addressed.

The change is a well-scoped refactor moving existing, battle-tested Mango decoder logic into a dedicated workspace package. The three issues from prior review threads (cluster-keyed cache, null guard on perp market account, and RPC rejection poisoning the cache) are all resolved in the new code. The two remaining observations (stray {} in a label cell and uncached spot market loading) are cosmetic and performance-only — they carry no correctness risk for the rendered output.

packages/decoder-mango/src/market.ts — the spot market fetch path has no caching counterpart to the perp market accountInfoCache.

Important Files Changed

Filename Overview
packages/decoder-mango/src/decoder.ts New decoder file extracting all Mango instruction decoders; numeric fields now consistently use .toNumber() (previous .toString() bug noted in earlier review is fixed).
packages/decoder-mango/src/market.ts Perp market fetching has proper cluster-keyed caching with transient-error eviction (addressing prior review threads); spot market loading via getSpotMarketFromSpotMarketConfig creates a new Connection and makes a fresh RPC call on every invocation with no caching.
packages/decoder-mango/src/detection.ts Clean extraction of instruction detection; parseMangoInstructionTitle throws on unknown variants (caught in MangoDetailsCard) and correctly reads the u32 LE discriminator.
app/features/instruction-program-mango/model/use-mango-market.ts New useMangoPerpMarket and useMangoSpotMarket hooks; both properly handle cancellation via isMounted() and reset to undefined on error or config becoming undefined.
app/features/instruction-program-mango/ui/ChangePerpMarketParamsDetailsCard.tsx MNGO per period cell contains a stray {} empty JSX expression; otherwise correctly guards on option flags and uses useMangoPerpMarket for the period duration label.
app/features/instruction-program-mango/ui/MangoDetailsCard.tsx Clean dispatcher routing Mango instruction variants to dedicated cards; error logging preserved and unknown instructions fall back to raw view.
app/features/instruction-program-mango/ui/AddSpotMarketDetailsCard.tsx Previous undefined-guard concern is fully addressed: spotMarketFromIndex result is cached in a variable and guarded with both !== undefined and !== 'UNKNOWN' checks.
package.json Root scripts wired to delegate to workspace packages: build, test, typecheck, and dev now run package scripts first; @blockworks-foundation/mango-client moved from root to packages/decoder-mango.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[TransactionInstruction] --> B[isMangoInstruction\ndetection.ts]
    B -->|true| C[MangoDetailsCard]
    C --> D[parseMangoInstructionTitle\ndetection.ts]
    D --> E{Switch on title}

    E -->|PlacePerpOrder / PlacePerpOrder2| F[PlacePerpOrder*DetailsCard]
    E -->|PlaceSpotOrder| G[PlaceSpotOrderDetailsCard]
    E -->|ChangePerpMarketParams| H[ChangePerpMarketParamsDetailsCard]
    E -->|AddSpotMarket| I[AddSpotMarketDetailsCard]
    E -->|Other Mango variants| J[Generic*DetailsCard]
    E -->|Unknown| K[Raw InstructionCard]

    F --> L[getPerpMarketFromInstruction\nmarket.ts]
    G --> M[getSpotMarketFromInstruction\nmarket.ts]
    H --> L

    L --> N[useMangoPerpMarket hook\nuse-mango-market.ts]
    M --> O[useMangoSpotMarket hook\nuse-mango-market.ts]

    N --> P[getPerpMarketFromPerpMarketConfig\nmarket.ts]
    O --> Q[getSpotMarketFromSpotMarketConfig\nmarket.ts]

    P --> R[(accountInfoCache\nmodule-level)]
    R -->|cache miss| S[Connection.getAccountInfo RPC]
    Q --> T[Market.load RPC\nno cache]

    subgraph decoder-mango package
        D
        L
        M
        P
        Q
        R
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[TransactionInstruction] --> B[isMangoInstruction\ndetection.ts]
    B -->|true| C[MangoDetailsCard]
    C --> D[parseMangoInstructionTitle\ndetection.ts]
    D --> E{Switch on title}

    E -->|PlacePerpOrder / PlacePerpOrder2| F[PlacePerpOrder*DetailsCard]
    E -->|PlaceSpotOrder| G[PlaceSpotOrderDetailsCard]
    E -->|ChangePerpMarketParams| H[ChangePerpMarketParamsDetailsCard]
    E -->|AddSpotMarket| I[AddSpotMarketDetailsCard]
    E -->|Other Mango variants| J[Generic*DetailsCard]
    E -->|Unknown| K[Raw InstructionCard]

    F --> L[getPerpMarketFromInstruction\nmarket.ts]
    G --> M[getSpotMarketFromInstruction\nmarket.ts]
    H --> L

    L --> N[useMangoPerpMarket hook\nuse-mango-market.ts]
    M --> O[useMangoSpotMarket hook\nuse-mango-market.ts]

    N --> P[getPerpMarketFromPerpMarketConfig\nmarket.ts]
    O --> Q[getSpotMarketFromSpotMarketConfig\nmarket.ts]

    P --> R[(accountInfoCache\nmodule-level)]
    R -->|cache miss| S[Connection.getAccountInfo RPC]
    Q --> T[Market.load RPC\nno cache]

    subgraph decoder-mango package
        D
        L
        M
        P
        Q
        R
    end
Loading

Reviews (9): Last reviewed commit: "feat: improve handling cached exceptions" | Re-trigger Greptile

Comment thread packages/decoder-mango/src/market.ts Outdated
Comment thread packages/decoder-mango/src/market.ts Outdated
@rogaldh rogaldh changed the title Feat/extract mango client feat(mango): extract mango client Jun 15, 2026
@rogaldh rogaldh requested a review from askov June 15, 2026 17:20
@rogaldh

rogaldh commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile-apps issues were addressed

Comment thread packages/decoder-mango/src/market.ts
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