Skip to content

feat: Mezo Lens integration (Stack / Borrow / Save / Lock / Swap / Liquidity) + chain-aware EDB bridge#21

Open
Timidan wants to merge 18 commits into
masterfrom
feat/mezo
Open

feat: Mezo Lens integration (Stack / Borrow / Save / Lock / Swap / Liquidity) + chain-aware EDB bridge#21
Timidan wants to merge 18 commits into
masterfrom
feat/mezo

Conversation

@Timidan
Copy link
Copy Markdown
Owner

@Timidan Timidan commented May 24, 2026

Summary

  • Adds Mezo Lens — six purpose-built tabs (Stack, Borrow, Save, Lock, Swap, Liquidity) that let a user preview every leg of a Mezo position before signing. All flows run through atomic eth_simulateV1 bundles so the user sees the resulting trove, ICR, LP tokens, swap quote, etc. before any wallet write.
  • Chain-aware EDB bridge routing — the dev/Vercel proxy inspects chainId per request and forwards Mezo (31611/31612) to a dedicated bridge while keeping every other chain on the existing bridge. Two new env vars (EDB_DEFAULT_BRIDGE_URL, EDB_MEZO_BRIDGE_URL) make the split explicit.
  • Simulation trace upgrades — native token symbol now reflects the replayed chain (BTC on Mezo, not "ETH"), Blockscout-vs-Sourcify badge renders correctly, native movements collapse to net-per-address, event dedup honors call-frame + emission index so legitimate identical logs from a bulk-transfer loop stay distinct.
  • Mezo bridge (edb submodule, separate PR) — stateful MEZO precompile inspector tracks balance deltas + allowances so contracts using before/after balance math (Wormhole NTT, Aerodrome) replay correctly. Chain metadata registered for both networks.

What ships in each commit

  • e27f0e7 chain config (registry, contracts, CSP, env docs)
  • 1b2148a chain-aware bridge routing (api/edbShared.ts, vite proxy, Vercel proxy)
  • 632f87c Mezo Lens app (46 files, all under src/components/integrations/mezo/)
  • 1bb6c4e trace + Blockscout badge + token movement net-per-address
  • d5407dd SimulationHistory IDB v2 → v3 migration
  • 05a7981 LI.FI Earn drive-by type tightening
  • dac6ec8 nav, search, og tags, logos, public mezo-lab
  • d685a4a edb submodule pointer bump

Test plan

  • Vercel preview deploys from feat/mezo; /integrations/mezo loads, wallet switch targets chain 31611
  • Stack: 0.04 BTC + 2000 MUSD + 50 sMUSD + 50 MEZO lock → all 5 plan steps green; "you'll deposit / you'll receive" shows BTC + MEZO out, sMUSD + veMEZO in
  • Borrow: open a standalone trove → ICR + liquidation price in receive panel
  • Save: deposit existing MUSD into sMUSD → sMUSD in receive
  • Lock: lock MEZO standalone → veMEZO NFT in receive (14-day default avoids week-boundary edge case)
  • Swap: quote BTC → MUSD on volatile pool, slippage selector flows to signing min-out (no 0-min-out signing)
  • Liquidity: add BTC/MUSD volatile pair, "you'll receive" shows LP tokens + pool share
  • Transaction Utils → Simulation (EDB) → replay Mezo mainnet 0x75b67f493f482ac707309bd55c0e4979e3fc1ca69d13be6b1889b27846f7351f:
    • SUCCESS status
    • Asset column shows "BTC" not "ETH"
    • Contracts panel shows "BLOCKSCOUT" badges
    • Events tab includes the MEZO precompile Transfer event
    • No duplicate events
    • Native token movements collapse to net-per-address
  • Replay an Ethereum mainnet tx through the same UI to confirm non-Mezo routing still works
  • Vercel env vars set per scope:
    • EDB_API_KEY (production, preview, development)
    • EDB_DEFAULT_BRIDGE_URL=https://edb.hexkit.tech (all scopes)
    • EDB_MEZO_BRIDGE_URL=https://edb.hexkit.tech/mezo (all scopes)
    • ETHERSCAN_API_KEY (all scopes)
    • VITE_WALLETCONNECT_PROJECT_ID (all scopes)

