Files
metamask-integration/chain138-snap/TESTING_INSTRUCTIONS.md

14 KiB

Chain 138 Snap Testing Instructions

Date: 2026-01-30
Status: Built and ready for testing


Prerequisites

  1. MetaMask Flask (development version of MetaMask)

  2. Snap Development Server Running

    cd metamask-integration/chain138-snap
    pnpm run start
    

    (Or use yarn start if you prefer Yarn; see PACKAGE_MANAGER.md.)

  3. For full E2E (API-dependent features): Token-aggregation service and companion site env. See E2E Preparation.


E2E Preparation

For full end-to-end success (market data, bridge routes, swap quotes), complete these before running the checklist:

  1. Start token-aggregation (local or use a deployed URL).

    • See E2E_PREPARATION.md for steps (database, env, npm run dev or Docker).
    • Note the API base URL (e.g. http://localhost:3000 for local).
  2. Configure companion site env.

    • In packages/site, copy .env.production.dist to .env or .env.production.
    • Set GATSBY_SNAP_API_BASE_URL to the token-aggregation base URL (e.g. http://localhost:3000).
    • Restart the site if it is already running so the variable is picked up.
  3. Run Snap + site: From repo root, pnpm run start (serves site and Snap on http://localhost:8000).

  4. Install MetaMask Flask and use the checklist in E2E testing checklist (MetaMask Flask) below.

Automated E2E (optional): Run pnpm run test:e2e to start the dev server (if needed) and run Playwright tests against the companion site. See E2E_PREPARATION.md. This does not drive MetaMask Flask.


Testing Steps

1. Install the Snap

  1. Open browser with MetaMask Flask installed
  2. Navigate to http://localhost:8000
  3. You should see the Snap installation page
  4. Click "Connect" to install the Snap
  5. MetaMask Flask will prompt for permissions - approve them

2. Test RPC Methods

Once installed, you can test the Snap's RPC methods:

Test get_networks

Pass apiBaseUrl (your token-aggregation service URL). Open browser console:

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_networks',
      params: { apiBaseUrl: 'https://your-token-aggregation-api.com' },
    },
  },
});

Expected response: { version, networks: [ ... ] } with full EIP-3085 params for Chain 138, Ethereum Mainnet, and ALL Mainnet.

Optional: You can pass networksUrl instead of (or without) apiBaseUrl to fetch networks from a JSON URL (e.g. GitHub raw):

params: { networksUrl: 'https://raw.githubusercontent.com/org/repo/main/networks.json' }

Test get_chain138_config

Requires apiBaseUrl. Returns Chain 138 config from the API:

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_chain138_config',
      params: { apiBaseUrl: 'https://your-token-aggregation-api.com' },
    },
  },
});

Expected response: Chain 138 params (chainId, chainName, rpcUrls, nativeCurrency, blockExplorerUrls, oracles).

Optional: Pass networksUrl instead of apiBaseUrl to use a remote networks JSON.

Test get_chain138_market_chains

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_chain138_market_chains',
      params: {
        apiBaseUrl: 'https://your-token-aggregation-api.com', // When deployed
      },
    },
  },
});

Expected response:

[
  {
    "chainId": 138,
    "name": "DeFi Oracle Meta Mainnet",
    "nativeToken": { "symbol": "ETH", "decimals": 18 },
    "rpcUrl": "https://rpc-http-pub.d-bis.org",
    "explorerUrl": "https://explorer.d-bis.org"
  }
]

Test get_market_summary

Requires apiBaseUrl (token-aggregation service URL). Fetches tokens with optional market data (price, volume) for a chain. Optional chainId (default 138).

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_market_summary',
      params: {
        apiBaseUrl: 'https://your-token-aggregation-api.com',
        chainId: 138, // optional, default 138
      },
    },
  },
});

Expected response: { tokens: [ { symbol, name, address, market?: { priceUsd, volume24h } } ] } or { error, tokens: [] } on failure.

Test show_market_data

