14 KiB
Chain 138 Snap Testing Instructions
Date: 2026-01-30
Status: Built and ready for testing
Thorough pre-publish testing: For a complete pass before every npm publish (including all logos/images, every RPC method, companion site, Send page, production-like test, and recommendations), use docs/PRE_PUBLISH_TESTING.md.
Prerequisites
-
MetaMask Flask (development version of MetaMask)
- Download: https://metamask.io/flask/
- Install as separate browser extension (won't conflict with regular MetaMask)
-
Snap Development Server Running
pnpm run start(From the repo root.) (Or use yarn start if you prefer Yarn; see PACKAGE_MANAGER.md.)
- Server will start on http://localhost:8000
- Keep this terminal open
-
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:
-
Start token-aggregation (local or use a deployed URL).
- See E2E_PREPARATION.md for steps (database, env,
npm run devor Docker). - Note the API base URL (e.g.
http://localhost:3000for local).
- See E2E_PREPARATION.md for steps (database, env,
-
Configure companion site env.
- In
packages/site, copy.env.production.distto.envor.env.production. - Set
GATSBY_SNAP_API_BASE_URLto the token-aggregation base URL (e.g.http://localhost:3000). - Restart the site if it is already running so the variable is picked up.
- In
-
Run Snap + site: From repo root,
pnpm run start(serves site and Snap on http://localhost:8000). -
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
- Open browser with MetaMask Flask installed
- Navigate to http://localhost:8000
- You should see the Snap installation page
- Click "Connect" to install the Snap
- 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 bridge routes: CCIP (WETH9/WETH10) and, when configured, Trustless (Lockbox on 138) 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: CCIP (WETH9/WETH10) and Trustless (Lockbox) → 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:
-
Environment
- MetaMask Flask installed
- Snap dev server running:
pnpm run start(oryarn start) in the repo root - For API-dependent tests: token-aggregation service reachable. Set
apiBaseUrlto your deployment (e.g.https://your-token-aggregation-api.com) or a local/staging URL (e.g.http://localhost:3000if running token-aggregation locally).
-
Install Snap
- Open http://localhost:8000 in the browser
- Click Connect and approve Snap installation in MetaMask Flask
-
RPC methods (apiBaseUrl or optional networksUrl / tokenListUrl / bridgeListUrl)
helloget_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)
-
Companion site cards
- Set
GATSBY_SNAP_API_BASE_URLin.env(copy from.env.production.distand 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 and Trustless routes.
- Swap quote: Enter token In/Out addresses and amount (raw), then "Get quote" shows amountOut; "Show quote in Snap" opens dialog.
- Set
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-accessfor API calls - Check
snap.manifest.jsonhas correct permissions
API calls failing
- Ensure
apiBaseUrlis 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_URLin.envor.env.production(seepackages/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
- Fix any bugs found during testing
- Submit to Snap directory when ready (see Publishing below)
Publishing
Checklist before publishing:
- Thorough test: Complete docs/PRE_PUBLISH_TESTING.md (build, logos/images, all RPC methods, companion site, Send page, production-like, final sign-off).
- All manual E2E checklist items above completed and passing.
- Token-aggregation (or your API) deployed and stable; production
apiBaseUrlknown. - Snap built with no errors;
prepublishOnlyhas run (updates manifest shasum). packages/snap/package.json:nameandpublishConfig(e.g."access": "public") correct for npm.- Integrator docs updated: dApps/site must pass
apiBaseUrl(or optionalnetworksUrl/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;prepublishOnlyhas run (manifest shasum updated). packages/snap/package.json:name,version,publishConfig(e.g."access": "public") correct for npm.snap.manifest.json:description,proposedName,initialPermissionsmatch what the Snap uses;source.location.npmwill 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 optionalnetworksUrl/tokenListUrl/bridgeListUrl) for market data, bridge, swap quote.
Steps to publish to MetaMask Snap directory:
- Build: Run
pnpm run build(or yarn build; see PACKAGE_MANAGER.md). TheprepublishOnlyscript updates the manifest shasum. - Publish package: Publish the Snap package to npm (e.g. from
packages/snap) sosource.location.npminsnap.manifest.jsonis valid. - 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 is npm: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 (networksUrl, tokenListUrl, bridgeListUrl) when invoking the Snap. See "Integrators" in the repo README and "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) — CCIP and Trustless — 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