Companion PR

  • Timidan/edb-extendedfeat/mezo branch — Mezo chain_metadata + stateful precompile inspector + source-provider tagging

Timidan added 9 commits May 23, 2026 05:37
…ute handling

- Added intentsApi.ts for handling intents-related API calls.
- Introduced useIntentOrderStatus.ts for managing intent order status with React Query.
- Created withdrawComposerRoute.ts to manage the withdrawal process through composer routes.
- Enhanced error handling and user feedback during the withdrawal process.
- Updated earnApi.ts to separate quote URL building from fetching logic.
- Improved type definitions in types.ts and added nullable symbol handling for EarnToken.
- Implemented nonce generation for unique order identification in nonce.ts.
- Added deadline management for orders in deadlines.ts.
- Created standardOrder.ts for building and managing standard order structures.
- Updated Vercel and Vite configurations to support new API endpoints.
- Add canonical contract addresses (MUSD, MEZO precompile, BTC ERC-20 surface,
  sMUSD, BorrowerOperations, TroveManager, SortedTroves, HintHelpers, PriceFeed,
  veMEZO, Voter, PoolFactory, Router, plus pool helpers)
- Extend chain registry with both networks (native BTC, 18 decimals)
- Extend CSP connect-src to allow Mezo public RPCs + Blockscout APIs
- Document EDB_DEFAULT_BRIDGE_URL and EDB_MEZO_BRIDGE_URL env vars
The dev/Vercel proxy now inspects the chainId on every request (from the
?chainId query param or the JSON body) and forwards to a Mezo bridge for
chain 31611/31612 vs the default bridge for everything else. Two new env
vars let operators point each side at a different URL; without them, the
proxy auto-derives the Mezo URL by appending /mezo to EDB_BRIDGE_URL.

- New api/edbShared.ts module exports resolveEdbBridgeUrl(),
  extractChainIdFromRawJsonBody(), and ETHERSCAN key injection helpers
- vite.config.ts dev proxy uses the shared helpers; the old static target
  is replaced with a per-request configure() that picks the bridge live
- api/edb-proxy.ts (Vercel) mirrors the dev path so previews route the
  same way as production
- vercel.json adds the /mezo Blockscout rewrite alongside the testnet one
- DebugBridgeService and useDebugPrep pass the chainId through to the
  bridge calls
…uidity)

End-to-end integration for Mezo Testnet that lets a user preview every leg
of a Mezo position before signing. Six tabs share a common workbench:
input + atomic-bundle eth_simulateV1 preview + step-by-step pipeline.

Highlights:

- sim/ — eth_simulateV1 client with per-leg gas budgeting (5M for openTrove,
  2M for veMEZO.createLock and Router.addLiquidity, 1M+ default split for
  the rest); bundle builders for each tab; viewcall encoders/decoders;
  unified SimulationResult shape with trove / swap / liquidity / veMEZO
  outcome fields
- pipeline/ — wagmi-backed execution after sim succeeds; per-leg status
  timeline with retry; legHandlers translate MezoLegSpec to wagmi writes
- preview/ — DepositReceiveCards / DecodedLegList / TokensMovedPanel;
  PreviewPanel composes them and renders the atomic-flow summary
- tabs/ — six tabs, each fronting one bundle builder. Common UX:
  AssetInput with `intent="deposit"|"receive"`, pool / slippage controls,
  pre-sim ICR validation, post-sim "you'll deposit / you'll receive" cards
- abi/ — minimal ABI fragments for MUSD, sMUSD, BorrowerOperations,
  TroveManager, PriceFeed, HintHelpers, SortedTroves, VotingEscrow,
  Voter, Gauge, Pool, Router (4-field Aerodrome routes), PoolFactory
- hooks/ — useFindPool, useReserves, usePriceFeed via wagmi
- components/ — AssetInput, AssetIcon, TabBar, MezoTopBar, WorkbenchBody,
  FlowRibbon, SectionEyebrow, Term (glossary popovers)
- ChainGate gates the whole page on wallet + chain 31611
- copy.ts holds every user-facing string (no jargon)
- MezoLensPage routes between tabs and renders PositionsSidebar +
  HonestyFooter alongside
The simulation-results renderer now adapts to the replayed chain instead
of hardcoding Ethereum assumptions, and the Contracts panel honors the
provider that actually returned the source.