Requires apiBaseUrl. Opens a Snap dialog listing token symbols and USD prices from the token-aggregation API.

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'show_market_data',
      params: {
        apiBaseUrl: 'https://your-token-aggregation-api.com',
        chainId: 138, // optional
      },
    },
  },
});

Expected: A MetaMask dialog showing "Market data (Chain 138)" and token lines with prices. Without apiBaseUrl, the Snap shows an alert asking to pass it.

Test get_token_list and get_token_list_url

With apiBaseUrl: same pattern as above; the Snap calls ${apiBaseUrl}/api/v1/report/token-list (optional chainId in params).
Optional: Pass tokenListUrl to fetch the token list from a JSON URL (e.g. GitHub raw):

params: { tokenListUrl: 'https://raw.githubusercontent.com/org/repo/main/token-list.json', chainId: 138 }

Test get_bridge_routes

Requires apiBaseUrl or bridgeListUrl. Returns CCIP bridge routes (WETH9 / WETH10) and Chain 138 bridge addresses.

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_bridge_routes',
      params: { apiBaseUrl: 'https://your-token-aggregation-api.com' },
    },
  },
});

Expected response: { routes: { weth9: {...}, weth10: {...} }, chain138Bridges: { weth9, weth10 } }.

Optional: Pass bridgeListUrl instead of apiBaseUrl to fetch bridge list from a JSON URL.

Test show_bridge_routes

Requires apiBaseUrl or bridgeListUrl. Opens a Snap dialog with bridge route summary (WETH9/WETH10 → Ethereum Mainnet).

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'show_bridge_routes',
      params: { apiBaseUrl: 'https://your-token-aggregation-api.com' },
    },
  },
});

Test get_swap_quote

Requires apiBaseUrl, tokenIn, tokenOut, amountIn (raw amount string). Optional chainId (default 138).

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'get_swap_quote',
      params: {
        apiBaseUrl: 'https://your-token-aggregation-api.com',
        chainId: 138,
        tokenIn: '0x...',
        tokenOut: '0x...',
        amountIn: '1000000000000000000',
      },
    },
  },
});

Expected response: { amountOut: string | undefined, error?: string, poolAddress?: string }.

Test show_swap_quote

Same params as get_swap_quote. Opens a Snap dialog with the quote (In/Out raw amounts).

Test hello (basic test)

await ethereum.request({
  method: 'wallet_invokeSnap',
  params: {
    snapId: 'local:http://localhost:8000',
    request: {
      method: 'hello',
    },
  },
});

Expected response:

"Hello from Chain 138 Snap!"

E2E testing checklist (MetaMask Flask)

