Skip to content

docs: add MetaMask integration guide with USDC token setup#100

Open
zkasuran wants to merge 2 commits into
circlefin:mainfrom
zkasuran:docs/metamask-usdc-integration
Open

docs: add MetaMask integration guide with USDC token setup#100
zkasuran wants to merge 2 commits into
circlefin:mainfrom
zkasuran:docs/metamask-usdc-integration

Conversation

@zkasuran

Copy link
Copy Markdown

Summary

Adds comprehensive MetaMask integration guide for Arc Testnet, including the critical wallet_watchAsset call to register USDC.

Problem

Issue #97 identified that there's no documented way to add Arc Testnet USDC to MetaMask's token list. Without this:

  • Users see no USDC balance after receiving tokens
  • Users assume transactions failed
  • DApps appear broken

Solution

New guide at docs/metamask-integration.md covering:

  1. Network setup with wallet_addEthereumChain
  2. USDC token registration with wallet_watchAsset (the missing piece)
  3. Complete onboarding flow combining both steps
  4. Contract addresses and chain configuration
  5. Why this matters section explaining the impact

Changes

  • ✅ New file: docs/metamask-integration.md
  • ✅ Updated README.md to link to new guide
  • ✅ Complete TypeScript code examples
  • ✅ Addresses issue reproduction steps

Testing

Code examples follow MetaMask's official API documentation:

Impact

Every DApp on Arc Testnet that involves USDC transfers benefits from this documentation.

Fixes #97

Adds comprehensive guide for integrating Arc Testnet with MetaMask,
including the critical wallet_watchAsset call to register USDC.

Without this step, users see no USDC balance in MetaMask after
receiving tokens, causing confusion and making DApps appear broken.

Includes:
- Complete onboarding flow with wallet_addEthereumChain
- wallet_watchAsset call for USDC token registration
- Contract addresses and chain configuration
- Why this matters section explaining the impact

Fixes circlefin#97

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@osr21

osr21 commented Jun 2, 2026

Copy link
Copy Markdown

Great guide — this addresses the exact pain point in #97.

One more MetaMask behaviour on Arc Testnet that's worth documenting alongside the wallet_watchAsset call: wallet_switchEthereumChain fails silently (tracked in #89).

Even after the network has been added, calling wallet_switchEthereumChain for Arc Testnet either resolves without switching or throws a 4902 even when the chain exists. The only reliable pattern is to always use wallet_addEthereumChain, which acts as both "add if missing" and "switch if present":

// ❌ Unreliable on Arc Testnet — may resolve without actually switching
await window.ethereum.request({
  method: 'wallet_switchEthereumChain',
  params: [{ chainId: '0x4CEF52' }],
});

// ✅ Reliable — works whether network is already added or not
await window.ethereum.request({
  method: 'wallet_addEthereumChain',
  params: [{
    chainId: '0x4CEF52',
    chainName: 'Arc Testnet',
    nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
    rpcUrls: ['https://rpc.drpc.testnet.arc.network'],
    blockExplorerUrls: ['https://testnet.arcscan.app'],
  }],
});

Note the nativeCurrency — Arc's gas is paid in USDC but MetaMask requires symbol: 'ETH' and decimals: 18 to accept the chain config (documented in #95). Using the actual USDC values causes MetaMask to reject the wallet_addEthereumChain call entirely.

Also: the rpcUrls entry matters here too — rpc.testnet.arc.network has CORS issues for browser DApps (#90), so rpc.drpc.testnet.arc.network is the reliable public endpoint to point users at.

Three corrections to the MetaMask guide, all verified against the repo
config, the MetaMask spec and the live testnet RPC:

- chainId was 0x4CF252 (5042002 transposed to 5042770). The testnet
  chain id is 5042002, which is 0x4CEF52 (hardhat.config.ts, defaults.rs).
- nativeCurrency was USDC/6 decimals. MetaMask only supports 18-decimal
  native currencies and rejects decimals != 18, so the add call has to
  use ETH/18 even though gas is paid in USDC (issue circlefin#95). The USDC
  ERC-20 watchAsset call keeps decimals: 6, which is correct.
- rpcUrls was https://rpc.arc.network, which does not resolve. Switched
  to https://rpc.drpc.testnet.arc.network, which returns chain id
  0x4cef52 and Access-Control-Allow-Origin: * for browser DApps (circlefin#90).

Also documents that wallet_switchEthereumChain fails silently or throws
4902 on Arc Testnet, and that wallet_addEthereumChain should be used as
both add and switch (issue circlefin#89).
@zkasuran

zkasuran commented Jun 8, 2026

Copy link
Copy Markdown
Author

Thanks @osr21, this was a good catch and it surfaced more than the switch-chain issue. I verified everything against the repo config, the MetaMask spec and the live testnet RPC, and pushed a fix. Three corrections plus your switch-chain note:

AI disclosure: these fixes were prepared with help from Claude (Anthropic). I verified each value against the repo, the MetaMask wallet_addEthereumChain docs and a live eth_chainId call to both RPC endpoints before pushing.

@osr21

osr21 commented Jun 9, 2026

Copy link
Copy Markdown

Thanks for the thorough fixes — the chainId, RPC, and nativeCurrency corrections all match what we see in a working implementation.

Two small additions:

wallet_watchAsset ordering — the call needs to happen after wallet_addEthereumChain fully resolves. If it fires while the user is still on a different network, MetaMask silently registers the USDC token on the wrong chain and the balance never appears. This is easy to hit in a combined "add network + add token" onboarding flow:

// ✅ Correct — await the chain switch first
await window.ethereum.request({ method: 'wallet_addEthereumChain', params: [arcConfig] });
await window.ethereum.request({ method: 'wallet_watchAsset', params: [usdcConfig] });

Dead block explorer URLs — worth a note in the guide that explorer.testnet.arc.network and explorer.arc.io no longer resolve. https://testnet.arcscan.app is the only working endpoint right now, so it should be the default in both the blockExplorerUrls field and any tx-link examples.

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.

docs: wallet_watchAsset call for USDC undocumented — USDC does not appear in MetaMask token list without it

3 participants