- edbTraceConverter accepts optional nativeSymbol / nativeName so native
  movements render as BTC on Mezo (chain id 31611/31612) instead of ETH
- Event dedup key now folds in the call-frame id + emission index so
  legitimate identical logs from a loop (bulk Transfer airdrops, etc.)
  don't collapse to a single row; same fix mirrored in the engine renderer
- Native token movements collapse to net-per-address rows so a multi-hop
  value-passing tx surfaces one debit + one credit instead of every
  intermediate frame
- Contracts panel displays a "BLOCKSCOUT" / "SOURCIFY" badge based on the
  explicit sourceProvider tag the engine attaches to each artifact, with
  bridge compaction preserving the label end-to-end
- Token metadata cache seeds MEZO, BTC, MUSD, sMUSD so a synthetic
  MEZO precompile Transfer renders as "MEZO" instead of "MEZOCaller"
- Bridge response normalization now plumbs sourceProvider through
  artifactFetching, responseParsing, bridgeSimulation, and the trace
  compactor scripts
Idempotent onupgradeneeded migration ensures the meta + simulations
stores have every needed index (timestamp, status, networkId,
contractAddress, from, to, functionName) on both fresh installs and
upgrades from v1/v2 without dropping existing entries.

- Adds version-change handler so a second tab triggers a clean reopen
- Refines SimulationHistoryPage retry path so a stale DB connection no
  longer wedges the "Failed to load" state
Drive-by cleanup encountered while building Mezo Lens — the touched
files are unrelated paths that benefited from minor type tightening
and removal of dead conditional branches. Behavior unchanged.
- Add Mezo Lens entries to top nav, mobile drawer, integrations hub, and
  universal search so the new flow is discoverable
- Route meta tags for /integrations/mezo (title, description, og)
- Mezo logo + wordmark assets
- public/mezo-lab/ standalone preview page used during prototyping
- README documents the new integration
- Drop a trailing-newline-only .gitignore tweak
Pulls in chain metadata for Mezo Testnet + Mainnet, the stateful
MEZO precompile inspector (balanceOf delta tracking + allowance
defaults), source-provider tagging on artifacts, event dedup,
and synthetic precompile log emission. See edb commit f280d32.
Copilot AI review requested due to automatic review settings May 24, 2026 20:27
@vercel
Copy link
Copy Markdown

vercel Bot commented May 24, 2026

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