Use this checklist for full manual E2E testing:

  1. Environment

    • MetaMask Flask installed
    • Snap dev server running: pnpm run start (or yarn start) in metamask-integration/chain138-snap
    • For API-dependent tests: token-aggregation service reachable. Set apiBaseUrl to your deployment (e.g. https://your-token-aggregation-api.com) or a local/staging URL (e.g. http://localhost:3000 if running token-aggregation locally).
  2. Install Snap

    • Open http://localhost:8000 in the browser
    • Click Connect and approve Snap installation in MetaMask Flask
  3. RPC methods (apiBaseUrl or optional networksUrl / tokenListUrl / bridgeListUrl)

    • hello
    • get_networks (apiBaseUrl or networksUrl)
    • get_chain138_config (apiBaseUrl or networksUrl)
    • get_chain138_market_chains (apiBaseUrl)
    • get_token_list, get_token_list_url (apiBaseUrl or tokenListUrl; optional chainId)
    • get_oracles (apiBaseUrl), show_dynamic_info (apiBaseUrl or networksUrl/tokenListUrl)
    • get_market_summary, show_market_data (apiBaseUrl; optional chainId)
    • get_bridge_routes, show_bridge_routes (apiBaseUrl or bridgeListUrl)
    • get_swap_quote, show_swap_quote (apiBaseUrl, tokenIn, tokenOut, amountIn; optional chainId)
  4. Companion site cards

    • Set GATSBY_SNAP_API_BASE_URL in .env (copy from .env.production.dist and fill) so the site passes apiBaseUrl to the Snap.
    • Market data: "Show market data" opens Snap dialog; "Fetch market summary" displays tokens/prices below.
    • Bridge: "Show bridge routes" opens Snap dialog with CCIP routes.
    • Swap quote: Enter token In/Out addresses and amount (raw), then "Get quote" shows amountOut; "Show quote in Snap" opens dialog.

Troubleshooting

Snap not appearing in MetaMask Flask

  • Ensure dev server is running on port 8000
  • Check browser console for errors
  • Try refreshing the page

Permission errors

  • Snap needs endowment:network-access for API calls
  • Check snap.manifest.json has correct permissions

API calls failing

  • Ensure apiBaseUrl is provided for methods that need it, or use the optional URL params: networksUrl, tokenListUrl, bridgeListUrl (see RPC method sections above).
  • On the companion site, set GATSBY_SNAP_API_BASE_URL in .env or .env.production (see packages/site/.env.production.dist) so Market data and other API-dependent cards work.
  • Check CORS settings on the token-aggregation API server (it uses cors() by default).
  • Verify API endpoint is accessible (e.g. token-aggregation and, for full testing, bridge/quote endpoints).

Next Steps

After Testing

  1. Fix any bugs found during testing
  2. Submit to Snap directory when ready (see Publishing below)

Publishing

Checklist before publishing:

  • All manual E2E checklist items above completed and passing.
  • Token-aggregation (or your API) deployed and stable; production apiBaseUrl known.
  • Snap built with no errors; prepublishOnly has run (updates manifest shasum).
  • packages/snap/package.json: name and publishConfig (e.g. "access": "public") correct for npm.
  • Integrator docs updated: dApps/site must pass apiBaseUrl (or optional networksUrl / tokenListUrl / bridgeListUrl) for market data, bridge, and swap quote.

Snap directory submission checklist:

  • All manual E2E checklist items in this doc completed and passing.
  • Snap built with pnpm run build; prepublishOnly has run (manifest shasum updated).
  • packages/snap/package.json: name, version, publishConfig (e.g. "access": "public") correct for npm.
  • snap.manifest.json: description, proposedName, initialPermissions match what the Snap uses; source.location.npm will be valid after publish.
  • Snap package published to npm so the manifest npm source is resolvable.
  • MetaMask Snap publishing guide followed: register Snap (package name or bundle URL), description, category, permissions.
  • Integrator docs: dApps/site must pass apiBaseUrl (or optional networksUrl / tokenListUrl / bridgeListUrl) for market data, bridge, swap quote.

Steps to publish to MetaMask Snap directory:

  1. Build: Run pnpm run build (or yarn build; see PACKAGE_MANAGER.md). The prepublishOnly script updates the manifest shasum.
  2. Publish package: Publish the Snap package to npm (e.g. from packages/snap) so source.location.npm in snap.manifest.json is valid.
  3. Snap directory: Follow the MetaMask Snap publishing guide to register the Snap (package name or bundle URL, description, category, permissions).

Production use: After the Snap is published, the production Snap ID will be the npm package name (e.g. npm:snap or npm:@your-org/chain138-snap). For market data, swap quote, and bridge routes to work, dApps (and the companion site) must pass apiBaseUrl (your token-aggregation service URL) or the optional URLs when invoking the Snap. Document this for integrators; see "API calls failing" in Troubleshooting.


Snap Capabilities

Current Features

  • Get Chain 138 configuration (get_chain138_config, get_networks)
  • Token list and token list URL (get_token_list, get_token_list_url)
  • Market data: get_market_summary (tokens with prices), show_market_data (dialog)
  • Oracles config (get_oracles), dynamic info dialog (show_dynamic_info)
  • Bridge routes (get_bridge_routes, show_bridge_routes) when bridge API is available
  • Swap quote (get_swap_quote, show_swap_quote) when quote API is available

Last updated: 2026-02-11
Status: Ready for manual testing in MetaMask Flask; Playwright E2E available via pnpm run test:e2e