Skip to main content
This app sends USDC from Base to OP Mainnet, Arbitrum, or Polygon from a browser wallet. It requests a quote, verifies it, approves the exact amount, sends the returned funding transaction, and polls the intent status. It has six source files. api.eco.com does not send CORS headers, and your API key must stay on a server, so the browser calls /eco/v1/* on the Vite dev server, which forwards the request to https://api.eco.com and adds x-api-key.

Prerequisites

  • Node.js 22.18 or later
  • A server-side API key enabled for v1. Contact Eco to request access
  • A browser wallet extension, such as MetaMask or Rabby, holding USDC and a small amount of ETH on Base for the approval and funding transactions

Create the project

Create these files in an empty folder.
package.json
tsconfig.json
vite.config.ts
index.html
Save the module from Verify quotes before funding as src/verify-quote.ts, then add the app:
src/main.tsx
Put your key in .env in the same folder. Vite reads it on the server side only.
.env
Keep the key and build output out of version control:
.gitignore

Run it

Open the printed http://localhost:5173 URL in the browser that has your wallet extension.
  1. Select Connect wallet and approve the connection in your wallet.
  2. Enter an amount, choose a destination, and select Get quote. The quote is verified before it is shown; a quote that fails verification shows the reason instead.
  3. Select Send. Your wallet asks for an approval of exactly the quoted amount, if the Portal does not already have one, and then for the funding transaction.
  4. After funding, the quote is cleared so it cannot be sent twice, and a second status line polls GET /v1/intents/status every 5 seconds until the intent reaches a final state such as filled.
Send moves real funds on mainnet.

Security

  • The API key is read from ECO_API_KEY by the dev server and never reaches the browser bundle. The proxy forwards only /eco/v1/* to https://api.eco.com.
  • Send is enabled only for a quote that passed verifyQuote() with recipientVerified: true, and the app sends the verified execution.transaction unchanged.
  • The recipient and funder are the connected account. The app rechecks the account, the chain, and the quote expiry immediately before sending.
  • The approval is for the exact quoted amount, not an unlimited allowance.

Deploy it

vite.config.ts proxies requests only while npm run dev runs. For a deployed app, serve the same forwarding from your backend: accept /eco/v1/*, call https://api.eco.com/v1/* with x-api-key, and return the response. Do not forward arbitrary hosts or paths.

Troubleshooting

  • Eco API 401: API key is missing, unknown, or revoked: the key is not enabled for v1. Check ECO_API_KEY in .env and restart npm run dev.
  • No browser wallet found: open the page in a browser with a wallet extension installed.
  • Quote rejected: ...: the quote did not match the request; request a new quote. See What it checks.
  • Signed, but the recipient could not be proven from route data: the route pays out inside a swap or bridge call, so Send stays disabled.
  • Quote expired: select Get quote again. Quotes are valid until expiresAt.

Next steps