Project Deployment Actions Updated (UTC)
web3-toolkit Ready Ready Preview, Comment May 25, 2026 12:47am

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d685a4a382

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +244 to +248
].filter((event, index, allEvents) => {
const key = eventKey(event, index);
return allEvents.findIndex((candidate, candidateIndex) =>
eventKey(candidate, candidateIndex) === key
) === index;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve duplicate logs when merging event sources

The sourceEvents dedup step collapses events using only address|topics|data, so two real logs with identical payloads (e.g., repeated Transfer emissions in loops or across call frames) are merged into one. This regresses event accuracy in the Events tab by undercounting legitimate emissions and hides execution details users rely on for simulation review. Include a stable per-emission discriminator (such as call-frame id + in-frame index or txHash/logIndex when present) in the key to avoid dropping valid duplicates.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a Mezo-specific “Lens” integration (Stack/Borrow/Save/Lock/Swap/Liquidity) with atomic eth_simulateV1 bundle previews, and updates the EDB/proxy + trace parsing pipeline to be chain-aware (notably for Mezo mainnet/testnet) with improved source-provider tagging, event handling, and native asset rendering.

Changes:

  • Add Mezo Lens UI + simulation bundle builder infrastructure for multi-step position previews.
  • Route EDB bridge requests to different upstream bridges based on chainId (Mezo vs non-Mezo), and extend Blockscout/Sourcify/Etherscan source-provider handling.
  • Improve trace parsing/output (native symbol/name, event dedupe strategy, net native movements per address) and migrate SimulationHistory IDB schema v2 → v3.

Reviewed changes

Copilot reviewed 120 out of 123 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
vercel.json Adds Mezo Blockscout proxy routes and LI.FI intents API routing on Vercel.
src/utils/transaction-simulation/responseParsing.ts Improves source provider detection for contract artifacts (explicit provider fields + meta fallbacks).
src/utils/transaction-simulation/bridgeSimulation.ts Preserves sourceProvider when inlining artifacts from bridge responses.
src/utils/transaction-simulation/artifactFetching.ts Adds Mezo chainIds to Blockscout instance mapping.
src/utils/tokenMovements.ts Seeds token metadata for Mezo assets (MEZO/BTC/MUSD/sMUSD).
src/utils/simulationArtifacts.ts Makes EDB trace conversion chain-aware for native asset name/symbol.
src/utils/resolver/sources/blockscout.ts Makes Blockscout URL construction robust across /api, /api/v2, and proxy bases; adds Mezo proxy mapping.
src/utils/edbTraceConverter.ts Adds native asset overrides, event dedupe keyed by call-frame + emission index, and collapses native movements to net deltas per address.
src/services/SimulationHistoryService.ts Bumps IndexedDB version to v3, hardens upgrade/index creation, and improves filtering null-safety.
src/services/DebugBridgeService.ts Updates debug bridge behavior to support new chain-aware routing/simulation behavior.
src/lib/intents/standardOrder.ts Adds intent order modeling utilities for LI.FI intents.
src/lib/intents/nonce.ts Adds nonce helpers for intent signing/validation.
src/lib/intents/eip7930.ts Adds EIP-7930 related helpers for intent formats.
src/lib/intents/deadlines.ts Adds deadline utilities for intent payloads.
src/lib/intents/contracts.ts Adds contract-related helpers for intents.
src/lib/intents/addressBytes.ts Adds address/bytes encoding helpers for intents.
src/hooks/useUniversalSearch.ts Extends search to include Mezo-related navigation/content updates.
src/contexts/debug/useDebugPrep.ts Updates debug preparation flow to support new simulation/routing behavior.
src/components/SimulationHistoryPage.tsx Updates simulation history UI to reflect IDB schema changes and new fields.
src/components/simulation-results/useSimulationPageState.ts Updates simulation page state management for new artifacts/trace behavior.
src/components/simulation-results/SummaryTab.tsx Updates summary rendering for revised asset movement/native symbol behavior.
src/components/simulation-results/EventsTab.tsx Updates events table behavior consistent with improved dedupe/topics handling.
src/components/simulation-results/eventDecoder.ts Updates event decoding pipeline to align with new trace/artifact fields.
src/components/simulation-results/ContractsTab.tsx Updates contract verification/source-provider badges (Blockscout vs Sourcify vs Etherscan).
src/components/shared/RouteMetaTags.tsx Adds/updates OG/meta tags for Mezo integration pages.
src/components/Navigation.tsx Adds Mezo navigation entries and related routing.
src/components/MobileDrawer.tsx Ensures Mezo navigation works in mobile drawer.
src/components/integrations/mezo/tabs/SaveTab.tsx Adds Mezo Lens “Save” tab UI and simulation wiring.
src/components/integrations/mezo/TabBar.tsx Adds Mezo Lens tab navigation component.
src/components/integrations/mezo/sim/views.ts Adds read-only view calls used in Mezo bundle simulations.
src/components/integrations/mezo/sim/types.ts Adds shared types for Mezo simulation legs/views/results.
src/components/integrations/mezo/sim/ethSimulateV1.ts Implements atomic bundle simulation builder for Mezo flows.
src/components/integrations/mezo/sim/bundles/swap.ts Adds swap bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/bundles/stack.ts Adds stack bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/bundles/save.ts Adds save bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/bundles/lock.ts Adds lock bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/bundles/liquidity.ts Adds liquidity bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/bundles/borrow.ts Adds borrow bundle legs/views for Mezo Lens.
src/components/integrations/mezo/sim/buildCalls.ts Adds shared call construction helpers for Mezo bundles.
src/components/integrations/mezo/preview/PreviewPanel.tsx Adds Mezo plan preview panel for all bundle legs.
src/components/integrations/mezo/preview/DecodedLegList.tsx Adds decoded leg rendering for preview UX.
src/components/integrations/mezo/PositionsSidebar.tsx Adds positions sidebar for Mezo Lens layouts.
src/components/integrations/mezo/pipeline/useMezoLegPipeline.ts Adds leg pipeline orchestration for Mezo plan building/simulation.
src/components/integrations/mezo/pipeline/MezoLegTimeline.tsx Adds timeline UI for leg execution/simulation steps.
src/components/integrations/mezo/pipeline/mezoLegs.ts Defines Mezo leg models and composition rules.
src/components/integrations/mezo/pipeline/legHandlers.ts Implements per-leg decoding/formatting/handling logic.
src/components/integrations/mezo/MezoLensPage.tsx Adds Mezo Lens top-level page routing + tab layout.
src/components/integrations/mezo/index.ts Exposes Mezo integration entrypoint(s).
src/components/integrations/mezo/hooks/useReserves.ts Adds Mezo pool reserve querying hook(s).
src/components/integrations/mezo/hooks/usePriceFeed.ts Adds Mezo price feed querying hook(s).
src/components/integrations/mezo/hooks/useFindPool.ts Adds Mezo pool discovery hook(s).
src/components/integrations/mezo/HonestyFooter.tsx Adds Mezo Lens disclosure/footer component.
src/components/integrations/mezo/glossary.ts Adds Mezo glossary terms for UI help text.
src/components/integrations/mezo/copy.ts Adds Mezo-specific copy strings.
src/components/integrations/mezo/constants.ts Adds Mezo chain constants/addresses for simulations.
src/components/integrations/mezo/components/WorkbenchBody.tsx Adds shared layout for Mezo Lens workbench.
src/components/integrations/mezo/components/Term.tsx Adds term/help UI component(s) for Mezo Lens.
src/components/integrations/mezo/components/SectionEyebrow.tsx Adds section heading UI component(s).
src/components/integrations/mezo/components/MezoTopBar.tsx Adds Mezo Lens top bar UI.
src/components/integrations/mezo/components/FlowRibbon.tsx Adds flow/status ribbon UI for Mezo Lens.
src/components/integrations/mezo/components/AssetInput.tsx Adds Mezo-specific asset input component(s).
src/components/integrations/mezo/ChainGate.tsx Gates Mezo Lens UX by selected chain.
src/components/integrations/lifi-earn/VaultList.tsx Updates LI.FI Earn UI to support intents-driven behaviors.
src/components/integrations/lifi-earn/useIntentOrderStatus.ts Adds hook for tracking intent order status.
src/components/integrations/lifi-earn/types.ts Tightens types related to LI.FI Earn / intents.
src/components/integrations/lifi-earn/txUtils.ts Updates tx utils for intent-based flows.
src/components/integrations/lifi-earn/TokenIcon.tsx Updates token icon handling for Earn/intents flows.
src/components/integrations/lifi-earn/intentsApi.ts Adds client API wrapper for intents endpoint.
src/components/integrations/lifi-earn/hooks/useWithdrawQuote.ts Updates withdraw quoting to support intents semantics.
src/components/integrations/lifi-earn/earnApi.ts Updates Earn API client behavior/types.
src/components/integrations/lifi-earn/destinationTokenOptions.ts Adds destination token option logic for Earn flows.
src/components/integrations/lifi-earn/concierge/VaultRecommendations.tsx Updates concierge recommendations for intents support.
src/components/integrations/lifi-earn/concierge/types.ts Updates concierge types to reflect new intent structures.
src/components/integrations/lifi-earn/concierge/LlmErrorAlert.tsx Updates LLM error UX for concierge flows.
src/components/integrations/lifi-earn/concierge/intent/intentLegs.ts Adds intent-based leg generation / degradation logic.
src/components/integrations/lifi-earn/concierge/intent/hooks/useVaultsByIntent.ts Updates vault fetching to support intents.
src/components/integrations/lifi-earn/concierge/intent/hooks/useIntentRecommendation.ts Updates intent recommendation logic.
src/components/integrations/lifi-earn/concierge/IdleSweepPanel.tsx Updates Idle Sweep UI for updated flows.
src/components/integrations/lifi-earn/concierge/FlowDiagram.tsx Updates concierge flow diagram for new leg types.
src/components/integrations/lifi-earn/concierge/fallback.ts Updates concierge fallback behavior with intents integration.
src/components/integrations/IntegrationsHub.tsx Adds Mezo integration entry to the integrations hub.
src/components/ExecutionStackTrace.tsx Updates execution stack trace UI consistent with new simulation artifacts.
src/chains/registry.ts Registers Mezo chain metadata (native currency symbol/name) and related chain config.
scripts/trace-processing.mjs Updates trace processing script for new trace/artifact behaviors.
scripts/simulator-bridge.mjs Updates simulator bridge script to support chain-aware routing.
scripts/artifact-compactor.mjs Updates artifact compaction script for new artifact shapes/source providers.
README.md Documents new env vars, Mezo integration, and updated simulation/bridge behavior.
public/logos/mezo.svg Adds Mezo logo asset.
public/logos/mezo-wordmark.svg Adds Mezo wordmark asset.
index.html Updates metadata/links for Mezo and updated routing.
data/mezoContracts.ts Adds Mezo contract registry/constants used by the Lens.
api/lifi-intents.ts Adds serverless API proxy for LI.FI intents (including rate limiting).
api/edbShared.ts Adds shared chainId extraction and bridge URL resolution helpers.
api/edb-proxy.ts Implements chain-aware EDB bridge routing and streaming/non-streaming behaviors.
.gitignore Updates ignores for new artifacts/assets.
.env.example Documents new env vars (EDB_DEFAULT_BRIDGE_URL, EDB_MEZO_BRIDGE_URL, etc.).
.codegraph/.gitignore Adds ignore rules for codegraph outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread api/edb-proxy.ts
Comment on lines 174 to 180
if (isSSE) {
// Abort upstream when client disconnects
req.on("close", () => controller.abort());
} else {
// Regular requests get a hard timeout
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
req.on("close", () => clearTimeout(timer));
timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
}
Comment on lines +92 to +100
const remainingBudget =
BUNDLE_GAS_BUDGET > reservedGas ? BUNDLE_GAS_BUDGET - reservedGas : 0n;
const share =
callsNeedingDefault > 0n ? remainingBudget / callsNeedingDefault : 0n;
const perCallDefault = share < MIN_CALL_GAS ? MIN_CALL_GAS : share;
const defaultGas = `0x${perCallDefault.toString(16)}` as Hex;
const callsWithGas: SimCall[] = blockStateCall.calls.map((call) =>
call.gas ? call : { ...call, gas: defaultGas },
);
Comment thread api/lifi-intents.ts
Comment on lines +32 to +52
// Best-effort per-IP rate limit (resets on cold start). Friction, not auth.
const RATE_LIMIT_WINDOW_MS = 60_000;
const RATE_LIMIT_MAX = 120;
const rateBuckets = new Map<string, { count: number; resetAt: number }>();

function rateLimit(req: VercelRequest): boolean {
const fwd = req.headers["x-forwarded-for"];
const ip = (Array.isArray(fwd) ? fwd[0] : fwd ?? req.socket?.remoteAddress ?? "")
.toString()
.split(",")[0]
.trim();
if (!ip) return true; // can't identify caller — let it through, upstream will protect
const now = Date.now();
const slot = rateBuckets.get(ip);
if (!slot || slot.resetAt < now) {
rateBuckets.set(ip, { count: 1, resetAt: now + RATE_LIMIT_WINDOW_MS });
return true;
}
if (slot.count >= RATE_LIMIT_MAX) return false;
slot.count += 1;
return true;
Mezo's Router only exposes swapExactTokensForTokens and addLiquidity —
there is no ETH-native variant because BTC on Mezo is itself an ERC-20
surface (0x7b7C…0000). The swap and liquidity bundles already always
use the standard token-token entrypoints; the routerSwapEthIn /
routerSwapEthOut / routerAddLiquidityEth leg types were dead and broke
the strict wagmi v2 typing on Vercel.

Removes those leg types from MezoLegSpec and their orphan branches in
buildCalls.ts, legHandlers.ts, decodeResults.ts, and the swap/liquidity
type-guards. Casts the routerSwap routes arg to `never` so wagmi's
strict `as const` ABI inference stops widening to the runtime tuple.
The SimulationResultsPage Summary header (Value + Tx Fee fields) was
rendering "ETH" for every replay regardless of chain. A Mezo Mainnet
tx with 0.000001 BTC value showed "0.000001 ETH" + "0 ETH" because
formatEth + calculateTxFee hardcoded the suffix and computeGasValues
seeded txFee = "0 ETH" literal.

- formatters.formatEth(wei, symbol = "ETH") + calculateTxFee(...,
  symbol = "ETH") now accept the native symbol with a back-compat
  default so existing call sites keep working.
- gasHelpers.computeGasValues(..., nativeSymbol = "ETH") threads it
  into the txFee placeholder.
- SimulationResultsPage resolves nativeSymbol via getChainById(
  result.chainId ?? contractContext.networkId)?.nativeCurrency.symbol
  and forwards it to both computeGasValues and TransactionSummary.
- TransactionSummary adds an optional nativeSymbol prop and uses it
  in the Value field rendering.

NATIVE TOKEN CHANGE table was already chain-aware via the trace
converter; this just brings the Summary header into line.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 124 out of 127 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

src/services/SimulationHistoryService.ts:252

  • request.onblocked immediately rejects initPromise, but the open request may later unblock and still fire onsuccess, setting this.db after the promise has rejected. That can leave the service in a partially-initialized state and force callers into error handling even though the DB eventually opened. Consider tracking a “blocked” flag to ignore a later onsuccess, or (preferably) surface a blocked state to the UI while keeping the init promise pending until the upgrade either succeeds or errors.

Comment on lines +240 to +249
const sourceEvents = [
...traceEvents,
...rawTraceEvents,
...(Array.isArray(artifacts?.events) ? artifacts.events : []),
].filter((event, index, allEvents) => {
const key = eventKey(event, index);
return allEvents.findIndex((candidate, candidateIndex) =>
eventKey(candidate, candidateIndex) === key
) === index;
});
Comment thread api/edb-proxy.ts
Comment on lines 174 to 178
if (isSSE) {
// Abort upstream when client disconnects
req.on("close", () => controller.abort());
} else {
// Regular requests get a hard timeout
Comment on lines +25 to +29
const tokenA = toMezoPoolTokenAddress(p.tokenA);
const tokenB = toMezoPoolTokenAddress(p.tokenB);

if (sameAddress(tokenA, tokenB)) {
throw new Error("buildLiquidityBundle: tokenA and tokenB must differ");
Wire MEZO, BTC, and MUSD icons through CoinGecko so the trace ASSET
column and Mezo Lens AssetIcon stop falling back to a generic dot.
Covers both the Mezo precompile/surface addresses and the Ethereum
NTT bridge twins. sMUSD has no public CDN entry so it keeps a
bundled SVG.
veBTC is the base ve-token of Mezo's Aerodrome v2 fork; add it as
an AssetSymbol with a local orange glyph + glossary entry. Bridged
USDC/USDT are indexed by CoinGecko, so route them through the same
CDN map as MUSD/MEZO. Seed metadata so traces surface the correct
symbol without an RPC roundtrip.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 125 out of 129 changed files in this pull request and generated 4 comments.

Comment on lines +25 to +54
const tokenA = toMezoPoolTokenAddress(p.tokenA);
const tokenB = toMezoPoolTokenAddress(p.tokenB);

if (sameAddress(tokenA, tokenB)) {
throw new Error("buildLiquidityBundle: tokenA and tokenB must differ");
}

// Mezo's Router has no `addLiquidityETH` — BTC on Mezo is the ERC-20
// surface at 0x7b7C…0000, so we always approve+addLiquidity. Same
// pattern as the swap builder.
const legs: MezoLegSpec[] = [
{
type: "approveErc20",
token: p.tokenA,
spender: MEZO_CONTRACTS.Router,
amount: p.amountADesired,
tokenLabel: tokenLabel(p.tokenA),
},
{
type: "approveErc20",
token: p.tokenB,
spender: MEZO_CONTRACTS.Router,
amount: p.amountBDesired,
tokenLabel: tokenLabel(p.tokenB),
},
{
type: "routerAddLiquidity",
tokenA: p.tokenA,
tokenB: p.tokenB,
stable: p.stable,
Comment on lines +240 to +249
const sourceEvents = [
...traceEvents,
...rawTraceEvents,
...(Array.isArray(artifacts?.events) ? artifacts.events : []),
].filter((event, index, allEvents) => {
const key = eventKey(event, index);
return allEvents.findIndex((candidate, candidateIndex) =>
eventKey(candidate, candidateIndex) === key
) === index;
});
Comment thread api/edb-proxy.ts
Comment on lines +156 to +159
const parsedQueryChainId = queryChainId ? Number(queryChainId) : null;
const chainId = Number.isInteger(parsedQueryChainId)
? parsedQueryChainId
: extractChainIdFromRawJsonBody(rawBody, req.headers["content-type"]);
Comment thread src/lib/intents/nonce.ts
Comment on lines +10 to +14
export function nextOrderNonce(): bigint {
counter = (counter + 1) & 0xffff;
const ts = BigInt(Date.now());
const rand = BigInt(Math.floor(Math.random() * 0xffffffff));
return (ts << (RAND_BITS + COUNTER_BITS)) | (rand << COUNTER_BITS) | BigInt(counter);
Three Stack-tab fixes that surface during recording:

1. Side-rail Trove and veMEZO sections were placeholder text. Wire
   them to TroveManager.Troves and veMEZO.locked so they reflect the
   wallet's actual on-chain position with 6s refetch.

2. If the user already has an active trove (status === 1), the Stack
   bundle now omits the openTrove leg instead of replaying it. Saves
   the user from a guaranteed revert when they re-run Build Stack.

3. Pipeline executeAll now skips legs already in "confirmed" state so
   clicking Build Stack again resumes from the first non-confirmed
   step. Pair with a 90s timeout on the wagmi receipt wait so a stuck
   poll can't halt the whole stack indefinitely.
Side-rail Trove row is now a button that opens a Manage Trove dialog
with two modes:

- Adjust — single signed adjustTrove call combining BTC delta
  (+ add / − withdraw) and MUSD delta (+ borrow / − repay). When
  repaying, the bundle prepends a MUSD approve so BorrowerOperations
  can pull the repayment.

- Close — approve current debt + closeTrove. Burns the trove,
  refunds the 200 MUSD gas comp, returns all collateral. Blocks the
  button when wallet MUSD is short of the debt.

Both flows reuse useMezoBundleSimulation for the live preview and
useMezoLegPipeline for execution, matching the rest of Mezo Lens.
Implement the previously-stubbed repayMUSD and closeTrove handlers.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Execution handlers were wired in the previous commit but the
simulation-side encoder still threw "v2 leg not implemented",
so the Manage Trove preview failed before the user could sign.
Encode both as plain BorrowerOperations calls; the trove dialog
now runs through the sim path cleanly.
Liquity-fork closeTrove pulls (debt - GAS_COMPENSATION) from the
user's wallet. The 200 MUSD gas comp lives in the protocol's Gas
Pool throughout the trove's life and is burned automatically on
clean close — never the borrower's cost. The earlier approve sized
to the full debt and the dialog warning said the user was "short by"
the gas comp amount, both wrong.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Side-rail now surfaces every position (Trove, veMEZO, sMUSD savings,
MUSD/BTC LP) and each row opens a dedicated Manage dialog. When a
position is empty, the row shows a "Deposit →" / "Add →" prompt so
the user can open one without leaving the rail.

- ManageLockDialog: top up MEZO into the existing veMEZO position
  (approve + increaseAmount) or extend the unlock time. Extend passes
  a relative duration from now (Aerodrome VotingEscrow semantics),
  not an absolute timestamp.
- ManageSavingsDialog: deposit MUSD into sMUSD or withdraw MUSD from
  the vault (the vault burns the matching sMUSD shares).
- ManageLiquidityDialog: add MUSD/BTC liquidity or remove LP shares.
  Carries a testnet banner — slippage min is 0 and the dialog should
  not ship to mainnet without slippage controls.

Supporting work:
- Wire sMusdWithdraw + routerRemoveLiquidity (sim encoder + exec
  handler + decoded summary + Router ABI entry).
- Shared BalanceDeltaPreview surfaces concrete asset deltas (wallet
  BTC / MUSD / sMUSD / MEZO + trove debt/coll + LP + veMEZO lock)
  from the simulation outcome.
- Close-trove approve sized off principal+interestOwed (total debt)
  minus the 200 MUSD gas comp — the protocol's Gas Pool burns the
  comp, the user only pays what they actually borrowed.
- Each dialog resets the pipeline on open and fingerprints legs;
  changing inputs after a partial run can't resume against stale
  specs.
- Implement repayMUSD and closeTrove on both the sim and execution
  sides (were previously v2-stubs).
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.

2 participants