# Superbridge Documentation
> Complete documentation for the Superbridge swap, cross-chain swap and bridging API, SDK, and Widget.
## Quick Reference
- Base URL: `https://api.superbridge.app`
- Auth: `x-api-key` header on every request
- OpenAPI spec: https://docs.superbridge.app/openapi.yaml
- Full docs: https://docs.superbridge.app
# Overview
## Introduction
---
Source: https://docs.superbridge.app/overview
---
Superbridge is a platform for transacting and transferring between blockchain networks at cost. We do this by aggregating the best providers and routes, and making them accessible via our API, SDK and user friendly frontends. Since launching in 2023, Superbridge has served 1M+ users, processed millions of transactions and driven $12B+ in volume across 100+ networks.
#### Get started
- **Bridge and swap** — head to [superbridge.app](https://superbridge.app) and connect your wallet.
- **Build on Superbridge** — explore the [Superbridge API](https://docs.superbridge.app/api-reference).
- **Launch your own** — deploy a dedicated, white-labelled instance with [Rollies](https://docs.superbridge.app/overview/rollups).
---
Source: https://docs.superbridge.app/overview/supported-chains
---
Don't see your chain here? Get in touch to explore adding support.
---
Source: https://docs.superbridge.app/overview/supported-protocols
---
Don't see your preferred protocol here? Get in touch to explore adding support.
## Solutions
---
Source: https://docs.superbridge.app/overview/chains
---
Superbridge gives chain operators a production-ready bridging experience for their network — no need to build and maintain a bridge frontend from scratch.
#### The Problem
Launching a new chain is hard enough without having to build bridging infrastructure. Most teams end up with a forked bridge UI that's difficult to maintain, lacks features, and provides a poor bridging experience.
#### How Superbridge Helps
##### Instant Bridge Frontend
Get a fully-featured, branded bridge interface for your chain without writing a single line of frontend code. Superbridge handles the UI, wallet integrations, transaction tracking, and error handling.
##### Instant Distribution
Launch on [Superbridge](https://superbridge.app) and immediately reach users across every chain and ecosystem we support. No need to build your own frontend or drive traffic — Superbridge puts your chain in front of millions of active users.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives teams and agents programmatic access to bridging routes, chain data, and transaction activity — making it easy to build custom integrations on top of your chain's bridge.
##### Custom Branding
Deploy Superbridge on your own domain with your own branding. Your users interact with a bridge that looks and feels like part of your ecosystem.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Supported VMs
- **EVM** — e.g. [Ethereum](https://ethereum.org), [Base](https://base.org), [Unichain](https://unichain.org)
- **SVM** — e.g. [Solana](https://solana.com), [Eclipse](https://eclipse.xyz)
- **Cairo VM** — e.g. [Starknet](https://starknet.io)
#### See Also
- [Rollups](https://docs.superbridge.app/overview/rollups) — for native bridge integrations across supported rollup frameworks
- [Interoperability Protocols](https://docs.superbridge.app/overview/interoperability-protocols) — for third-party cross-chain protocol integrations
#### Get started
Reach out via our Get in Touch page to set up Superbridge for your chain.
---
Source: https://docs.superbridge.app/overview/rollups
---
Superbridge gives rollup teams a production-ready bridging experience for their chain — no need to build and maintain a bridge frontend from scratch.
Where Superbridge really shines is offering one seamless interface for accessing native bridge APIs and third-party interoperability providers. Gone are the days of needing separate interfaces for bridging different tokens or chains.
For more on interoperability protocols including fast bridging, see [Interoperability Protocols](https://docs.superbridge.app/overview/interoperability-protocols).
#### The Problem
Each rollup framework has its own canonical bridge contracts with unique interfaces, finality mechanisms, and transaction lifecycles. Supporting these natively requires deep protocol-level integration that most teams don't have the resources to build and maintain.
#### How Superbridge Helps
##### Instant Bridge Frontend
Get a fully-featured, branded bridge interface for your rollup without writing a single line of frontend code. Superbridge handles the UI, wallet integrations, transaction tracking, and error handling.
##### Instant Distribution
Launch on [Superbridge](https://superbridge.app) and immediately reach users across every chain and ecosystem we support. No need to build your own frontend or drive traffic — Superbridge puts your rollup in front of millions of active users.
##### Managed Token Listings
Get tokens listed on Superbridge so your users can bridge them to and from your chain. We handle token metadata, contract verification, and display.
##### Native Bridge Integration
Superbridge integrates directly with each framework's canonical bridge contracts. Deposits and withdrawals go through the official bridge — no third-party proxies or wrappers.
##### Transaction Lifecycle Management
Each rollup framework has different finality and withdrawal flows. Superbridge handles the full lifecycle for each, including multi-step withdrawal processes like proving and finalising on optimistic rollups.
##### Fast Withdrawals
Native rollup withdrawals can take up to 7 days. Superbridge integrates third-party routes so your users can withdraw in minutes — dramatically improving the experience of moving assets off your chain.
##### Custom Branding
Deploy Superbridge on your own domain with your own branding. Your users interact with a bridge that looks and feels like part of your ecosystem.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives teams and agents programmatic access to bridging routes, chain data, and transaction activity — making it easy to build custom integrations on top of your rollup's bridge.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Supported Frameworks
- [OP Stack](https://docs.optimism.io)
- [Arbitrum Orbit](https://docs.arbitrum.io)
- [ZKsync](https://docs.zksync.io)
- [AggLayer](https://docs.polygon.technology/agglayer)
- [Linea](https://docs.linea.build)
- [Taiko](https://docs.taiko.xyz)
#### Get started
Reach out via our Get in Touch page to set up Superbridge for your rollup.
---
Source: https://docs.superbridge.app/overview/tokens
---
Superbridge gives token issuers a production-ready bridging experience for their token — no need to build and maintain a bridge frontend from scratch.
#### The Problem
Deploying a token across multiple chains introduces complexity. Bridge contracts need to be configured, token mappings need to be maintained, and users need to know which bridge to use. Getting any of this wrong means stuck funds or confused users.
#### How Superbridge Helps
##### Instant Bridge Frontend
Get a fully-featured, branded bridge page for your token without writing a single line of frontend code. Superbridge handles the UI, wallet integrations, transaction tracking, and error handling.
##### Instant Distribution
List your token on Superbridge and immediately reach users across every chain and ecosystem we support. No need to build your own frontend or drive traffic — Superbridge puts your token in front of millions of active users.
##### Managed Listings
Get your token listed on Superbridge so users can bridge it between supported chains. We handle the token metadata, contract verification, and accurate cross-chain address mappings — so users never accidentally bridge to the wrong contract or end up with an unwrapped variant they didn't expect.
##### Multi-Protocol Routing
If your token is supported by multiple bridging protocols, Superbridge automatically finds the best route. Bridgers get the fastest, cheapest path without needing to know which protocol to use.
##### Token-Specific Branding
For projects that want a dedicated experience, Superbridge can deploy a branded bridge page specifically for your token — complete with custom theming and curated chain support.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives teams and agents programmatic access to token data and bridging routes — making it easy to build custom integrations around your token.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Whether you want your token listed on Superbridge or a dedicated branded bridge for your project, reach out via our Get in Touch page.
---
Source: https://docs.superbridge.app/overview/interoperability-protocols
---
Superbridge gives interoperability protocols a production-ready bridging experience powered by their infrastructure — no need to build and maintain a bridge frontend from scratch.
#### The Problem
Building a great cross-chain protocol is only half the battle. Getting users to actually use it requires a polished frontend, wallet integrations, transaction tracking, and ongoing maintenance. Most protocol teams would rather focus on their core infrastructure than build and maintain a bridge UI.
#### How Superbridge Helps
##### Instant Bridge Frontend
Get a fully-featured, branded bridge interface powered by your protocol without writing a single line of frontend code. Superbridge handles the UI, wallet integrations, transaction tracking, and error handling.
##### Instant Distribution
Integrate your protocol with Superbridge and immediately reach users across every chain and ecosystem we support. No need to build your own frontend — Superbridge handles the user experience.
##### Smart Routing
Superbridge's routing engine evaluates your protocol alongside others for every transaction. When your protocol offers the best route (fastest, cheapest, or most secure), users are automatically directed to it.
##### Transaction Lifecycle Management
Superbridge handles the full transaction lifecycle for your protocol — from initiation through finalisation. Bridgers get real-time status updates, error handling, and retry logic without your team building any of it.
##### Branded Deployments
For protocols that want a dedicated experience, Superbridge can deploy a branded instance that prioritises your protocol's routes. Bridgers get a familiar Superbridge experience powered by your infrastructure.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives teams and agents programmatic access to bridging routes and transaction activity — making it easy to build custom integrations powered by your protocol.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Currently Integrated Protocols
- [Across](https://across.to)
- [CCTP](https://www.circle.com/cctp)
- [CCIP](https://chain.link/ccip)
- [Hyperlane](https://www.hyperlane.xyz)
- [LayerZero](https://layerzero.network)
- [Stargate](https://stargate.finance)
- [Caldera Metalayer](https://caldera.xyz)
- [Relay](https://relay.link)
- [Mayan](https://mayan.finance)
- [Wormhole](https://wormhole.com)
#### Integrate Your Protocol
If you're building an interoperability protocol and want to reach more users, get in touch via our contact page.
---
Source: https://docs.superbridge.app/overview/centralised-exchanges
---
Superbridge gives centralised exchanges a battle-tested, fee-free API for rebalancing funds across chains.
#### The Problem
Centralised exchanges need to move assets across chains to maintain liquidity and meet user demand. Building and maintaining integrations with native bridge contracts across multiple rollup frameworks is complex, error-prone, and a constant maintenance burden.
#### How Superbridge Helps
##### Fee-Free Bridging
Superbridge routes through native, canonical bridges — meaning no third-party fees, no fee proxies, and no unintended side effects. Move assets across chains at cost.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume. The same infrastructure that powers thousands of daily bridge transactions is available via a simple API.
##### Multi-Chain Coverage
A single integration gives you access to native bridges across all supported rollup frameworks and chains. No need to build and maintain separate integrations for each chain.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives you programmatic access to bridging routes, chain data, and transaction activity — making it easy to automate rebalancing workflows.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to discuss your rebalancing needs.
---
Source: https://docs.superbridge.app/overview/solvers
---
Superbridge gives solvers a battle-tested, fee-free API for moving funds across chains.
#### The Problem
Solvers need reliable, low-cost access to cross-chain bridges to fulfil user transactions. Integrating directly with native bridge contracts across different rollup frameworks requires deep protocol knowledge and ongoing maintenance as bridges evolve.
#### How Superbridge Helps
##### Fee-Free Bridging
Superbridge routes through native, canonical bridges — meaning no third-party fees, no fee proxies, and no unintended side effects. Move assets across chains at cost.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume. The same infrastructure that powers thousands of daily bridge transactions is available via a simple API.
##### Multi-Chain Coverage
A single integration gives you access to native bridges across all supported rollup frameworks and chains. No need to build and maintain separate integrations for each chain.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives you programmatic access to bridging routes, chain data, and transaction activity — making it easy to automate your solving workflows.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to discuss your integration.
---
Source: https://docs.superbridge.app/overview/arbitrage
---
Superbridge gives cross-chain arbitrageurs a battle-tested, fee-free API for positioning capital across chains.
#### The Problem
Cross-chain arbitrageurs profit by exploiting price discrepancies and spreads across chains. To act on these opportunities, they need capital on the right chain at the right time. Moving funds quickly and cheaply between chains is critical — but integrating directly with canonical bridge contracts across different frameworks requires deep protocol knowledge and ongoing maintenance.
#### How Superbridge Helps
##### Fee-Free Bridging
Superbridge routes through native, canonical bridges — meaning no third-party fees, no fee proxies, and no unintended side effects. Move assets across chains at cost.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume. The same infrastructure that powers thousands of daily bridge transactions is available via a simple API.
##### Multi-Chain Coverage
A single integration gives you access to native bridges across all supported rollup frameworks and chains. No need to build and maintain separate integrations for each chain.
##### Programmatic Access
The [Superbridge API](https://docs.superbridge.app/api-reference) gives you programmatic access to bridging routes, chain data, and transaction activity — making it easy to automate your arbitrage workflows.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to discuss your integration.
---
Source: https://docs.superbridge.app/overview/ecosystems
---
Superbridge gives ecosystem teams a production-ready bridging experience for their network of chains — no need to build and maintain a bridge frontend from scratch.
#### How Superbridge Helps
##### Instant Bridge Frontend
Get a fully-featured, branded bridge interface for your entire ecosystem without writing a single line of frontend code. Superbridge handles the UI, wallet integrations, transaction tracking, and error handling.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### What is an Ecosystem Deployment?
An ecosystem deployment is a white-label instance of Superbridge configured for a specific chain or group of chains. It includes:
- Custom branding and theming
- Curated token lists
- Preferred bridging routes
- Custom domain support
- Analytics and monitoring
#### OP Superchain
[superbridge.app](https://superbridge.app) is the flagship ecosystem deployment, serving as the recommended bridge for the Optimism Superchain. It has processed billions of dollars in bridging volume across all OP Stack chains.
#### Deploying for Your Ecosystem
Reach out via our Get in Touch page to set up Superbridge for your ecosystem.
---
Source: https://docs.superbridge.app/overview/agents-llms
---
Superbridge provides programmatic cross-chain bridging that is well-suited for AI agents, LLMs, and other automated systems.
#### Why Superbridge for Agents
- **Structured API responses** — All endpoints return well-typed JSON, making it easy to parse and act on bridging data without scraping or guesswork.
- **Multi-provider routing** — A single API call returns quotes from multiple bridging providers, letting agents compare and select the best route automatically.
- **Full transaction lifecycle** — The [Activity](https://docs.superbridge.app/api-reference/activity) endpoint provides real-time status tracking, so agents can monitor transactions from initiation to completion.
- **Native bridge focus** — Routes use canonical, native bridges where possible, minimising trust assumptions and fees.
#### Get started
1. Get an API key — see [Authentication](https://docs.superbridge.app/api-reference/authentication).
2. Explore the [API Reference](https://docs.superbridge.app/api-reference) for endpoint details.
3. Use the [SDK](https://docs.superbridge.app/sdk) for type-safe TypeScript integration.
4. Point your agent at [`/llms.txt`](https://docs.superbridge.app/llms.txt) for the full documentation in a single plain-text file.
#### LLM-friendly Documentation
The complete Superbridge documentation is available as a single markdown file at [`/llms.txt`](https://docs.superbridge.app/llms.txt). This is designed for ingestion by LLMs and AI coding assistants — paste it into your context window or tool configuration to give your agent full knowledge of the Superbridge API.
---
Source: https://docs.superbridge.app/overview/apps
---
Superbridge helps apps onboard users to the right chain with the right assets — at cost, with no slippage.
#### The Problem
Apps are built around specific flows. A lending protocol needs users to deposit assets on a particular chain. A DEX needs liquidity on a specific deployment. But users often have their assets on the wrong chain, and bridging is a confusing, high-friction step that causes drop-off.
Getting users onboarded with the right assets shouldn't mean sending them to a third-party bridge, hoping they find their way back.
#### How Superbridge Helps
##### At-Cost Routes, No Slippage
Superbridge routes through native and canonical bridges, meaning users move assets at cost with no slippage. There are no third-party fees eating into their capital before they even start using your app.
##### White-Labelled Onboarding
Embed Superbridge directly into your app's onboarding flow so users never leave your experience. Available via the [Widget](https://docs.superbridge.app/widget) for drop-in integration, or via the [API](https://docs.superbridge.app/api-reference) for fully custom flows.
##### Multi-Chain, Multi-Asset
Whether your app is deployed on one chain or many, Superbridge handles routing from wherever the user's assets are. Support onboarding from any chain Superbridge covers without building individual bridge integrations.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume. Your users benefit from production-hardened infrastructure with robust transaction tracking, error handling, and monitoring built in.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to discuss integrating Superbridge into your app.
---
Source: https://docs.superbridge.app/overview/wallets
---
Superbridge gives wallet providers cross-chain bridging flows for their users — no need to build and maintain bridging infrastructure from scratch.
#### The Problem
Wallet users expect to move assets between chains without leaving the app. Building a reliable, multi-chain bridging experience in-house means integrating multiple protocols, handling transaction tracking, managing token mappings, and keeping up with new chains — all while maintaining a seamless UX.
#### How Superbridge Helps
##### Multi-Protocol Routing
Superbridge automatically finds the best bridging route across all supported protocols. Your users get the fastest, cheapest path without needing to know which bridge to use.
##### Multi-Chain Coverage
Tap into Superbridge's network of supported chains and tokens from day one. No need to integrate individual bridges or negotiate chain-by-chain — Superbridge gives your users access to every chain and ecosystem we support.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume across hundreds of chains. Your users benefit from production-hardened infrastructure with robust transaction tracking, error handling, and monitoring built in.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to add cross-chain bridging to your wallet.
---
Source: https://docs.superbridge.app/overview/bridge-swap-aggregators
---
Superbridge gives bridge and swap aggregators native and canonical cross-chain bridging flows — no need to build and maintain direct protocol integrations from scratch.
#### The Problem
Aggregators need to source liquidity across dozens of bridging protocols, each with their own contracts, APIs, and quirks. Native and canonical bridges are particularly difficult to integrate because they vary by chain and rollup framework. Without them, aggregators miss the most secure, fee-free routes available.
#### How Superbridge Helps
##### Multi-Protocol Routing
Superbridge automatically finds the best bridging route across all supported protocols. Your users get the fastest, cheapest path without needing to know which bridge to use.
##### Multi-Chain Coverage
Tap into Superbridge's network of supported chains and tokens from day one. No need to integrate individual bridges or negotiate chain-by-chain — Superbridge gives your users access to every chain and ecosystem we support.
##### Battle-Tested Infrastructure
Superbridge has processed billions of dollars in bridging volume across hundreds of chains. Your users benefit from production-hardened infrastructure with robust transaction tracking, error handling, and monitoring built in.
##### Dedicated Support
Hands-on user and engineering support for custom integration work or network/wallet specific intricacies. The Superbridge engineering team is here to help.
#### Get started
Reach out via our Get in Touch page to add native cross-chain bridging to your aggregator.
## Use Cases
---
Source: https://docs.superbridge.app/overview/onboarding
---
Help users get started on new chains by providing a frictionless onboarding experience. Superbridge makes it easy for users to move their assets to a new network for the first time.
#### How It Works
Onboarding with Superbridge removes the complexity of cross-chain transfers for first-time users. By integrating Superbridge into your chain's onboarding flow, users can bridge assets from chains they already use to your network in just a few clicks.
#### Superbridge Benefits
- **Wide range of chains supported** — users can onboard from almost anywhere, no matter which chain they're currently on
- **Many route options** — native and canonical bridges as well as fast intent-based or liquidity-based solutions, ensuring users get the best experience for their transfer
- **White-labelled flows** — teams can embed the [Widget](https://docs.superbridge.app/widget) for a drop-in experience or use the [API](https://docs.superbridge.app/api-reference) directly for fully custom onboarding flows
---
Source: https://docs.superbridge.app/overview/bridging
---
Move tokens between chains seamlessly with Superbridge. Whether you're bridging between L1s and L2s or across different rollup ecosystems, Superbridge finds the optimal route for your transfer.
#### How It Works
Superbridge aggregates multiple bridging protocols and routes to find the best path for your cross-chain transfer. When you initiate a bridge, Superbridge evaluates available routes across native bridges, third-party protocols, and solver networks to deliver the fastest and most cost-effective option.
#### Superbridge Benefits
- **Simplified complex flows** — intuitive interface that abstracts away the complexity of cross-chain transactions
- **Secure, canonical routes** — native and canonical bridge routes prioritised for maximum security
- **Managed & verified tokens and routes** — every token and route is vetted before being made available, so users can bridge with confidence
---
Source: https://docs.superbridge.app/overview/swapping
---
Swap tokens across chains without needing to bridge first. Superbridge handles cross-chain swaps so users can go from any token on one chain to any token on another in a single transaction.
#### How It Works
Cross-chain swapping combines bridging and token swaps into one seamless operation. Instead of manually bridging to a destination chain and then swapping on a DEX, Superbridge routes the entire flow automatically — finding the best combination of bridges and swaps to get users the token they want on the chain they want.
#### Superbridge Benefits
- **Only the best providers** — we integrate only vetted, top-tier liquidity and swap providers
- **Multi-VM support** — swap across EVM and non-EVM chains
- **Gasless support** — execute swaps without needing gas on the origin chain
## Safety & Security
---
Source: https://docs.superbridge.app/overview/compliance
---
Superbridge is committed to maintaining the highest standards of compliance and security across all supported chains and protocols.
#### Wallet Screening
Superbridge uses a number of providers to screen all wallets interacting with the platform, including [TRM Labs](https://www.trmlabs.com/) and [Zero Shadow](https://zeroshadow.io/), alongside our own internal blocklist. Every transaction is checked against this combined risk data to identify and block wallets associated with illicit activity.
Maintaining multiple sources of intelligence — both third-party and internal — lets us respond quickly to emerging threats and ensures comprehensive coverage beyond what any single provider offers.
#### How It Works
When a user connects their wallet to Superbridge, our screening pipeline evaluates the wallet address in real time against each provider and our internal list. Wallets flagged for sanctions violations, terrorist financing, or other high-risk activity are automatically blocked from using the platform.
This ensures Superbridge remains a safe and compliant bridging solution for all users and chain partners.
---
Source: https://docs.superbridge.app/overview/disclosures
---
We take the security of Superbridge seriously and welcome reports from the community. If you discover a vulnerability, bug, or anything else that could affect the safety of our users or their funds, we want to hear about it.
#### Reporting a Vulnerability
Email us at [security@superbridge.app](mailto:security@superbridge.app) with anything you find or want to report. Please include enough detail for us to reproduce and understand the issue, such as:
- A description of the vulnerability and its potential impact
- Steps to reproduce, or a proof of concept
- Any relevant chains, contracts, transactions, or addresses involved
We don't currently run a formal bug bounty program, but we genuinely appreciate responsible disclosure and will work with you to understand and resolve any issue you report.
#### Responsible Disclosure
We ask that you give us a reasonable opportunity to investigate and address a reported issue before disclosing it publicly, and that you avoid accessing, modifying, or destroying data that isn't yours while researching. Acting in good faith helps us keep users safe.
# API Reference
## Getting Started
---
Source: https://docs.superbridge.app/api-reference
---
The Superbridge API provides programmatic access to cross-chain bridging routes, token information, chain data, and transaction activity.
Where the Superbridge API differs from other cross-chain APIs is our focus on native, canonical asset bridging. That means no fees, fee proxies, or unintended side effects. The Superbridge API is built around hard or costly to index protocols and we do our best to make it easy to integrate with these flows.
#### Base URL
All API requests should be made to:
```
https://api.superbridge.app
```
#### Authentication
All requests require an API key passed via the `x-api-key` header. See [Authentication](https://docs.superbridge.app/api-reference/authentication) for details.
#### Endpoints
- [/v1/chains](https://docs.superbridge.app/api-reference/chains) — List supported chains
- [/v1/tokens](https://docs.superbridge.app/api-reference/tokens) — List supported tokens
- [/v1/token](https://docs.superbridge.app/api-reference/token) — Get a single supported token
- [/v1/routes](https://docs.superbridge.app/api-reference/routes) — Get bridging routes
- [/v1/activity](https://docs.superbridge.app/api-reference/activity) — Get transaction activity
- [/v1/get_step_transaction](https://docs.superbridge.app/api-reference/step-transaction) — Get step transaction data
- [/v1/index_transaction](https://docs.superbridge.app/api-reference/index-transaction) — Notify the indexer about a submitted transaction
- [/v1/submit_gasless](https://docs.superbridge.app/api-reference/submit-gasless) — Submit a signed gasless transaction for relay
- [/v1/health](https://docs.superbridge.app/api-reference/health) — Check API availability
---
Source: https://docs.superbridge.app/api-reference/authentication
---
All API requests require authentication via the `x-api-key` header. Include your API key with every request.
#### Obtaining an API Key
To obtain an API key, get in touch with the Superbridge team.
#### API Key Best Practices
Your API key identifies your account and is used to track usage. If your key is compromised, contact us and we'll rotate it for you.
- **Keep it server-side** — don't expose your key in frontend code. If you need to call the API from a browser, route requests through your own backend.
- **Use environment variables** — avoid hardcoding keys in source code.
- **Exclude from version control** — add keys to `.gitignore` or use a secrets manager.
- **Limit access** — only share with team members who need it.
#### Error Responses
Requests without a valid API key will receive a `401 Unauthorized` response.
---
Source: https://docs.superbridge.app/api-reference/testing
---
You can request a testing API key to try out the Superbridge API before going to production.
#### Requesting a Key
To get a testing API key, get in touch with the Superbridge team.
#### Limits
Testing keys are intended for evaluation and integration work, so they come with the following limits:
- **$100 quote value** — quotes are limited to a maximum of $100 in value.
- **1 request every 5 seconds** — requests are rate limited to one per five seconds.
- **Valid for 30 days** — testing keys expire 30 days after they're issued, after which requests are rejected.
When you're ready to move to production, [let us know](mailto:biz@superbridge.app) and we can put together a quote based on expected transfer volume and activity levels.
---
Source: https://docs.superbridge.app/api-reference/openapi
---
The Superbridge API follows the [OpenAPI 3.0](https://swagger.io/specification/) specification. You can use the spec to integrate AI agents and LLM tools, generate SDKs in any language, import into tools like Postman, and more.
[Download OpenAPI Spec](https://docs.superbridge.app/openapi.yaml)
---
Source: https://docs.superbridge.app/api-reference/agents-llms
---
The full Superbridge documentation is available as a single markdown file at [`/llms.txt`](https://docs.superbridge.app/llms.txt), designed for consumption by LLMs and AI agents.
#### Usage
Point your agent or coding assistant at the following URL to give it full context on the Superbridge API:
```
https://docs.superbridge.app/llms.txt
```
This file is auto-generated from the documentation source and stays in sync with every page on this site.
#### What's Included
The `/llms.txt` file contains the complete content of every documentation page, including:
- Overview and concepts
- API endpoint descriptions, parameters, and response schemas
- Guides on transaction lifecycle, approvals, signing, and more
- SDK and Widget documentation
#### Tips for Agents
- Use the [OpenAPI spec](https://docs.superbridge.app/api-reference/openapi) alongside `/llms.txt` for precise request/response types.
- The [SDK](https://docs.superbridge.app/sdk) provides type-safe TypeScript wrappers if your agent runs in a Node.js environment.
- See the [Overview](https://docs.superbridge.app/overview/agents-llms) page for more on why Superbridge is a good fit for automated bridging.
## Endpoints
---
Source: https://docs.superbridge.app/api-reference/health
---
Check whether the API is available.
`GET /v1/health`
##### Response
Returns a boolean ok flag.
```typescript
interface Response {
ok?: boolean;
}
```
---
Source: https://docs.superbridge.app/api-reference/chains
---
Retrieve the list of supported chains.
`GET /v1/chains`
##### Parameters
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `key` | string | No | Shorthand chain identifier (e.g. eth for Ethereum) |
| `id` | string | No | Native chain ID (e.g. 1 for Ethereum) |
| `uid` | string | No | Chain UUID (internal identifier) |
##### Response
Returns an array of Chain objects.
Array of `Chain`
```typescript
interface Chain {
// Native chain ID (e.g. 1 for Ethereum)
id: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
keys: string[];
// Chain UUID (internal identifier)
uid: string;
blockExplorers: BlockExplorer[];
logoUri: string | null;
vm: "evm" | "svm" | "stark";
type: "mainnet" | "testnet";
name: string;
rpcUrl: string;
}
```
---
Source: https://docs.superbridge.app/api-reference/tokens
---
Retrieve the list of supported tokens. Results are paginated.
`GET /v1/tokens`
##### Parameters
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `address` | string | No | Filter by token address |
| `chainKey` | string | No | Shorthand chain identifier (e.g. eth for Ethereum) |
| `chainId` | string | No | Native chain ID (e.g. 1 for Ethereum) |
| `chainUid` | string | No | Chain UUID (internal identifier) |
| `cursor` | string | No | Pagination cursor |
| `limit` | number | No | Page size (1-100) |
| `search` | string | No | Search by name, symbol, or address |
##### Response
Returns a paginated response with an array of Token objects and a cursor for the next page.
```typescript
interface PaginatedTokensResponse {
tokens: TokenDto[];
nextCursor: string | null;
}
```
##### Pagination
Use the `nextCursor` value from the response as the `cursor` query parameter to fetch the next page. When `nextCursor` is null, there are no more results.
---
Source: https://docs.superbridge.app/api-reference/token
---
Retrieve a single supported token by address and chain.
`GET /v1/token`
##### Parameters
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `address` | string | Yes | 0x0000000000000000000000000000000000000000 for native tokens |
| `chainKey` | string | No | Shorthand chain identifier (e.g. eth for Ethereum) |
| `chainId` | string | No | Native chain ID (e.g. 1 for Ethereum) |
| `chainUid` | string | No | Chain UUID (internal identifier) |
Provide the token `address` and exactly one chain identifier: `chainUid`, `chainId`, or `chainKey`.
##### Response
Returns a Token object.
```typescript
interface TokenDto {
// 0x0000000000000000000000000000000000000000 for native tokens
address: string;
// Whether this token provides gas on its chain, regardless of the address form in this DTO
isGasToken: boolean;
// Whether this exact address form is backed by the chain native balance RPC rather than an ERC20/SPL balance call
isNative: boolean;
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
name: string;
decimals: number;
logoUri: string | null;
symbol: string;
usd: number | null;
isSpl2022?: boolean;
verified: boolean;
}
```
---
Source: https://docs.superbridge.app/api-reference/routes
---
Get available routes for a swap, cross-chain swap or bridge. Returns quotes from multiple bridging providers.
`POST /v1/routes`
##### Request Body
```typescript
interface GetRoutesRequest {
// Chain UUID (internal identifier)
fromChainUid?: string;
// Chain UUID (internal identifier)
toChainUid?: string;
// Native chain ID (e.g. 1 for Ethereum)
fromChainId?: string;
// Native chain ID (e.g. 1 for Ethereum)
toChainId?: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
fromChainKey?: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
toChainKey?: string;
// 0x0000000000000000000000000000000000000000 for native tokens
fromTokenAddress: string;
// 0x0000000000000000000000000000000000000000 for native tokens
toTokenAddress: string;
sender?: string;
recipient?: string;
// Amount in wei (or smallest denomination)
amount: string;
routeIds?: ("op-deposit-cdm" | "op-deposit-portal" | "op-withdrawal-cdm" | "op-withdrawal-messagepasser" | "arb-deposit-retryable" | "ArbitrumWithdrawal" | "ZksyncDeposit" | "ZksyncWithdrawal" | "Cctp" | "cctp-v1-wh" | "cctp-v1-wh-relayer" | "cctp-v1-wh-executor" | "cctp-v1-ccip" | "CctpV2Standard" | "CctpV2StandardAuto" | "cctp-v2-standard-forwarder" | "cctp-v2-standard-wh-executor" | "CctpV2Fast" | "CctpV2FastAuto" | "cctp-v2-fast-forwarder" | "cctp-v2-fast-wh-executor" | "Across" | "Hyperlane" | "Lz" | "stargate-v2-fast" | "Ccip" | "Eco" | "Relay" | "TaikoDeposit" | "TaikoWithdrawal" | "LineaDeposit" | "LineaWithdrawal" | "StarknetDeposit" | "StarknetWithdrawal" | "LxlyDeposit" | "LxlyWithdrawal" | "LxlyCross" | "Aori" | "GasDotZip" | "VeloraDelta" | "Openocean" | "Jupiter" | "BaseBridgeToSvm" | "BaseBridgeToEvm" | "WormholeTokenBridge" | "WormholeNTT" | "mayan-swift" | "mayan-swift-v2" | "mayan-mctp" | "mayan-fast-mctp" | "mayan-fast-mctp-swap" | "mayan-wh" | "mayan-mono" | "IcttTransfer" | "weth-deposit" | "weth-withdraw" | "lido-eth-to-steth" | "lido-steth-to-wsteth" | "lido-wsteth-to-steth" | "lido-eth-to-wsteth" | "signet-deposit" | "signet-withdrawal" | "Superset")[];
slippage: number;
}
```
Provide one source chain identifier and one destination chain identifier using `fromChainUid`/`toChainUid`, `fromChainId`/`toChainId`, or `fromChainKey`/`toChainKey`.
Use `routeIds` to restrict the response to specific route implementations.
We recommend refreshing routes every 30 seconds to avoid submitting stale quotes that may revert onchain.
##### Response
Returns an object containing an array of route results, one per provider.
```typescript
interface RouteResponse {
request: RouteRequest;
results: RouteResult[];
}
```
---
Source: https://docs.superbridge.app/api-reference/activity
---
Returns detailed information for swap, cross-chain swap and bridge operations.
`GET /v1/activity`
##### Parameters
| Name | Type | Required | Description |
|------|------|----------|-------------|
| `txHash` | string | No | Filter by initiating transactionHash |
| `status` | string | No | "pending" or "done", default all |
| `type` | string | No | "mainnet" or "testnet", default all |
| `pageSize` | number | No | |
| `fromChainId` | string | No | |
| `fromChainKey` | string | No | |
| `fromChainUid` | string | No | |
| `toChainUid` | string | No | |
| `toChainId` | string | No | |
| `toChainKey` | string | No | |
| `cursor` | string | No | |
| `address` | string | No | Filter by address |
Use `address` to fetch activity for a wallet, or `txHash` to find activity by an initiating transaction hash. You can also filter by source/destination chain, `status`, chain `type`, `pageSize`, and `cursor`.
##### Response
Returns an array of Activity objects.
Array of `Activity`
```typescript
interface Activity {
type: "bridge" | "crosschainswap" | "swap";
// Chain UUID (internal identifier)
fromChainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
fromChainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
fromChainKeys: string[];
// Chain UUID (internal identifier)
toChainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
toChainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
toChainKeys: string[];
steps: (TransactionStepDoneDto | TransactionStepInvalidatedDto | TransactionStepNotReadyDto | TransactionStepReadyDto | TransactionStepAutoDto | WaitStepDoneDto | WaitStepInvalidatedDto | WaitStepInProgressDto | WaitStepNotStartedDto | UpgradeEventDto)[];
fees: FeeGroup[];
meta: RouteMetaDto;
id: string;
from: string;
to: string;
amount: string;
receiveAmount: string;
fromToken: TokenDto;
toToken: TokenDto;
referrer: string | null;
nextCheckTimestamp: number | null;
escapeHatch: boolean;
providerExplorerDetails: ProviderExplorerDetails | null;
}
```
---
Source: https://docs.superbridge.app/api-reference/step-transaction
---
Get the transaction data required to execute a specific step of a multi-step bridge transaction (e.g. proving or finalizing a withdrawal).
`POST /v1/get_step_transaction`
##### Request Body
```typescript
interface GetStepTransactionRequest {
id: string;
submitter: string;
action: "Revoke" | "Approve" | "ApproveGasToken" | "Initiate" | "Prove" | "Finalise" | "Refund";
}
```
Use the activity `id` and the ready step's `action` to determine what to pass here. The `submitter` should be the address that will sign and submit the transaction.
##### Response
Returns the transaction data for the requested step. The shape varies by VM type (EVM, SVM, Starknet).
One of:
```typescript
interface InitiatingTransactionEvmDto {
type: "evm";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
// Hex
data: string;
from: string;
to: string;
value: string;
}
```
```typescript
interface InitiatingTransactionSvmDto {
type: "svm";
// Base64
data: string;
chainUid: string;
chainId: string;
chainKeys: string[];
}
```
```typescript
interface InitiatingTransactionStarkDto {
type: "starknet";
chainUid: string;
chainId: string;
chainKeys: string[];
calls: StarkCallDto[];
}
```
See [Transaction Lifecycle](https://docs.superbridge.app/api-reference/transaction-lifecycle) for more on how multi-step bridge transactions work.
---
Source: https://docs.superbridge.app/api-reference/index-transaction
---
Notify the Superbridge Indexer about a submitted transaction so it can be tracked and indexed.
`POST /v1/index_transaction`
##### Request Body
```typescript
interface IndexTransactionRequest {
routeId: "op-deposit-cdm" | "op-deposit-portal" | "op-withdrawal-cdm" | "op-withdrawal-messagepasser" | "arb-deposit-retryable" | "ArbitrumWithdrawal" | "ZksyncDeposit" | "ZksyncWithdrawal" | "Cctp" | "cctp-v1-wh" | "cctp-v1-wh-relayer" | "cctp-v1-wh-executor" | "cctp-v1-ccip" | "CctpV2Standard" | "CctpV2StandardAuto" | "cctp-v2-standard-forwarder" | "cctp-v2-standard-wh-executor" | "CctpV2Fast" | "CctpV2FastAuto" | "cctp-v2-fast-forwarder" | "cctp-v2-fast-wh-executor" | "Across" | "Hyperlane" | "Lz" | "stargate-v2-fast" | "Ccip" | "Eco" | "Relay" | "TaikoDeposit" | "TaikoWithdrawal" | "LineaDeposit" | "LineaWithdrawal" | "StarknetDeposit" | "StarknetWithdrawal" | "LxlyDeposit" | "LxlyWithdrawal" | "LxlyCross" | "Aori" | "GasDotZip" | "VeloraDelta" | "Openocean" | "Jupiter" | "BaseBridgeToSvm" | "BaseBridgeToEvm" | "WormholeTokenBridge" | "WormholeNTT" | "mayan-swift" | "mayan-swift-v2" | "mayan-mctp" | "mayan-fast-mctp" | "mayan-fast-mctp-swap" | "mayan-wh" | "mayan-mono" | "IcttTransfer" | "weth-deposit" | "weth-withdraw" | "lido-eth-to-steth" | "lido-steth-to-wsteth" | "lido-wsteth-to-steth" | "lido-eth-to-wsteth" | "signet-deposit" | "signet-withdrawal" | "Superset";
// Chain UUID (internal identifier)
chainUid?: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId?: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKey?: string;
metadata?: string;
txHash: string;
}
```
You must provide the `routeId` and `txHash` fields. For the chain identifier, provide one of `chainUid`, `chainId`, or `chainKey` — see [Chain Identifiers](https://docs.superbridge.app/api-reference/chain-identifiers) for details on each format.
See the [Indexing](https://docs.superbridge.app/api-reference/indexing) guide for when and why to use this endpoint.
---
Source: https://docs.superbridge.app/api-reference/submit-gasless
---
Submit a signed gasless transaction for relay. Used for routes where the user signs a message instead of submitting an on-chain transaction directly.
`POST /v1/submit_gasless`
##### Request Body
```typescript
interface SubmitGaslessRequest {
routeId: "op-deposit-cdm" | "op-deposit-portal" | "op-withdrawal-cdm" | "op-withdrawal-messagepasser" | "arb-deposit-retryable" | "ArbitrumWithdrawal" | "ZksyncDeposit" | "ZksyncWithdrawal" | "Cctp" | "cctp-v1-wh" | "cctp-v1-wh-relayer" | "cctp-v1-wh-executor" | "cctp-v1-ccip" | "CctpV2Standard" | "CctpV2StandardAuto" | "cctp-v2-standard-forwarder" | "cctp-v2-standard-wh-executor" | "CctpV2Fast" | "CctpV2FastAuto" | "cctp-v2-fast-forwarder" | "cctp-v2-fast-wh-executor" | "Across" | "Hyperlane" | "Lz" | "stargate-v2-fast" | "Ccip" | "Eco" | "Relay" | "TaikoDeposit" | "TaikoWithdrawal" | "LineaDeposit" | "LineaWithdrawal" | "StarknetDeposit" | "StarknetWithdrawal" | "LxlyDeposit" | "LxlyWithdrawal" | "LxlyCross" | "Aori" | "GasDotZip" | "VeloraDelta" | "Openocean" | "Jupiter" | "BaseBridgeToSvm" | "BaseBridgeToEvm" | "WormholeTokenBridge" | "WormholeNTT" | "mayan-swift" | "mayan-swift-v2" | "mayan-mctp" | "mayan-fast-mctp" | "mayan-fast-mctp-swap" | "mayan-wh" | "mayan-mono" | "IcttTransfer" | "weth-deposit" | "weth-withdraw" | "lido-eth-to-steth" | "lido-steth-to-wsteth" | "lido-wsteth-to-steth" | "lido-eth-to-wsteth" | "signet-deposit" | "signet-withdrawal" | "Superset";
// Chain UUID (internal identifier)
chainUid?: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId?: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKey?: string;
signature: string;
metadata: string;
}
```
You must provide the `routeId`, `signature`, and `metadata` fields. The `signature` is the user's signed message, and `metadata` is the opaque payload returned by the route. For the chain identifier, provide one of `chainUid`, `chainId`, or `chainKey` — see [Chain Identifiers](https://docs.superbridge.app/api-reference/chain-identifiers) for details on each format.
## Guides
---
Source: https://docs.superbridge.app/api-reference/chain-identifiers
---
Every chain in the Superbridge API is represented with three identifiers. Any of them can be used when querying or submitting requests that accept chain filters.
You can see the values returned for chains by checking out the [/chains](https://docs.superbridge.app/api-reference/chains) endpoint.
#### Chain ID
The native blockchain chain ID. This is the numeric identifier used by the chain itself (e.g. `1` for Ethereum, `10` for Optimism, `42161` for Arbitrum One).
Chain IDs are guaranteed to be static and will never change.
Returned by `/v1/chains` as `id`, and by token, route, transaction, and activity payloads as `chainId`. Used in request parameters like `fromChainId`, `toChainId`, and `chainId`.
```json
{
"id": "1"
}
```
#### Chain UID
A UUID assigned internally by Superbridge to uniquely identify a chain. Unlike Chain IDs, these are guaranteed to be globally unique across all chain types.
Some testnets and the occasional mainnet have conflicting chain IDs, making `chainId` alone insufficient for unique identification. The `chainUid` resolves this by providing a guaranteed unique identifier for every chain.
Chain UIDs are guaranteed to be static and will never change.
Returned by `/v1/chains` as `uid`, and by token, route, transaction, and activity payloads as `chainUid`.
```json
{
"uid": "9a3f7b2e-1d4c-4e8a-b6f5-0c2d9e8a7b3f"
}
```
#### Chain Key
A human-readable shorthand identifier for a chain (e.g. `eth` for Ethereum, `base` for Base, `arb` for Arbitrum One). A chain may have multiple keys, so this is returned as an array.
Chain keys are stable but additive. New keys may be added to a chain over time, but existing keys will never be removed.
Returned by `/v1/chains` as `keys`, and by token, route, transaction, and activity payloads as `chainKeys`. Used in request parameters like `fromChainKey`, `toChainKey`, and `chainKey`.
```json
{
"keys": ["eth", "ethereum"]
}
```
#### Usage in requests
When an endpoint accepts a chain identifier, you can use any of the three identifier types. For example, the [Routes](https://docs.superbridge.app/api-reference/routes) endpoint accepts any of `fromChainId`/`toChainId`, `fromChainKey`/`toChainKey` or `fromChainUid`/`toChainUid`.
The [Chains](https://docs.superbridge.app/api-reference/chains) endpoint uses shorter query names: `id`, `uid`, and `key`.
---
Source: https://docs.superbridge.app/api-reference/transaction-lifecycle
---
Cross-chain transactions are not instantaneous. Each transaction goes through multiple steps and wait periods before completion.
#### Steps
A bridging transaction is broken down into a series of steps. Each step is one of:
- **Transaction** — an on-chain transaction that needs to be submitted (by the caller or automatically by a relayer)
- **Wait** — a wait period for on-chain confirmations or protocol finalization
- **Info** — informational context (e.g. links or status messages)
Some bridges complete in seconds, others can take minutes, hours, or even days depending on the underlying protocol and chains involved.
The steps for a given bridge are known upfront — the [Routes](https://docs.superbridge.app/api-reference/routes) endpoint includes the expected steps for each route so you know what to expect before initiating. Once a transaction is in flight, the [Activity](https://docs.superbridge.app/api-reference/activity) endpoint provides detailed, real-time status for each step including progress, confirmations, and gas costs.
##### Transaction step statuses
| Status | Meaning |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| `ready` | The transaction can be submitted now. Call [Step Transaction](https://docs.superbridge.app/api-reference/step-transaction) to get the transaction data. |
| `not-ready` | A future transaction step that isn't actionable yet (e.g. waiting for a prior step to complete). |
| `auto` | The transaction will be submitted automatically by a relayer — no action required. |
| `done` | The transaction has been submitted and confirmed on-chain. |
##### Wait step statuses
| Status | Meaning |
| ------------- | ------------------------------------------------------------------------------ |
| `not-started` | The wait period hasn't begun yet (a prior step needs to complete first). |
| `in-progress` | The wait period is active. Includes `startedAt` and `expectedDuration` fields. |
| `done` | The wait period is complete. |
#### Progressing a transaction
When a transaction step has status `ready`, you can progress the bridge by calling the [Step Transaction](https://docs.superbridge.app/api-reference/step-transaction) endpoint. This returns the transaction data (calldata, target address, value) that needs to be signed and submitted on-chain.
The flow is:
1. Poll the [Activity](https://docs.superbridge.app/api-reference/activity) endpoint to get the current steps
2. Find the step with `transactionType: "ready"`
3. Call `POST /v1/get_step_transaction` with the activity `id`, the step's `action`, and the `submitter` address
4. Sign and submit the returned transaction on-chain
5. Continue polling activity until the bridge is complete
The response shape from Step Transaction varies by VM — EVM transactions return `to`, `data`, and `value`, while SVM transactions return serialized transaction data. See [Step Transaction](https://docs.superbridge.app/api-reference/step-transaction) for the full response schema.
#### Polling with `nextCheckTimestamp`
Each activity item includes a `nextCheckTimestamp` field (unix milliseconds, or `null`). Use this to determine when to poll the [Activity](https://docs.superbridge.app/api-reference/activity) endpoint next.
- If `nextCheckTimestamp` is in the future, there's no point polling before that time — the status won't have changed.
- If `nextCheckTimestamp` is in the past or `null`, you can poll immediately.
- Once all steps are `done`, `nextCheckTimestamp` will be `null` — the transaction is complete.
This avoids unnecessary API calls during long wait periods (e.g. the 7-day challenge period on optimistic rollups) while still ensuring you catch state changes promptly.
#### Wait Periods
Between transaction steps there are often wait periods. These can range from a few seconds for fast bridges to days for protocols that use optimistic verification (e.g. Optimism and Arbitrum native bridges have a 7 day challenge period).
Each in-progress wait step includes `startedAt` (unix ms) and `expectedDuration` (ms) so you can track progress or estimate completion time.
---
Source: https://docs.superbridge.app/api-reference/routes-vs-quotes
---
The [/routes](https://docs.superbridge.app/api-reference/routes) endpoint returns an array of route results, one per provider. Each result always includes the provider information, and the `result` field will be either a quote or an error.
#### Route Result
```json
{
"request": { ... },
"results": [
{
"meta": {
"id": "Across",
"provider": { "id": "across", "name": "Across", "icon": "..." },
"secondaryProvider": null,
"requiresManualSteps": false
},
"result": { ... }
}
]
}
```
#### Quotes
When a provider can fulfill the request, `result` contains a quote with the initiating transaction, approval information, fees, expected receive amount, and transaction steps.
You can distinguish a quote from an error by checking for the presence of the `initiatingTransaction` field.
#### Errors
When a provider can't fulfill the request, `result` contains an error object with a `type` field. See [Errors](https://docs.superbridge.app/api-reference/errors) for the full list of error types.
---
Source: https://docs.superbridge.app/api-reference/errors
---
The [/routes](https://docs.superbridge.app/api-reference/routes) endpoint can return two kinds of errors:
- **Route errors** are returned when the request can't produce any quotes at all. The response is a `400 Bad Request` with a single error object in the body — no `results` are returned.
- **Quote errors** are returned when the request itself is valid but an individual provider can't return a quote. They appear on the `result` field of a single entry in `results`, alongside quotes from other providers that succeeded.
In both cases, the error object has a `type` field identifying the specific error.
#### Route Errors
Route errors are thrown when no quotes can be returned. The `/routes` request fails with `400 Bad Request` and the body is one of the following objects.
##### Paused
The route between these chains is temporarily paused.
```json
{
"type": "Paused"
}
```
##### Disabled
The route between these chains has been disabled and is not currently available.
```json
{
"type": "Disabled"
}
```
##### SlippageTooHigh
The requested slippage is above the maximum slippage permitted for this route. Includes the requested `slippagePercent` and the `maximumSlippagePercent` allowed.
```json
{
"type": "SlippageTooHigh",
"slippagePercent": 25,
"maximumSlippagePercent": 10
}
```
#### Quote Errors
Quote errors live on the `result` field of an individual entry in `results`. Other providers in the same response may still return valid quotes.
You can distinguish a quote from a quote error by checking for the presence of `initiatingTransaction` on `result` — if it's there, it's a quote. See [Routes vs. Quotes](https://docs.superbridge.app/api-reference/routes-vs-quotes) for more detail.
##### GenericError
A catch-all error for unexpected failures. Includes an `error` field with a message.
```json
{
"type": "GenericError",
"error": "Something went wrong"
}
```
##### AmountTooSmall
The requested amount is below the minimum supported by this provider. May include a `minimum` field with the smallest acceptable amount, but this is not always available.
```json
{
"type": "AmountTooSmall",
"minimum": "1000000"
}
```
##### AmountTooLarge
The requested amount exceeds the maximum supported by this provider. May include a `maximum` field with the largest acceptable amount, but this is not always available.
```json
{
"type": "AmountTooLarge",
"maximum": "1000000000000000000000"
}
```
##### PriceImpactTooHigh
The quote's price impact exceeds the maximum accepted. Includes the observed `priceImpactPercent` and the `maximumPriceImpactPercent` allowed.
```json
{
"type": "PriceImpactTooHigh",
"priceImpactPercent": 12.5,
"maximumPriceImpactPercent": 10
}
```
##### Paused
This provider is temporarily paused for this route.
```json
{
"type": "Paused"
}
```
##### Disabled
This provider has been disabled for this route.
```json
{
"type": "Disabled"
}
```
##### ERC777MintToSmartContract
The requested token is an ERC-777 and the recipient is a smart contract, which this provider doesn't support.
```json
{
"type": "ERC777MintToSmartContract"
}
```
---
Source: https://docs.superbridge.app/api-reference/approvals
---
Approvals are EVM only. Other VMs supported by the Superbridge API do not require separate approval steps.
Quotes may include token approval transactions that need to be executed before the initiating transaction. These are optional fields on the route quote — consumers should use their own allowance checking logic to determine if approvals are actually needed.
Always use the `contractAddress` from the approval object when checking and setting allowances. The approval target is not always the same contract that is called in the initiating transaction.
The Superbridge API always specifies the minimum required approval amount — it will never request a max (unlimited) approval.
#### tokenApproval
An ERC-20 token approval for the bridging contract to spend the token being bridged. Includes the `tokenAddress`, `amount`, `contractAddress`, and a pre-built `tx` object.
Check the current allowance for `tokenAddress` on `contractAddress`. If the allowance is less than `amount`, submit the `tx`.
#### revokeTokenApproval
Some tokens (like USDT) require the spending allowance to be reset to zero before it can be set to a new value. If `revokeTokenApproval` is present, the current allowance must be revoked before `tokenApproval` can be submitted.
#### gasTokenApproval
Some rollups use a custom gas token instead of ETH. When bridging to one of these rollups, you might need to approve spending of the gas token so it can be sent alongside your bridged token to pay for execution of the destination transaction.
#### Worst case example
Consider bridging USDT to a rollup with a custom gas token. In this scenario, three approvals may be needed:
1. **revokeTokenApproval** — USDT has a non-zero allowance that must be reset to zero first
2. **tokenApproval** — approve the bridge contract to spend USDT
3. **gasTokenApproval** — approve the bridge contract to spend the gas token for destination chain execution
All three must be confirmed before submitting the initiating transaction.
#### Batching approvals
Wallets that support batched transactions — such as multisig wallets (e.g. Safe) or EOAs with EIP-7702 delegation — can submit approvals and the initiating transaction in a single step. Since the Superbridge API returns pre-built `tx` objects for both approvals and the initiating transaction, all calls can be bundled into one batched execution.
---
Source: https://docs.superbridge.app/api-reference/signing
---
[Quotes](https://docs.superbridge.app/api-reference/routes) and [steps](https://docs.superbridge.app/api-reference/step-transaction) return pre-built transaction objects that need to be signed and submitted on-chain. The shape of the transaction object varies by VM type.
#### EVM
EVM transactions include `to`, `data`, and `value` fields that can be passed directly to any Ethereum library.
If the quote includes [approvals](https://docs.superbridge.app/api-reference/approvals), they must be confirmed before the initiating transaction.
##### Viem
```typescript
import { walletClient } from './client';
const hash = await walletClient.sendTransaction({
to: tx.to,
data: tx.data,
value: BigInt(tx.value),
});
```
##### Ethers
```typescript
import { ethers } from 'ethers';
const signer = await provider.getSigner();
const hash = await signer.sendTransaction({
to: tx.to,
data: tx.data,
value: tx.value,
});
```
#### SVM
For Solana and other SVM chains, the `data` field contains a base64-encoded `VersionedTransaction`. Decode it, sign it, and send it directly — the transaction is self-contained with all instructions, lookup tables, and compute budget already set.
```typescript
import { VersionedTransaction } from '@solana/web3.js';
const txBytes = Buffer.from(tx.data, 'base64');
const transaction = VersionedTransaction.deserialize(txBytes);
transaction.sign([wallet]);
const signature = await connection.sendTransaction(transaction);
```
#### Starknet
For Starknet, the initiating transaction includes a `calls` array of `{contractAddress, entrypoint, calldata}` objects. This can be submitted directly via the Starknet wallet.
##### starknet.js
```typescript
const result = await account.execute(tx.calls);
```
##### Wallet API
```typescript
const result = await wallet.request({
type: 'wallet_addInvokeTransaction',
params: {
calls: tx.calls.map((call) => ({
contract_address: call.contractAddress,
entry_point: call.entrypoint,
calldata: call.calldata,
})),
},
});
```
---
Source: https://docs.superbridge.app/api-reference/indexing
---
In most cases, submitted transactions will automatically be picked up by the Superbridge Indexer. The indexer monitors supported chains and will detect and track your bridge transactions without any additional action required.
#### When to manually index
However, there are certain edge cases where automatic detection may not occur — for example, during periods of high network congestion, or when using less common route implementations. As such, we always recommend pinging the API with the transaction hash, route identifier, and chain identifier whenever an operation has been submitted.
This ensures your transaction is tracked reliably, regardless of network conditions.
#### How to index a transaction
Use the [Index Transaction](https://docs.superbridge.app/api-reference/index-transaction) endpoint to notify the indexer:
```bash
curl -X POST https://api.superbridge.app/v1/index_transaction \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"routeId": "Across",
"txHash": "0x...",
"chainId": "1"
}'
```
You can identify the chain using any of the three supported formats — `chainUid`, `chainId`, or `chainKey`. See [Chain Identifiers](https://docs.superbridge.app/api-reference/chain-identifiers) for details.
---
Source: https://docs.superbridge.app/api-reference/troubleshooting
---
#### Delayed OP Stack Dispute Games
When bridging via the OP Stack native bridge, withdrawals require a valid dispute game to be posted on-chain before the withdrawal can be proven. Superbridge analyses historical dispute game posting and resolution times to estimate when this step will be ready.
In practice, delays in dispute game resolution are common and can vary significantly. The estimated time provided by the API reflects historical patterns but actual resolution may take longer.
If you observe extended delays beyond the estimated time, please [get in touch](mailto:enterprise@superbridge.app).
#### Delayed CCTP Minting
When bridging via CCTP (Circle's Cross-Chain Transfer Protocol), the mint step requires an attestation from Circle before it can be executed. Bridge durations often exceed the advertised time because pulling the attestation from Circle can be delayed.
If you observe extended delays in CCTP attestations, please [get in touch](mailto:enterprise@superbridge.app).
#### Invalidation Events
Rollups can invalidate pending withdrawals, typically during system upgrades or as a security fix. An invalidation event resets the wait duration required for a withdrawal, meaning users will need to wait the full proving/challenge period again from the point of invalidation.
Invalidation events will almost always be accompanied by an Info Step in the transaction's steps array, providing context on what happened.
Where possible, when the date for an invalidation event is known ahead of time, the Superbridge API will restrict certain routes to prevent withdrawals being initiated that would be immediately affected.
## Reference
---
Source: https://docs.superbridge.app/api-reference/examples
---
End-to-end examples of common bridging flows using the Superbridge API with viem.
#### Bridge ETH from Ethereum to Base
This example fetches a route, signs and sends the initiating transaction, then polls for completion.
```typescript
import { createPublicClient, createWalletClient, http, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';
const API_BASE = 'https://api.superbridge.app';
const API_KEY = 'your-api-key';
const account = privateKeyToAccount('0x...');
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(),
});
// 1. Get a route
const routesResponse = await fetch(`${API_BASE}/v1/routes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY,
},
body: JSON.stringify({
fromChainKey: 'eth',
toChainKey: 'base',
fromTokenAddress: '0x0000000000000000000000000000000000000000',
toTokenAddress: '0x0000000000000000000000000000000000000000',
amount: parseUnits('0.01', 18).toString(),
sender: account.address,
recipient: account.address,
slippage: 0.005,
}),
});
const { results } = await routesResponse.json();
// 2. Pick the first quote (check for initiatingTransaction to distinguish from errors)
const quote = results.find((r) => r.result.initiatingTransaction)?.result;
if (!quote) throw new Error('No quote available');
// 3. Send the initiating transaction
const hash = await walletClient.sendTransaction({
to: quote.initiatingTransaction.to,
data: quote.initiatingTransaction.data,
value: BigInt(quote.initiatingTransaction.value),
});
console.log('Transaction sent:', hash);
// 4. Wait for the transaction to be confirmed
await publicClient.waitForTransactionReceipt({ hash });
// 5. Poll activity until the bridge is complete
async function pollUntilComplete() {
while (true) {
const activityResponse = await fetch(
`${API_BASE}/v1/activity?address=${account.address}`,
{ headers: { 'x-api-key': API_KEY } },
);
const activities = await activityResponse.json();
// Find our bridge by matching the initiating tx hash
const bridge = activities.find((a) =>
a.steps.some(
(s) =>
s.type === 'transaction' &&
s.transactionType === 'done' &&
s.confirmation?.transactionHash === hash,
),
);
if (!bridge) {
// Transaction not indexed yet, wait and retry
await new Promise((r) => setTimeout(r, 5000));
continue;
}
// Check if all steps are done
const allDone = bridge.steps.every((s) =>
s.type === 'transaction'
? s.transactionType === 'done' || s.transactionType === 'auto'
: s.type === 'wait'
? s.waitType === 'done'
: true,
);
if (allDone) {
console.log('Bridge complete!');
return bridge;
}
// Check for a step that needs signing
const readyStep = bridge.steps.find(
(s) => s.type === 'transaction' && s.transactionType === 'ready',
);
if (readyStep) {
// Get the step transaction data
const stepTxResponse = await fetch(
`${API_BASE}/v1/get_step_transaction`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': API_KEY,
},
body: JSON.stringify({
id: bridge.id,
action: readyStep.action,
submitter: account.address,
}),
},
);
const stepTx = await stepTxResponse.json();
const stepHash = await walletClient.sendTransaction({
to: stepTx.to,
data: stepTx.data,
value: BigInt(stepTx.value),
});
await publicClient.waitForTransactionReceipt({ hash: stepHash });
console.log('Step transaction sent:', stepHash);
}
// Wait using nextCheckTimestamp
const delay = bridge.nextCheckTimestamp
? Math.max(bridge.nextCheckTimestamp - Date.now(), 2000)
: 5000;
await new Promise((r) => setTimeout(r, delay));
}
}
await pollUntilComplete();
```
#### Handling approvals (ERC-20 bridging)
When bridging ERC-20 tokens, the route may include approval transactions that must be submitted before the initiating transaction.
```typescript
// After getting a quote...
// Check if token approval is needed
if (quote.tokenApproval) {
// Some tokens (e.g. USDT) require revoking existing allowance first
if (quote.revokeTokenApproval) {
const revokeHash = await walletClient.sendTransaction({
to: quote.revokeTokenApproval.tx.to,
data: quote.revokeTokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: revokeHash });
}
const approveHash = await walletClient.sendTransaction({
to: quote.tokenApproval.tx.to,
data: quote.tokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: approveHash });
}
// Check if gas token approval is needed (custom gas token rollups)
if (quote.gasTokenApproval) {
const gasApproveHash = await walletClient.sendTransaction({
to: quote.gasTokenApproval.tx.to,
data: quote.gasTokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: gasApproveHash });
}
// Now send the initiating transaction
const hash = await walletClient.sendTransaction({
to: quote.initiatingTransaction.to,
data: quote.initiatingTransaction.data,
value: BigInt(quote.initiatingTransaction.value),
});
```
---
Source: https://docs.superbridge.app/api-reference/types
---
All types returned by the Superbridge API, generated from the OpenAPI spec.
#### Chain
Returned by the `/v1/chains` endpoint.
```typescript
interface Chain {
// Native chain ID (e.g. 1 for Ethereum)
id: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
keys: string[];
// Chain UUID (internal identifier)
uid: string;
blockExplorers: BlockExplorer[];
logoUri: string | null;
vm: "evm" | "svm" | "stark";
type: "mainnet" | "testnet";
name: string;
rpcUrl: string;
}
```
#### Token
Returned by the `/v1/tokens` and `/v1/token` endpoints.
```typescript
interface TokenDto {
// 0x0000000000000000000000000000000000000000 for native tokens
address: string;
// Whether this token provides gas on its chain, regardless of the address form in this DTO
isGasToken: boolean;
// Whether this exact address form is backed by the chain native balance RPC rather than an ERC20/SPL balance call
isNative: boolean;
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
name: string;
decimals: number;
logoUri: string | null;
symbol: string;
usd: number | null;
isSpl2022?: boolean;
verified: boolean;
}
```
#### RouteResult
A single provider's response to a route request. Contains either a quote or an error.
```typescript
interface RouteResult {
result: QuoteDto | GenericQuoteErrorDto | AmountTooLargeQuoteErrorDto | AmountTooSmallQuoteErrorDto | PausedQuoteErrorDto | DisabledQuoteErrorDto | PriceImpactTooHighQuoteErrorDto | EscapeHatchNotSupportedQuoteErrorDto | ERC777MintToSmartContractQuoteErrorDto;
meta: RouteMetaDto;
}
```
#### RouteQuote
A successful quote from a provider.
```typescript
interface QuoteDto {
type: "bridge" | "crosschainswap" | "swap";
initiatingTransaction?: InitiatingTransactionEvmDto | InitiatingTransactionEvmGaslessDto | InitiatingTransactionSvmDto | InitiatingTransactionStarkDto;
steps: (TransactionStepReadyDto | TransactionStepDoneDto | TransactionStepInvalidatedDto | TransactionStepNotReadyDto | TransactionStepAutoDto | WaitStepDoneDto | WaitStepInvalidatedDto | WaitStepInProgressDto | WaitStepNotStartedDto | UpgradeEventDto)[];
fees: FeeGroup[];
metadata?: string;
native: boolean;
revokeTokenApproval?: TokenApprovalParamsDto;
tokenApproval?: TokenApprovalParamsDto;
gasTokenApproval?: TokenApprovalParamsDto;
token: TokenDto;
receiveToken: TokenDto;
receive: string;
minReceive?: string;
}
```
#### Initiating Transactions
Pre-built transactions to be signed and submitted. The shape varies by VM type.
##### EVM
```typescript
interface InitiatingTransactionEvmDto {
type: "evm";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
// Hex
data: string;
from: string;
to: string;
value: string;
}
```
##### EVM Gasless
```typescript
interface InitiatingTransactionEvmGaslessDto {
type: "evm-gasless";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
typedData: string;
}
```
##### SVM
```typescript
interface InitiatingTransactionSvmDto {
type: "svm";
// Base64
data: string;
chainUid: string;
chainId: string;
chainKeys: string[];
}
```
##### Starknet
```typescript
interface InitiatingTransactionStarkDto {
type: "starknet";
chainUid: string;
chainId: string;
chainKeys: string[];
calls: StarkCallDto[];
}
```
#### TokenApproval
An ERC-20 approval required before bridging. See [Approvals](https://docs.superbridge.app/api-reference/approvals).
```typescript
interface TokenApprovalParamsDto {
// The contract that needs the approval
contractAddress: string;
tokenAddress: string;
amount: string;
tx: InitiatingTransactionEvmDto;
}
```
#### FeeItem
A single fee line item.
```typescript
interface FeeItem {
amount?: string;
token?: TokenDto;
usd?: number;
name: string;
exclusive?: boolean;
bps?: number;
}
```
#### FeeGroup
A group of fee line items belonging to a provider.
```typescript
interface FeeGroup {
items: FeeItem[];
provider: ProviderDto;
}
```
#### Activity
An activity item returned by the `/v1/activity` endpoint.
```typescript
interface Activity {
type: "bridge" | "crosschainswap" | "swap";
// Chain UUID (internal identifier)
fromChainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
fromChainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
fromChainKeys: string[];
// Chain UUID (internal identifier)
toChainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
toChainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
toChainKeys: string[];
steps: (TransactionStepDoneDto | TransactionStepInvalidatedDto | TransactionStepNotReadyDto | TransactionStepReadyDto | TransactionStepAutoDto | WaitStepDoneDto | WaitStepInvalidatedDto | WaitStepInProgressDto | WaitStepNotStartedDto | UpgradeEventDto)[];
fees: FeeGroup[];
meta: RouteMetaDto;
id: string;
from: string;
to: string;
amount: string;
receiveAmount: string;
fromToken: TokenDto;
toToken: TokenDto;
referrer: string | null;
nextCheckTimestamp: number | null;
escapeHatch: boolean;
providerExplorerDetails: ProviderExplorerDetails | null;
}
```
#### TransactionStepDone
A completed transaction step.
```typescript
interface TransactionStepDoneDto {
type: "transaction";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
action: "Revoke" | "Approve" | "ApproveGasToken" | "Initiate" | "Prove" | "Finalise" | "Refund";
transactionStatus: "done";
confirmation: ConfirmationDtoV2;
}
```
#### TransactionStepReady
A transaction step that is ready to be signed.
```typescript
interface TransactionStepReadyDto {
type: "transaction";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
action: "Revoke" | "Approve" | "ApproveGasToken" | "Initiate" | "Prove" | "Finalise" | "Refund";
transactionStatus: "ready";
}
```
#### TransactionStepNotReady
A transaction step that is not yet available.
```typescript
interface TransactionStepNotReadyDto {
type: "transaction";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
action: "Revoke" | "Approve" | "ApproveGasToken" | "Initiate" | "Prove" | "Finalise" | "Refund";
transactionStatus: "not-ready";
estimatedGas: EvmNotReadyStepGasEstimateDto | SvmNotReadyStepGasEstimateDto | StarkNotReadyStepGasEstimateDto;
}
```
#### TransactionStepAuto
A transaction step handled automatically (e.g. by a relayer).
```typescript
interface TransactionStepAutoDto {
type: "transaction";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
action: "Revoke" | "Approve" | "ApproveGasToken" | "Initiate" | "Prove" | "Finalise" | "Refund";
transactionStatus: "auto";
}
```
#### WaitStepDone
A completed wait step.
```typescript
interface WaitStepDoneDto {
type: "wait";
waitType: "general" | "refund" | "op-dispute-game" | "op-state-root" | "op-challenge-period" | "base-bridge-state-root" | "cctp-attestation" | "arb-confirmation" | "linea-block-anchored";
waitStatus: "done";
actualDuration?: number;
expectedDuration: number;
}
```
#### WaitStepInProgress
A wait step currently in progress.
```typescript
interface WaitStepInProgressDto {
type: "wait";
waitType: "general" | "refund" | "op-dispute-game" | "op-state-root" | "op-challenge-period" | "base-bridge-state-root" | "cctp-attestation" | "arb-confirmation" | "linea-block-anchored";
waitStatus: "in-progress";
startedAt: number;
expectedDuration: number;
}
```
#### WaitStepNotStarted
A wait step that has not started yet.
```typescript
interface WaitStepNotStartedDto {
type: "wait";
waitType: "general" | "refund" | "op-dispute-game" | "op-state-root" | "op-challenge-period" | "base-bridge-state-root" | "cctp-attestation" | "arb-confirmation" | "linea-block-anchored";
waitStatus: "not-started";
expectedDuration: number;
}
```
#### WaitStepInvalidated
A wait step invalidated by a protocol upgrade event.
```typescript
interface WaitStepInvalidatedDto {
type: "wait";
waitType: "general" | "refund" | "op-dispute-game" | "op-state-root" | "op-challenge-period" | "base-bridge-state-root" | "cctp-attestation" | "arb-confirmation" | "linea-block-anchored";
waitStatus: "invalidated";
actualDuration?: number;
invalidatedBy: UpgradeEventDto;
expectedDuration: number;
}
```
#### UpgradeEvent
A protocol upgrade event that can invalidate earlier wait or transaction steps.
```typescript
interface UpgradeEventDto {
type: "upgrade-event";
upgradeType: "op-upgrade-fault-proofs" | "arb-upgrade-bold";
upgradeSubType: "op-upgrade-fault-proofs" | "op-respected-game-type-change" | "op-upgrade-13" | "op-retirement-timestamp-change" | "arb-bold-upgrade";
// Chain UUID (internal identifier)
chainUid: string;
// Native chain ID (e.g. 1 for Ethereum)
chainId: string;
// Shorthand chain identifier (e.g. eth for Ethereum)
chainKeys: string[];
timestamp: number;
blockNumber: number;
}
```
#### Confirmation
Transaction confirmation details.
```typescript
interface ConfirmationDtoV2 {
timestamp: number;
transactionHash: string;
status: "confirmed" | "reverted" | "dropped";
}
```
#### BlockExplorer
```typescript
interface BlockExplorer {
url: string;
family: "etherscan" | "blockscout" | "routescan" | "starkscan" | "other";
}
```
#### EvmNotReadyStepGasEstimate
```typescript
interface EvmNotReadyStepGasEstimateDto {
vm: "evm";
gasLimit: number;
}
```
#### SvmNotReadyStepGasEstimate
```typescript
interface SvmNotReadyStepGasEstimateDto {
vm: "svm";
computeUnitLimit: number;
price: number;
signatures: number;
}
```
#### StarkNotReadyStepGasEstimate
```typescript
interface StarkNotReadyStepGasEstimateDto {
vm: "stark";
l1GasAmount: number;
l1DataGasAmount: number;
l2GasAmount: number;
l1GasPrice?: string;
l1DataGasPrice?: string;
l2GasPrice?: string;
}
```
#### Provider
Display information for a route provider.
```typescript
interface ProviderDto {
id: string;
name: string;
icon: string;
}
```
# SDK
## Getting Started
---
Source: https://docs.superbridge.app/sdk
---
The Superbridge SDK is a type-safe TypeScript wrapper around the [Superbridge API](https://docs.superbridge.app/api-reference). It provides fully typed request and response objects generated from the OpenAPI spec.
#### Installation
#### Quick Start
```typescript
import { createClient } from '@superbridge/sdk';
const sb = createClient({
apiKey: 'your-api-key',
});
const routes = await sb.getRoutes({
fromChainKey: 'eth',
toChainKey: 'base',
fromTokenAddress: '0x0000000000000000000000000000000000000000',
toTokenAddress: '0x0000000000000000000000000000000000000000',
amount: '1000000000000000000',
slippage: 0.005,
});
```
#### Methods
The SDK exposes one method per public API endpoint: `health`, `getChains`, `getTokens`, `getToken`, `getRoutes`, `getActivity`, `getStepTransaction`, `indexTransaction`, and `submitGasless`.
#### Learn More
The SDK mirrors the [Superbridge API](https://docs.superbridge.app/api-reference) 1:1. For understanding bridging flows, response types, error handling, and transaction lifecycle, see the [API Reference](https://docs.superbridge.app/api-reference) — everything there applies directly to the SDK.
## Reference
---
Source: https://docs.superbridge.app/sdk/examples
---
End-to-end examples of common bridging flows using the Superbridge SDK with viem. See [Type Guards](https://docs.superbridge.app/sdk/type-guards) for narrowing helpers used throughout.
#### Bridge ETH from Ethereum to Base
This example fetches a route, signs and sends the initiating transaction, then polls for completion.
```typescript
import { createClient, guards } from '@superbridge/sdk';
import { createPublicClient, createWalletClient, http, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';
const sb = createClient({ apiKey: 'your-api-key' });
const account = privateKeyToAccount('0x...');
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(),
});
// 1. Get a route
const response = await sb.getRoutes({
fromChainKey: 'eth',
toChainKey: 'base',
fromTokenAddress: '0x0000000000000000000000000000000000000000',
toTokenAddress: '0x0000000000000000000000000000000000000000',
amount: parseUnits('0.01', 18).toString(),
sender: account.address,
recipient: account.address,
slippage: 0.005,
});
if (guards.routes.isError(response)) {
throw new Error(`Route unavailable: ${response.type}`);
}
// 2. Find the first usable quote
const quote = response.results
.map((r) => r.result)
.find(guards.quotes.isQuote);
if (!quote) throw new Error('No quote available');
// 3. Narrow and send the initiating transaction
const { initiatingTransaction } = quote;
if (initiatingTransaction.type !== 'evm') {
throw new Error('Expected an EVM transaction');
}
const hash = await walletClient.sendTransaction({
to: initiatingTransaction.to,
data: initiatingTransaction.data,
value: BigInt(initiatingTransaction.value),
});
console.log('Transaction sent:', hash);
// 4. Wait for the transaction to be confirmed
await publicClient.waitForTransactionReceipt({ hash });
// 5. Poll activity until the bridge is complete
async function pollUntilComplete() {
while (true) {
const activities = await sb.getActivity({ txHash: hash });
const bridge = activities[0];
if (!bridge) {
await new Promise((r) => setTimeout(r, 5000));
continue;
}
// Check if all steps are done
const allDone = bridge.steps.every((s) =>
s.type === 'transaction'
? s.transactionType === 'done' || s.transactionType === 'auto'
: s.type === 'wait'
? s.waitType === 'done'
: true,
);
if (allDone) {
console.log('Bridge complete!');
return bridge;
}
// Check for a step that needs signing
const readyStep = bridge.steps.find(
(s) => s.type === 'transaction' && s.transactionType === 'ready',
);
if (readyStep) {
const stepTx = await sb.getStepTransaction({
id: bridge.id,
action: readyStep.action,
submitter: account.address,
});
if (stepTx.type !== 'evm') {
throw new Error('Expected an EVM step transaction');
}
const stepHash = await walletClient.sendTransaction({
to: stepTx.to,
data: stepTx.data,
value: BigInt(stepTx.value),
});
await publicClient.waitForTransactionReceipt({ hash: stepHash });
console.log('Step transaction sent:', stepHash);
}
// Wait using nextCheckTimestamp
const delay = bridge.nextCheckTimestamp
? Math.max(bridge.nextCheckTimestamp - Date.now(), 2000)
: 5000;
await new Promise((r) => setTimeout(r, delay));
}
}
await pollUntilComplete();
```
#### Handling approvals (ERC-20 transfers)
When transferring ERC-20 tokens, the route quote may include approval transactions that must be submitted before the initiating transaction.
```typescript
import { createClient, guards } from '@superbridge/sdk';
const sb = createClient({ apiKey: 'your-api-key' });
const response = await sb.getRoutes({ /* ... */ });
if (guards.routes.isError(response)) {
throw new Error(`Route unavailable: ${response.type}`);
}
const quote = response.results
.map((r) => r.result)
.find(guards.quotes.isQuote);
if (!quote) throw new Error('No quote available');
// Some tokens (e.g. USDT) require revoking existing allowance first
if (quote.revokeTokenApproval) {
const revokeHash = await walletClient.sendTransaction({
to: quote.revokeTokenApproval.tx.to,
data: quote.revokeTokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: revokeHash });
}
if (quote.tokenApproval) {
const approveHash = await walletClient.sendTransaction({
to: quote.tokenApproval.tx.to,
data: quote.tokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: approveHash });
}
// Custom gas token rollups may also require a gas token approval
if (quote.gasTokenApproval) {
const gasApproveHash = await walletClient.sendTransaction({
to: quote.gasTokenApproval.tx.to,
data: quote.gasTokenApproval.tx.data,
});
await publicClient.waitForTransactionReceipt({ hash: gasApproveHash });
}
// Now send the initiating transaction
if (quote.initiatingTransaction.type !== 'evm') {
throw new Error('Expected an EVM transaction');
}
const hash = await walletClient.sendTransaction({
to: quote.initiatingTransaction.to,
data: quote.initiatingTransaction.data,
value: BigInt(quote.initiatingTransaction.value),
});
```
---
Source: https://docs.superbridge.app/sdk/type-guards
---
The SDK includes type guard helpers for working with the various discriminated unions returned by the API.
```typescript
import { guards } from '@superbridge/sdk';
```
#### Route Guards
`getRoutes()` resolves to either a `RouteResponse` (success) or a `RouteError` (top-level error such as the entire route being paused or exceeding the global USD cap). Use `guards.routes` to narrow.
```typescript
const response = await sb.getRoutes({ /* ... */ });
if (guards.routes.isError(response)) {
// RouteError - discriminate on `type`
if (response.type === 'Paused') {
// PausedRouteErrorDto
}
if (response.type === 'Disabled') {
// DisabledRouteErrorDto
}
if (response.type === 'SlippageTooHigh') {
// SlippageTooHighRouteErrorDto - has slippagePercent, maximumSlippagePercent
}
return;
}
// guards.routes.isResponse(response) - has `results`
const { results } = response;
```
#### Quote Guards
Each entry in `RouteResponse.results[]` has a `result` field that is either a `QuoteDto` (a usable quote with an `initiatingTransaction`) or a `QuoteError` (a per-provider error such as `AmountTooSmall`). Use `guards.quotes` to narrow.
```typescript
for (const route of response.results) {
if (guards.quotes.isQuote(route.result)) {
// QuoteDto - has initiatingTransaction, fees, steps, receive
}
if (guards.quotes.isError(route.result)) {
// QuoteError - discriminate on `type`
}
}
```
Once narrowed to an error, discriminate on `type` directly — TypeScript will narrow to the specific error DTO.
```typescript
for (const route of response.results) {
if (!guards.quotes.isError(route.result)) continue;
const error = route.result;
if (error.type === 'AmountTooLarge') {
// AmountTooLargeQuoteErrorDto - has maximum
}
if (error.type === 'AmountTooSmall') {
// AmountTooSmallQuoteErrorDto - has minimum
}
if (error.type === 'PriceImpactTooHigh') {
// PriceImpactTooHighQuoteErrorDto - has priceImpactPercent, maximumPriceImpactPercent
}
if (error.type === 'GenericError') {
// GenericQuoteErrorDto - has error
}
// 'Paused' | 'Disabled' | 'EscapeHatchNotSupported' | 'ERC777MintToSmartContract'
}
```
#### Gas Estimate Guards
`TransactionStepNotReadyDto.estimatedGas` is shaped per chain family. Narrow on `vm`.
```typescript
for (const step of bridge.steps) {
if (step.type !== 'transaction' || step.transactionStatus !== 'not-ready') {
continue;
}
const gas = step.estimatedGas;
if (gas.vm === 'evm') {
// EvmNotReadyStepGasEstimateDto - has gasLimit
}
if (gas.vm === 'svm') {
// SvmNotReadyStepGasEstimateDto - has computeUnitLimit
}
if (gas.vm === 'stark') {
// StarkNotReadyStepGasEstimateDto - has l1GasAmount, l1DataGasAmount, l2GasAmount
}
}
```
#### Narrowing transactions and steps
Initiating transactions and activity steps don't have dedicated guards — narrow on the discriminating property directly.
```typescript
// Initiating transaction - discriminated by `type`
const { initiatingTransaction } = quote;
if (initiatingTransaction.type === 'evm') {
// InitiatingTransactionEvmDto - has to, data, value
}
if (initiatingTransaction.type === 'evm-gasless') {
// InitiatingTransactionEvmGaslessDto - has typedData
}
if (initiatingTransaction.type === 'svm') {
// InitiatingTransactionSvmDto - has data (base64)
}
if (initiatingTransaction.type === 'starknet') {
// InitiatingTransactionStarkDto - has calls
}
```
Steps narrow on `type`, then on `transactionStatus` / `waitStatus`.
```typescript
for (const step of bridge.steps) {
if (step.type === 'transaction') {
if (step.transactionStatus === 'ready') {
// TransactionStepReadyDto - fetch via getStepTransaction
}
if (step.transactionStatus === 'done') {
// TransactionStepDoneDto - has confirmation
}
if (step.transactionStatus === 'not-ready') {
// TransactionStepNotReadyDto - has estimatedGas
}
if (step.transactionStatus === 'auto') {
// TransactionStepAutoDto - executed automatically
}
if (step.transactionStatus === 'invalidated') {
// TransactionStepInvalidatedDto - has confirmation, invalidatedBy
}
}
if (step.type === 'wait') {
if (step.waitStatus === 'not-started') {
// WaitStepNotStartedDto
}
if (step.waitStatus === 'in-progress') {
// WaitStepInProgressDto - has startedAt
}
if (step.waitStatus === 'done') {
// WaitStepDoneDto - has actualDuration
}
if (step.waitStatus === 'invalidated') {
// WaitStepInvalidatedDto - has actualDuration, invalidatedBy
}
}
if (step.type === 'upgrade-event') {
// UpgradeEventDto - can be referenced by invalidated steps
}
}
```
# CLI
## Getting Started
---
Source: https://docs.superbridge.app/cli
---
The Superbridge CLI is a command-line wrapper around the [Superbridge API](https://docs.superbridge.app/api-reference) and [SDK](https://docs.superbridge.app/sdk). Read-only endpoints are exposed as subcommands; on-chain execution is funnelled through a single `execute` command that handles approvals, the initiating transaction, indexing, gasless intent submission, and step polling for you.
#### Installation
Install globally to get the `superbridge` binary on your `PATH`:
Or run a one-off without installing:
Every example in these docs uses the globally-installed `superbridge` binary, but you can prefix any command with your package manager's runner (`npx`, `pnpx`, `yarn dlx`, `bunx`) to run it without installing.
#### Quick Start
Set your API key as an environment variable, then run any read-only command:
```bash
export SUPERBRIDGE_API_KEY=sb_live_...
superbridge health
superbridge chains
superbridge tokens --chain-key eth --search USDC
```
Every command pretty-prints to stdout by default — tables for lists, formatted summaries for single objects. To get raw JSON instead (for piping into [`jq`](https://jqlang.github.io/jq/) or other tools), pass `--output json`:
```bash
superbridge chains --mainnets --output json | jq '.[] | {key, name, chainId}'
```
#### Conventions
- **Human format on stdout, status on stderr.** Output is pretty-printed by default; pass `--output json` to get raw JSON. Progress messages and errors always go to stderr, so piped JSON output stays clean.
- **Env first, flags override.** Anywhere you can pass `--api-key`, the corresponding `SUPERBRIDGE_API_KEY` env var works too. The flag wins if both are set.
- **Body-heavy commands accept inline, file, or stdin.** `routes` accepts an inline JSON string, `@path/to/file.json` to read from a file, or `-` to read from stdin. Individual flags override fields from the body.
#### Next Steps
- [Authentication](https://docs.superbridge.app/cli/authentication) — API keys and private keys for signing.
- [Commands](https://docs.superbridge.app/cli/commands) — full command reference.
- [Examples](https://docs.superbridge.app/cli/examples) — end-to-end workflows including executing a route.
---
Source: https://docs.superbridge.app/cli/authentication
---
The CLI needs two kinds of credentials:
- An **API key** for every command (read-only or otherwise).
- One or more **private keys** when running `execute`, which signs and submits transactions on your behalf.
#### API Key
To obtain an API key, get in touch with the Superbridge team.
The CLI looks for your key in this order:
1. `--api-key ` flag
2. `SUPERBRIDGE_API_KEY` environment variable
```bash
export SUPERBRIDGE_API_KEY=sb_live_...
superbridge health
```
#### Private Keys
The `execute` command signs transactions for one or more virtual machines depending on the route. The CLI supports keys for **EVM** chains, **SVM** (Solana) chains, and **Starknet**.
For each VM, keys are loaded with this precedence:
1. `---private-key ` flag — convenient but **leaks into shell history**, so the CLI prints a warning when you use it.
2. `---private-key-file ` flag — reads the key from a file.
3. `_PRIVATE_KEY` environment variable.
##### EVM
```bash
export EVM_PRIVATE_KEY=0xabc...
```
A 32-byte hex string with or without the `0x` prefix.
##### SVM (Solana)
```bash
export SVM_PRIVATE_KEY=...
```
Three formats are accepted:
- **Base58** (the format Phantom exports).
- **Hex** (with or without `0x`).
- **JSON byte array** (the format `solana-keygen` writes — useful with `--svm-private-key-file ~/.config/solana/id.json`).
##### Starknet
```bash
export STARK_PRIVATE_KEY=0x...
export STARK_ACCOUNT_ADDRESS=0x...
```
Starknet additionally requires the **account contract address**, which is distinct from the public key derivation. Pass it via `--stark-account-address` or `STARK_ACCOUNT_ADDRESS`.
#### Best Practices
- **Prefer env vars or files** — never pass keys inline in shared shells or CI logs.
- **Keep API keys server-side** — don't bake them into client-side scripts that ship to users.
- **Use a fresh key for automation** — rotate via the Superbridge team if anything is exposed.
- **Scope your shell session** — `export` keys in a subshell or use a tool like `direnv` so they don't linger in your environment.
## Reference
---
Source: https://docs.superbridge.app/cli/commands
---
Every command accepts the [global flags](#global-flags) below in addition to its own arguments. Run `superbridge --help` for the canonical, up-to-date list.
#### Global Flags
Every command pretty-prints to stdout by default. Pass `--output json` to get raw JSON instead — useful for piping into [`jq`](https://jqlang.github.io/jq/), saving to a file, or feeding into another command.
| Flag | Description |
| --- | --- |
| `--api-key` | Override `SUPERBRIDGE_API_KEY` for this invocation. |
| `--output` | `pretty` (default) or `json`. |
#### `health`
Check the API is reachable and your key works.
```bash
superbridge health
```
#### `chains`
List supported chains. Without filters, returns every chain Superbridge knows about.
| Flag | Description |
| --- | --- |
| `--key` | Filter by shorthand chain key (e.g. `eth`). |
| `--id` | Filter by native chain id (e.g. `1`). |
| `--uid` | Filter by Superbridge chain UID. |
| `--mainnets` | Restrict to mainnet chains. |
| `--testnets` | Restrict to testnet chains. |
```bash
superbridge chains --mainnets
superbridge chains --key eth --output json | jq '.[0]'
```
#### `tokens`
List tokens, optionally filtered by chain or search term. Cursor-paginated.
| Flag | Description |
| --- | --- |
| `--address` | Filter by token address. |
| `--chain-key`, `--chain-id`, `--chain-uid` | Filter by chain. |
| `--search` | Search by name, symbol, or address. |
| `--cursor` | Cursor for fetching the next page of results. |
| `--limit` | Page size (1–100). |
```bash
superbridge tokens --chain-key eth --search USDC --limit 5
```
#### `routes`
Fetch available routes for a bridge or swap. Body-heavy — pass the request via `--body`, with individual flags overriding fields.
| Flag | Description |
| --- | --- |
| `--body` | Request body as inline JSON, `@path/to/file.json`, or `-` for stdin. |
| `--from-chain-key`, `--from-chain-id`, `--from-chain-uid` | Source chain. |
| `--to-chain-key`, `--to-chain-id`, `--to-chain-uid` | Destination chain. |
| `--from-token`, `--to-token` | Token addresses (`0x000...0` for native). |
| `--sender`, `--recipient` | Addresses involved in the route. If omitted, a default address is derived for the source/destination chain's VM. |
| `--amount` | Amount in human units (e.g. `0.01` for 0.01 ETH or USDC). The CLI scales by the from-token's decimals. |
| `--slippage` | Slippage as a decimal (e.g. `0.005` for 0.5%). |
| `--provider` | Comma-separated list of providers to restrict the search to. |
```bash
superbridge routes \
--from-chain-key eth \
--to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01
```
Or pass an entire request as JSON:
```bash
superbridge routes --body @route-request.json
```
See the [Routes API reference](https://docs.superbridge.app/api-reference/routes) for the full request schema.
#### `activity`
Fetch bridge activity (history). All filters are optional; without any, you'll get the most recent items.
| Flag | Description |
| --- | --- |
| `--tx-hash` | Filter by initiating transaction hash. |
| `--address` | Filter by sender or recipient address. |
| `--status` | `pending` or `done` (default: all). |
| `--type` | `mainnets` or `testnets` (default: all). |
| `--page-size` | Max 30. |
| `--from-chain-*`, `--to-chain-*` | Chain filters (key / id / uid). |
```bash
superbridge activity --tx-hash 0xabc...
superbridge activity --address 0xYourAddress --status pending
```
#### `step`
Find a ready step for an in-flight bridge, build its transaction, walk through signing/submission, and poll until the step status changes. Used during long-running flows where the user has to sign a follow-up transaction (for example, a `Prove` or `Finalise` step on an OP Stack rollup).
| Flag | Description |
| --- | --- |
| `--tx-hash` | Initiating transaction hash. |
| `--action` | `RouteAction` — e.g. `Approve`, `Initiate`, `Prove`, `Finalise`, `Refund`. |
| `--yes` | Skip the confirmation prompt. |
```bash
superbridge step \
--tx-hash 0xabc... \
--action Prove
```
In most cases you should let `execute` handle follow-up steps for you — see below.
#### `execute`
Quote a bridge interactively, pick a provider, and run it end-to-end: any required revoke / approval / gas-token-approval transactions, the initiating transaction (or a gasless intent), then activity polling with automatic step dispatch until the bridge is complete.
This command needs a [private key](https://docs.superbridge.app/cli/authentication#private-keys) for the from-chain's VM. Sender and recipient are derived from your wallet — pass `--recipient` to send somewhere else.
| Flag | Description |
| --- | --- |
| `--from-chain-key` / `--from-chain-id` / `--from-chain-uid` | Source chain. **Required.** |
| `--to-chain-key` / `--to-chain-id` / `--to-chain-uid` | Destination chain. **Required.** |
| `--from-token` / `--to-token` | Token addresses (`0x000...0` for native). **Required.** |
| `--amount` | Amount in human units (e.g. `0.01` for 0.01 ETH or USDC). The CLI scales by the from-token's decimals. **Required.** |
| `--slippage` | Slippage as a decimal (e.g. `0.005`). Default `0.005`. |
| `--recipient` | Override the recipient address (defaults to your wallet on the to-chain). |
| `--provider` | Pre-select a provider by id or name, skipping the picker. |
| `--yes` | Skip the confirmation prompt. |
| `--no-wait` | Submit the initiating transaction and exit without polling. |
| `--evm-private-key` / `--evm-private-key-file` | EVM signing key (or `EVM_PRIVATE_KEY`). |
| `--svm-private-key` / `--svm-private-key-file` | SVM signing key (or `SVM_PRIVATE_KEY`). |
| `--stark-private-key` / `--stark-private-key-file` | Starknet signing key (or `STARK_PRIVATE_KEY`). |
| `--stark-account-address` | Starknet account contract address (or `STARK_ACCOUNT_ADDRESS`). |
```bash
export EVM_PRIVATE_KEY=0x...
superbridge execute \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01
```
The CLI fetches quotes, prompts you to choose a provider, confirms the action, then logs progress to stderr (`› evm tx sent on Ethereum: 0x...`) until the bridge is complete.
For non-interactive use (CI, scripts), pass `--provider ` and `--yes`.
`index-transaction` and `submit-gasless` are intentionally not exposed as subcommands — they're called automatically by `execute` and aren't useful in isolation.
---
Source: https://docs.superbridge.app/cli/examples
---
Common workflows for the Superbridge CLI. All examples assume `SUPERBRIDGE_API_KEY` is set in your environment.
#### Run without installing
Every example below uses the globally-installed `superbridge` binary. If you'd rather not install anything, prefix the command with your package manager's runner:
The same prefix works for any subcommand:
For repeated use — and especially for `execute`, which runs a long-lived poll loop — install the CLI globally instead. Each `npx` / `dlx` invocation re-resolves the package and is meaningfully slower to start.
#### Bridge ETH from Ethereum to Base
`execute` is interactive — it fetches quotes, lets you pick a provider, confirms the action, then runs the bridge end-to-end.
```bash
export EVM_PRIVATE_KEY=0xabc...
superbridge execute \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01
```
`execute` handles approvals (if any), submits the initiating transaction, then polls activity and dispatches any follow-up step transactions until the bridge is `done`. Sender and recipient are derived from your wallet; pass `--recipient` to send to a different address.
#### Inspect quotes before executing
`routes` shows the same set of quotes that `execute` will pick from. Use it to scout fees, expected duration, and which providers cover the pair before committing.
```bash
superbridge routes \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01
# When ready, run execute with the provider you want
superbridge execute \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01 \
--provider Across
```
#### Submit and exit without waiting
Bridges can take minutes to hours depending on the provider and chain. To submit the initiating transaction and return immediately, pass `--no-wait`:
```bash
superbridge execute \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount 0.01 \
--provider Across --yes --no-wait
```
You can later poll status with `activity`:
```bash
superbridge activity --tx-hash
```
#### Bridge from Solana
Provide an SVM key. The CLI will dispatch the SVM-shaped initiating transaction automatically.
```bash
export SVM_PRIVATE_KEY=...
superbridge execute \
--from-chain-key sol --to-chain-key eth \
--from-token \
--to-token \
--amount 1 \
--recipient 0xYourEvmAddress
```
For cross-VM bridges, you must pass `--recipient` (or set both `EVM_PRIVATE_KEY` and `SVM_PRIVATE_KEY` so the CLI can derive the destination address from your wallet).
#### Run from a CI script
`execute` requires `--provider` and `--yes` in non-interactive contexts (no TTY) so a missed prompt can't block the script:
```bash
#!/usr/bin/env bash
set -euo pipefail
superbridge execute \
--from-chain-key eth --to-chain-key base \
--from-token 0x0000000000000000000000000000000000000000 \
--to-token 0x0000000000000000000000000000000000000000 \
--amount "$1" \
--provider Across \
--yes
```
#### Filter token lists with `jq`
Pass `--output json` to get raw JSON output that's pipe-friendly:
```bash
# Top 10 USDC variants across all chains
superbridge tokens --search USDC --limit 10 --output json \
| jq '.tokens[] | {symbol, name, chain: .chain.name, address}'
# Just the chain IDs of every supported mainnet
superbridge chains --mainnets --output json | jq -r '.[].chainId' | sort -n
```
#### Build a route request from a JSON file
Hand-craft or template a request to keep flags out of your shell history:
```json
{
"fromChainKey": "eth",
"toChainKey": "base",
"fromTokenAddress": "0x0000000000000000000000000000000000000000",
"toTokenAddress": "0x0000000000000000000000000000000000000000",
"amount": "10000000000000000",
"sender": "0xYourAddress",
"recipient": "0xYourAddress",
"slippage": 0.005
}
```
The JSON body matches the API request shape — `amount` is in wei / smallest denomination (this is `0.01` ETH).
```bash
superbridge routes --body @request.json
```
Flags can still override individual fields — handy for templating an amount. Unlike the JSON body, `--amount` is in human units and the CLI scales it by the from-token's decimals:
```bash
superbridge routes --body @request.json --amount 0.05
```
# Widget
## Getting Started
---
Source: https://docs.superbridge.app/widget
---
The Superbridge Widget is a drop-in React component that adds cross-chain bridging and swapping to your application.
#### Installation
##### Peer dependencies
The widget requires the following peer dependencies:
- `react` >= 19
- `react-dom` >= 19
- `wagmi` >= 3
- `@tanstack/react-query` >= 5
#### Quick start
```tsx
import { Widget } from "@superbridge/widget";
import "@superbridge/widget/styles.css";
function App() {
return ;
}
```
#### Props
All props are optional. The full set is typed by `WidgetProps` exported from `@superbridge/widget` — your editor will autocomplete and document them inline. The most common ones:
##### Appearance
| Prop | Type | Description |
| --- | --- | --- |
| `theme.cssVariables` | `WidgetCssVariables` | CSS variable overrides for colors, fonts, radius, and per-shape tokens. See [Theming](https://docs.superbridge.app/widget/theming). |
| `theme.motion` | `MotionProps` | Per-element hover/tap/open transitions. See [Theming](https://docs.superbridge.app/widget/theming). |
| `theme.textAnimation` | `AnimatedNumberComponent` | Custom component used to render every animated number in the widget. Must accept `{ value, format?, className? }`. Defaults to a plain formatted span — drop in a flow / scramble / count renderer to animate. |
##### Data & API
| Prop | Type | Description |
| --- | --- | --- |
| `apiUrl` | `string` | Override the Superbridge API base URL. Defaults to production. |
| `localDevelopmentApiKey` | `string` | Dev-only API key for use on `localhost`. See [Local development](https://docs.superbridge.app/widget/local-development). |
##### Initial selection
| Prop | Type | Description |
| --- | --- | --- |
| `defaultFromChainUid` / `defaultFromChainId` / `defaultFromChainKey` | `string` | Initial source chain. Changes after initialization do not reset user selection. |
| `defaultToChainUid` / `defaultToChainId` / `defaultToChainKey` | `string` | Initial destination chain. Changes after initialization do not reset user selection. |
| `defaultFromTokenAddress` | `string` | Initial source token. Changes after initialization do not reset user selection. |
| `defaultToTokenAddress` | `string` | Initial destination token. Changes after initialization do not reset user selection. |
##### Wallets
| Prop | Type | Description |
| --- | --- | --- |
| `openEvmWalletModal` | `() => void` | Open your own EVM wallet picker instead of the built-in modal. See [Wallet management](https://docs.superbridge.app/widget/wallet-management). |
| `openSvmWalletModal` | `() => void` | Open your own Solana wallet picker. |
| `openStarkWalletModal` | `() => void` | Open your own Starknet wallet picker. |
##### Localization
| Prop | Type | Description |
| --- | --- | --- |
| `defaultLanguage` | `string` | Initial locale code (e.g. `'en'`, `'es'`). The widget owns language changes after initialization. |
##### Behavior
| Prop | Type | Description |
| --- | --- | --- |
| `keyboardShortcuts` | `boolean` | Enable shortcuts like `f` to open the from-token selector. Default `false`. |
| `portalTarget` | `HTMLElement` | Render modals into this element instead of an internal portal. Must have (or live inside) the `.sb-widget` class so scoped styles apply. |
| `onEvent` | `(event: WidgetEvent) => void` | Subscribe to widget events for analytics, logging, or app-side reactions. |
## Guides
---
Source: https://docs.superbridge.app/widget/local-development
---
To use the Superbridge Widget during local development, you need to pass `localDevelopmentApiKey`.
```tsx
import { Widget } from "@superbridge/widget";
```
You can find your local development API key in the Rollie dashboard.
> The `localDevelopmentApiKey` is intended for local development only. Do not expose it in production builds. Make sure it is excluded from your production bundle — for example, by loading it from an environment variable that is only set in development.
>
> In production, the widget picks up your Rollie configuration from the domain it loads into, so no API key is required.
---
Source: https://docs.superbridge.app/widget/theming
---
The widget is themed entirely through CSS variables. Pass an object of overrides to `theme.cssVariables` — they're written onto the widget's host element, so everything inside reacts.
```tsx
import { Widget } from "@superbridge/widget";
```
The `cssVariables` object is fully typed via `WidgetCssVariables` — your editor autocompletes every available token, so the reference list below is intentionally high-level.
#### Variable groups
The variables fall into a few categories:
##### Colors
Semantic color roles, each with a background, a `-foreground` for text/icons on top, and an `-outline` for the border ring.
- `--color-foreground` — default body text
- `--color-card` / `--color-popover` — main surfaces and floating menus
- `--color-primary` / `--color-secondary` / `--color-muted` / `--color-accent` / `--color-destructive` — action roles
- `--color-border`, `--color-input`, `--color-ring` — separators, input borders, focus rings
##### Typography
- `--font-heading`, `--font-button`, `--font-body` — font families per role
- `--tracking-heading`, `--tracking-button`, `--tracking-body` — letter-spacing per role
See [Styling fonts](#styling-fonts) below.
##### Radius
- `--radius` — base radius. The full `--radius-2xs` … `--radius-4xl` scale is derived from this via `calc()`, so retuning the base retunes everything.
#### Styling fonts
Font variables accept any valid CSS `font-family` value. To use a custom font, load it yourself with `@font-face` (or a `` to a hosted provider) and then point the variables at it:
```css
/* your-app.css */
@font-face {
font-family: "Acme Display";
src: url("/fonts/acme-display.woff2") format("woff2");
font-display: swap;
}
@font-face {
font-family: "Acme Text";
src: url("/fonts/acme-text.woff2") format("woff2");
font-display: swap;
}
```
```tsx
```
Tips:
- Always include a system fallback stack — the widget renders before your font finishes loading.
- Prefer `woff2` and `font-display: swap` to avoid invisible text during load.
- Hosted fonts (Google Fonts, Fontsource, etc.) work the same way — load the stylesheet, then reference the family name.
- If `--font-button` is unset it inherits whatever the surrounding role uses; set it explicitly when you want buttons to look distinct from headings.
---
Source: https://docs.superbridge.app/widget/wallet-management
---
The widget supports three virtual machine ecosystems: **EVM**, **Solana (SVM)**, and **Starknet**. For each, you can either let the widget manage wallet connections itself or provide your own wallet UI.
#### Using the built-in wallet modal
By default, the widget sets up wallet providers and renders its own wallet selection modal.
- **EVM** — Creates a minimal Wagmi config. Discovers installed wallets via [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) and includes a WalletConnect fallback.
- **SVM** — Wraps itself in a Solana `ConnectionProvider` and `WalletProvider`.
- **Starknet** — Provides a default `StarknetConfig` with Braavos and Argent connectors.
#### Providing your own wallet providers
If your app already has wallet providers set up (e.g. a `WagmiProvider` higher in the tree), wrap the widget with `WidgetExternalWalletProvider`. This initializes the widget runtime and state without installing the widget's default wallet providers, so wallet hooks read from your existing contexts.
```tsx
import { Widget } from "@superbridge/widget";
import { internals } from "@superbridge/widget/internals";
const { WidgetExternalWalletProvider } = internals;
function Bridge() {
return (
);
}
```
When you support Solana or Starknet routes, make sure the matching Solana wallet adapter or Starknet provider is also present above `WidgetExternalWalletProvider`.
#### Composing the default wallet providers
Apps that want to reuse the widget's default wallet providers while owning the surrounding wallet UI can compose the provider layers manually:
```tsx
import { internals } from "@superbridge/widget/internals";
const {
WidgetRuntimeProvider,
WidgetStateProvider,
WidgetView,
WidgetWalletProvider,
} = internals;
function Bridge() {
return (
openWalletDrawer(),
}}
>
);
}
```
`Widget` composes these layers for the default drop-in behavior.
#### Using your own wallet modal
If you want full control over the wallet connection UI, pass modal callbacks. When provided, the widget hides its built-in connect buttons for that ecosystem and calls your function instead.
```tsx
{
// Open your custom EVM wallet picker
}}
openSvmWalletModal={() => {
// Open your custom Solana wallet picker
}}
openStarkWalletModal={() => {
// Open your custom Starknet wallet picker
}}
/>
```
You can mix and match — for example, provide your own EVM modal while letting the widget handle Solana and Starknet.