Changelog

Jake Loo

Overview

This release focuses on improving reliability, performance, and user experience with several key enhancements:

  1. Universal Bridge: Enables bridge and swapping
  2. Search: Enhances search capability to improve onchain knowledge and optimizes thirdweb documentation search and access
  3. Contract Interaction: Simulates transactions result and improves contract information retrieval
  4. Performance: Improves contract interaction latency and performance

Improvements & Fixes

  • Improves token balance display with native token support
  • Fixes intermittent failure when interacting with newly deployed contracts
  • Improves error message formatting with actionable suggestions
  • Improves handling of missing contracts with better error messages
Jake Loo

This release significantly enhances Nebula's blockchain integration capabilities with a focus on improved multichain support, better token and NFT handling, and more robust authentication.

The model has been upgraded to provide more accurate and consistent responses more quickly. Users can now see the model's step-by-step thinking process as it performs tasks.

New approach to chain management. By default, only mainnet chains are enabled, to enable testnet requires setting context.networks = "testnet" in the /chat endpoint. The Chain IDs in the context may also be updated through conversations.

Breaking Changes 🔨

  • Model Updates: Experience more accurate and consistent responses with the improved t0_003 model.
  • Chain Management: Defaults to mainnet only. Enabling testnets require specific flag in the context. By setting, context.networks = "testnet"
  • Delegate Auth: Create a SIWE delegated auth tokens for scoped API access to chat and session.

Features ✨

Improvements

  • Guided Tool Prompts: More accurate tool selection by AI agents, resulting in fewer errors and more relevant responses.
  • Improved Output Consistency: More standardized and predictable response formats, making automated parsing of outputs more reliable.
  • Chain ID Parameter Prioritization: Explicit control over which blockchain they're interacting with, reducing confusion and errors from context-switching
  • Comprehensive Blockchain Data Retrieval: Access detailed information about blocks, transactions, and events, enabling more complex analyses within the tool.
  • Multi-chain Insight Support: Perform cross-chain operations and comparisons without needing to use separate tools or interfaces.
  • Domain Name Resolution: Interact with human-readable domain names (like ENS) instead of complex addresses, improving usability.
  • Human-readable Timestamps: See dates and times in standard formats rather than UNIX epochs, making information immediately understandable.

Token & NFT Support

  • Creating Assets: create different token standards (ERC20, ERC721, ERC1155) more easily.
  • NFT Collection Name Display: Friendly collection names rather than just contract addresses, making NFT identification more intuitive.
  • Better Wallet Balance Display: Updated token balances with proper decimal divisions, showing correct human-readable amounts. Correct token names for native blockchain currencies (e.g., ETH, MATIC).

Authentication

  • Nebula Auth Method: Developer can delegate scoped account access, improving security while maintaining functionality.
  • Smart Account Validator: Smart contract wallets (using ERC-1271 and ERC-6492) can now authenticate with Nebula Auth.
Greg

We just released one of our biggest updates yet to the Universal Bridge API. These changes will be coming soon to the SDK and UI components.

The new response schema includes a steps field, which gives you all the info you need to build a comprehensive bridge and swap UI. This includes token metadata, price, expected execution time, input and output amounts, and the transactions to be executed.

A buy, sell, or transfer prepared quote will now look something like this:

{
"data": {
"id": "0x11cb09cf545d9c1c1cc12aa20aaee180a59336ec72701b148f452734c50f1bbf",
"originAmount": "17055594260",
"destinationAmount": "10000001000001000005",
"blockNumber": "22325874",
"timestamp": 1745340923953,
"estimatedExecutionTimeMs": 22000,
"intent": {
"originChainId": 1,
"originTokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"destinationChainId": 8453,
"destinationTokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"amount": "10000001000001000005",
"sender": "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
"receiver": "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709"
},
"steps": [
{
"originToken": {
"chainId": 1,
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC",
"name": "USD Coin",
"decimals": 6,
"priceUsd": 0.999949,
"iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
},
"destinationToken": {
"chainId": 8453,
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"symbol": "ETH",
"name": "Ether",
"decimals": 18,
"priceUsd": 1695.537726,
"iconUri": "https://assets.relay.link/icons/1/light.png"
},
"transactions": [
{
"chainId": 1,
"to": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"data": "0x095ea7b3000000000000000000000000f8ab2dbe6c43bf1a856471182290f91d621ba76d00000000000000000000000000000000000000000000000000000003f897b714",
"type": "eip1559",
"id": "0xe984ce73defcb35a2decb07b1cbadb57bea0e9bd4c3d919f286988daae5e98a8",
"action": "approval"
},
{
"type": "eip1559",
"to": "0xF8Ab2dBE6c43bf1a856471182290f91D621Ba76d",
"from": "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
"value": "0",
"data": "0x...",
"chainId": 1,
"action": "buy",
"id": "0x3b575d76157c50c94c61f0e1265dee784d00d2ad7502f1c6a6dba938e270b196",
"spender": "0xfCEF2Fe72413b65d3F393d278A714caD87512bcd"
}
],
"originAmount": "17055594260",
"destinationAmount": "10000001000001000005",
"estimatedExecutionTimeMs": 22000
}
]
}
}

Onramp quotes will now have the following schema:

{
"data": {
"id": "5a066908-82da-4d31-8dea-99c45f72e98b",
"link": "https://pay.coinbase.com/buy/select-asset?appId=41cbb2fb-8b35-45b9-949b-9672bc8edb78&addresses=%7B%220x2247d5d238d0f9d37184d8332aE0289d1aD9991b%22%3A%5B%22unichain%22%5D%7D&assets=%5B%22USDC%22%5D&defaultAsset=USDC&defaultNetwork=unichain&presetCryptoAmount=1716.321932&fiatCurrency=USD&partnerUserId=7d789de0-b4e0-4aac-84b4-5e13b11c896d",
"destinationAmount": "1000000100000010000",
"timestamp": 1745341089555,
"expiration": 1745344689547,
"intent": {
"chainId": 324,
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"amount": "1000000100000010000",
"receiver": "0x2247d5d238d0f9d37184d8332aE0289d1aD9991b",
"onramp": "coinbase",
"currency": "USD",
"maxSteps": 2,
"excludeChainIds": []
},
"steps": [
{
"originToken": {
"chainId": 130,
"address": "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
"symbol": "USDC",
"name": "USDCoin",
"decimals": 6,
"priceUsd": 0.999949,
"iconUri": "https://ethereum-optimism.github.io/data/USDC/logo.png"
},
"destinationToken": {
"chainId": 324,
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"symbol": "ETH",
"name": "Ether",
"decimals": 18,
"priceUsd": 1691.447,
"iconUri": "https://assets.relay.link/icons/1/light.png"
},
"transactions": [
{
"chainId": 130,
"to": "0x078D782b760474a361dDA0AF3839290b0EF57AD6",
"data": "0x095ea7b3000000000000000000000000f8ab2dbe6c43bf1a856471182290f91d621ba76d00000000000000000000000000000000000000000000000000000000664cfe8c",
"type": "eip1559",
"id": "0xb1ec1d50e1ef52ebb5fab91103f05605e9d24fb8ff26c4e5ef728e41ff82b788",
"action": "approval"
},
{
"type": "eip1559",
"to": "0xF8Ab2dBE6c43bf1a856471182290f91D621Ba76d",
"from": "0x2247d5d238d0f9d37184d8332aE0289d1aD9991b",
"value": "0",
"data": "0x...",
"chainId": 130,
"action": "buy",
"id": "0x1c66f9e7aefee5ffcc9b22595d07c3eedfa89deaec189707f73272f8e52d1d7b",
"spender": "0x078D782b760474a361dDA0AF3839290b0EF57AD6"
}
],
"originAmount": "1716321932",
"destinationAmount": "1000000100000010000",
"estimatedExecutionTimeMs": 2000
}
],
"currency": "USD",
"currencyAmount": 1716.321932
}
}

The steps are to be completed after the use has done the initial onramp.

You can find all this and more in our API reference docs.

Features

  • steps parameter for all quotes with prepared transactions and estimates
  • Faster approximate quote responses
  • Onramping with post-onramp cross-chain swaps
  • Fiat quote included in onramp responses

Bug Fixes

  • Removed ZK chains from intermediate steps, due to inconsistent addresses when using smart wallets
Yash Kumar

We have added CLI and SDK support for Stylus contracts.

This allows developers to use thirdweb CLI to create, publish, and deploy their contracts written with Stylus. The deployed contracts can be used via thirdweb dashboard or SDK.

Prerequisites:

You can also use the Stylus quickstart guide for reference: https://docs.arbitrum.io/stylus/quickstart

Here's how to use this feature:

Setup a starter repo (can be skipped if you already have a Stylus project)

npx thirdweb create-stylus

This will setup a project containing a template contract.

You can now publish this contract by running the publish command:

npx thirdweb publish-stylus -k <YOUR SECRET KEY>

Publishing a contract saves the contract metadata to an onchain registry, and creates a contract page from where you can deploy a specific version of this contract multiple times.

This is how it will look:

Alternatively, you can use the deploy command to do a one-time deployment:

npx thirdweb deploy-stylus -k <YOUR SECRET KEY>

After deployment, the contract will be available on thirdweb dashboard. You can interact with it via dashboard or integrate it in your app using the code snippets as shown below:

Greg

We've significantly increased the number of onramp routes available in the Universal Bridge widget. You can now onramp to chains like Mantle, Unichain, Lens, Treasure, and more. No SDK upgrade necessary. Try it out on the bridge page here.

0:00
/0:41
Arsenii

We’ve fixed the issues with how metadata links are resolved — and introduced a new way to give you control over it.

Accurate Link Resolution

  • Fixed a bug where metadata responses sometimes included incorrectly resolved URLs.
  • Added validation logic to detect bad URIs in cached or stored metadata — and automatically re-fetches only the original source.

🧠 New: Control Over Metadata Link Resolution

  • Introduced a new resolve_metadata_links parameter (default: true) to all NFT endpoints which can return metadata.
  • When set to false, the response will return original links such as ipfs:// and ar://, instead of their resolved HTTP versions.

This gives clients full control — whether you want cleanly resolved URLs or raw metadata as authored on-chain.

Joaquim Verges

We're excited to announce a major enhancement to the thirdweb TypeScript SDK that will significantly improve the developer experience when building blockchain applications. With release 5.95.0, we've supercharged the SDK by integrating it with Insight - our in-house indexer - replacing traditional RPC calls for fetching contract state, events, balances, NFT metadata, and more.

The Power of Insight

Until now, the thirdweb SDK has relied primarily on RPC calls to fetch on-chain data. While functional, this approach sometimes faced limitations in terms of speed, reliability, and functionality. By integrating Insight directly into our SDK, we've addressed these challenges head-on, offering:

  • Significantly faster queries for contract events, balances, and NFTs
  • Enhanced reliability with reduced dependency on mutli roundtrip RPC calls
  • Cross-chain functionality that lets you query data across multiple blockchains in a single call
  • Advanced filtering capabilities for more precise data retrieval

What's New in the SDK

New capabilities in the Connect UI components

The Connect UI modal now uses Insight to give your users a full wallet experience directly in your websites:

  • Shows all ERC20 token balances
  • Show all NFTs
  • Shows past transactions of the connected wallet
0:00
/0:11

You can now view all your tokens and NFTs in the connect modal

Supercharged Existing Functions

Your favorite thirdweb functions have been turbocharged with Insight integration:

  • getContractEvents
  • getOwnedNFTs
  • getNFTs
  • getNFT

These functions now automatically leverage our indexer on supported chains, with a graceful fallback to traditional RPC calls when needed.

If you're already using those functions in your app, no changes needed on your end, you'll just get the improved functionality out of the box.

If for any reason you need to turn off that behavior, you can pass useIndexer: false to always use RPC.

New Insight Namespace

We've added a dedicated Insight namespace with powerful new functions:

  • Insight.getOwnedTokens() - Get ERC20 tokens owned by an address across multiple chains
  • Insight.getOwnedNFTs() - Get NFTs (ERC721 and ERC1155) owned by an address
  • Insight.getNFTs() - Get NFTs (ERC721 and ERC1155) for a given contract
  • Insight.getNFT() - Get NFTs metadata for a given contract and tokenId
  • Insight.getTransactions() - Get all transactions for a given wallet address
  • Insight.getContractEvents() - Query indexed events with advanced filtering options

You can import those with import { Insight } from "thirdweb"

New Standalone Package: @thirdweb-dev/insight


For developers who need direct access to our indexer API, we've released a standalone package: @thirdweb-dev/insight. This lightweight API wrapper provides:

  • Typed functions, request bodies, and responses
  • Always stays in sync with the Insight API
  • Perfect for backend applications requiring optimized blockchain data access, without the rest of the SDK

Hands-on Examples

For the existing functions, you will get the improved functionality out of the box without any changes. If you want to use the new multichain capabilities directly, here's some examples using the new Insight namespace:

Get ERC20 Tokens Across Multiple Chains

import { Insight } from "thirdweb";
const tokens = await Insight.getOwnedTokens({
client,
ownerAddress,
chains: [base, polygon, arbitrum],
});

With just a few lines of code, you can now retrieve all ERC20 tokens owned by an address across Base, Polygon, and Arbitrum networks simultaneously!

Fetch Owned NFTs

import { Insight } from "thirdweb";
const nfts = await Insight.getOwnedNFTs({
client,
ownerAddress,
chains: [sepolia],
});

Get Transaction History

import { Insight } from "thirdweb";
const transactions = await Insight.getTransactions({
client,
walletAddress,
chains: [sepolia],
});

Query Indexed Contract Events

import { Insight } from "thirdweb";
const events = await Insight.getContractEvents({
client,
chains: [sepolia],
contractAddress: "0x...",
event: transferEvent(),
decodeLogs: true,
});

Using the Standalone Insight Package

For developers who want low level access to the Insight API with type-safe functions, here's how to use the standalone @thirdweb-dev/insight package:

Configuration

import { configure } from "@thirdweb-dev/insight";
// Call this once at the startup of your application
configure({
clientId: "<YOUR_CLIENT_ID>",
});

Example Usage

import { getV1Events } from "@thirdweb-dev/insight";
const events = await getV1Events({
query: {
chain: [1, 137],
filter_address: "0x1234567890123456789012345678901234567890",
},
});

These functions will map one to one with the Insight OpenAPI spec and will stay in sync as the service changes.

Getting Started

These new features are available now in thirdweb SDK v5.95.0 and the new @thirdweb-dev/insight v1.0.0 package.

To get started:

npm install thirdweb@latest
# Or if you need the standalone package
npm install @thirdweb-dev/insight

Looking for dotnet/unity? It's already out, head over to the dotnet documentation to learn more.

What's Next?

This Insight integration is just the beginning. We're continuously working to enhance the thirdweb developer experience with more powerful indexing capabilities, additional cross-chain functionality, and deeper integration with our developer tools ecosystem.

Stay tuned for more updates, and as always, happy building!


For more detailed documentation on these new features, visit portal.thirdweb.com.

Toomas Oosalu

Insight adds more data to token price API to also return market data, historical price data and holder count in addition to the price!

Market Data

The following data is now included by default for each token:

percent_change_24h - Percentage change of the price over the last day

volume_24h_usd - Trading volume in USD over the last day

volume_change_24h - Percentage change of volume over the last day

market_cap_usd - Market cap value in USD

Holder Count

By specifying include_holders=true query param the number of on-chain holders of the token will also be returned

Historical Price Data

By including include_historical_prices=true query param, the response will contain a list of token prices per hour over the last 30 days.


Here is an example response for USDC on Ethereum

{
"data": [
{
"chain_id": 1,
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"symbol": "USDC",
"price_usd": 0.9998078912327243,
"price_usd_cents": 100,
"percent_change_24h": -0.02612099,
"market_cap_usd": 60411059379,
"volume_24h_usd": 10036602253,
"volume_change_24h": 6.5387,
"historical_prices": [
{
"date": "2025-03-18 11:00:00",
"price_usd": 0.9998556959666844,
"price_usd_cents": 100
},
{
"date": "2025-03-18 12:00:00",
"price_usd": 0.9998533259452913,
"price_usd_cents": 100
},
{
"date": "2025-03-18 13:00:00",
"price_usd": 0.9998012400259259,
"price_usd_cents": 100
},
.... and so on over the next 30 days...
],
"holders": 2994360
}
]
}

Try it out in our playground


📖 Learn more about Insight - it’s open source and ready to power your applications!

Joaquim Verges

We're constantly working to improve the developer and administrative experience of ecosystem wallets. Today, we're excited to announce two significant enhancements to Ecosystem Wallets, designed to give you more flexibility and control:

  1. Unified User Search: Find users faster, regardless of the address you have.
  2. Better Ecosystem Analytics: You can now see how each partner brings users to your ecosytem over time
  3. Collaborative Partner Management: Empower your team to manage ecosystem partners and rules directly.

Let's dive into the details:

1. Enhanced User Search: Find Users by Signer (EOA) or Smart Account Address

Managing users within your ecosystem just got easier. When you enable Account abstraction for you ecosystem, you can now query with users based on their originating Externally Owned Account (EOA) or their deployed Smart Account address. Previously, only EOA search was allowed.

What's New:

  • You can now search for specific users within the Ecosystem Wallets dashboard using either their Signer Address (EOA) or their specific Smart Account address associated with your project.

How to Use:

const userDetails = await getUser({
client,
walletAddress: "0x...", // can be either EOA or smart account address
});

You can also use the backend API directly.

2. Better Ecosystem Analytics

You can now view how much each partner is contributing to your ecosystem over time. Previously you could only see overall stats for the ecosystem.

What's New:

  • Your ecosystem dashboard now shows connection analytics broken down by partner. So you can measure the success of each partner in your ecosystem.

How to Use:

  • Simply navigate to your ecosystem page in the dashboard, and go to the analytics tab to see the new stats.

3. Team-Based Ecosystem Partner & Rule Management

Managing the partners and rules that govern your ecosystem can now be done by anyone in your team. Previously, these configurations might have been restricted to the team owner.

What's New:

  • Authorized team members within your thirdweb project now have the ability to add new Ecosystem Partners and edit the configurations and rules for existing partners directly from the dashboard.

How to Use:

  • Team members with appropriate permissions can access the Ecosystem Partner configuration section within the thirdweb dashboard to add or modify partner details and rules. (Ensure your project's team roles are configured accordingly in the thirdweb dashboard settings).

These updates are live now in your thirdweb dashboard and SDKs.

Happy building!

Arsenii

We’ve just completed a full rollout of metadata performance upgrades across all NFT-related API routes — and started extending the same treatment to ERC20s.

What’s New?

Optimized Metadata Across All NFT Routes

Every API call involving NFT metadata now performs a single, efficient data read per request — even for multichain queries. Whether you're pulling transfers, balances, or metadata directly, things just got a whole lot faster.

🚀 Performance Gains: NFT Metadata Latency Drops by 10x+

We’ve slashed the latency for NFT metadata queries — and the numbers speak for themselves. For example, data for GET /v1/nfts/:contract_address

MetricBeforeAfter🔻 Improvement
p50103 ms5.9 ms~17× faster
p75152 ms13.4 ms~11× faster
p90243 ms54.8 ms~4.4× faster
p95327 ms99.3 ms~3.3× faster
p99464 ms192.1 ms~2.4× faster
p99.9555 ms242.3 ms~2.3× faster
Max756 ms290.2 ms~2.6× faster
  • GET /v1/nfts and GET /v1/nfts/transfers also saw solid improvements in the ~1.1× to 2.9× range, with reduced tail latencies and smoother performance across the board.
  • Not just faster — more consistent, with reduced tail latencies and fewer spikes in production.
  • These performance gains are now live for all metadata queries hitting the NFT endpoints.

🧱 ERC20 Metadata Storage Begins

We’ve started persisting ERC20 metadata as well, laying the foundation for more efficient token balance queries with rich metadata. Stay tuned — optimized joined queries are on the way.

🔄 Unified NFT Balances Endpoint

We’ve consolidated NFT balance queries under a single route:
/v1/nfts/balance/{ownerAddress}
This new endpoint works across ERC721 and ERC1155 standards, supports multichain queries out of the box, and is the one we recommend going forward.

Heads up: the old ERC721/ERC1155-specific balance endpoints are still live, but are now officially deprecated.

This makes it easier than ever to query, display, and work with NFTs and tokens at scale — with less overhead and more consistency.

Toomas Oosalu

Insight adds two new endpoints - one to lookup a token based on symbols and one to retrieve an NFT collection's metadata.

Token Lookup

Search for tokens by their symbol across 6000+ tokens.

Symbols are not unique nor strictly curated however, so be careful with how you use them!

To fetch all tokens with symbol ETH on Ethereum and B3

const lookupTokens = async (symbol: string) => {
try {
const response = await fetch(
`https://insight.thirdweb.com/v1/tokens/lookup?symbol=${symbol}&chain=1`,
{
headers: {
"x-client-id": <THIRDWEB_CLIENT_ID>,
},
},
);
const res = await response.json();
return res.data;
} catch (error) {
console.error("Error:", error);
}
};
await lookupTokens("ETH")

Try it out in our playground

Collection Metadata

Get metadata about an NFT collection.

By including a include_stats=true query param, you can also get the following statistics about a collection:

  • owner_count - Amount of distinct addresses that hold the NFTs
  • mint_count - Amount of NFT tokens that have been minted
  • token_count - Amount of distinct token IDs that currently exist
  • total_quantity - Amount of tokens that currently exist
const getCollectionMetadata = async (contractAddress: string) => {
try {
const response = await fetch(
`https://1.insight.thirdweb.com/v1/nfts/collection/${contractAddress}?include_stats=true`,
{
headers: {
"x-client-id": <THIRDWEB_CLIENT_ID>,
},
},
);
const res = await response.json();
return res.data;
} catch (error) {
console.error("Error:", error);
}
};

Try it out in our playground


📖 Learn more about Insight - it’s open source and ready to power your applications!

Toomas Oosalu

We're excited to announce that thirdweb Insight has expanded its blockchain data querying capabilities to 84 chains, adding these 17 new chains:

What This Means For Developers
With these additions, you can now use all of Insight's powerful features across these new chains.

Try them out on the playground!

View All Supported Chains
For a complete list of supported chains and their respective chain IDs, check the thirdweb chainlist.


📖 Learn more about Insight - it’s open source and ready to power your applications!

Greg

We've added support for MAGIC on Treasure (61166) and GHO on Lens (232) to our Universal Bridge, bringing the total number of routes available to over 35,000. Check out the full API reference here to get started, or try it in the playground.

Arsenii

We’ve rolled out a series of performance upgrades across the board to make NFT metadata queries faster, smarter, and more reliable than ever.

What Changed?

Unified Fetching for NFT Data

  • NFT metadata, ownership info, and token data are now pulled in a single optimised query internally, reducing the number of round trips and improving latency consistency.
  • This makes NFT-related endpoints much more consistent at scale.

🧠 Smarter Metadata Handling

  • Metadata is now fetched on-demand only when needed, skipping unnecessary lookups for already known or irrelevant data.
  • We've introduced a system to automatically skip refetching metadata that’s deemed not worth roundtrips — improving efficiency without losing accuracy.

🪄 Parallel Processing & Query Optimizsation

  • Queries for metadata are now parallelised, making better use of compute resources.
  • Owner and balance aggregations are now handled more effectively, ensuring both speed and correctness in multi-owner or high-traffic collections.

🛠️ Critical Bugfix for NFT Transfers

  • Fixed a major issue where NFT transfers were duplicated across chains. Transfer data is now properly filtered per chain, ensuring clean and accurate results.
  • Transfer endpoints now properly correlated to chain identification to avoid any confusion in multichain contexts.

🔁 Same Gains for Fungible Tokens (ERC20)

All of these improvements won’t just apply to NFTs — we’re extending the same performance, consistency, and metadata logic enhancements to ERC20 tokens as well.


🔁 What's next? All of these improvements won’t just apply to NFTs — we’re extending the same performance, consistency, and metadata logic enhancements to ERC20 tokens as well.


💡 Result? lower and more predictable response times, better metadata hygiene, and fewer redundant operations — even across large multichain datasets.

Let us know what you think — or better yet, try it out and feel the speed.

Greg

Ever wondered if your token is supported on Universal Bridge? You can check all routes for a given token using the routes page. Search by chain ID, token address, token symbol, or name for all origin and destination routes. You can access the site at thirdweb.com/routes.

0:00
/0:17
Greg

You can use the transactions array returned by a Universal Bridge prepared quote to easily execute a full route from origin to destination. This pattern is now even easier with transaction action fields included to denote what each transaction does. The most important of these actions is the approval type, which represents a pre-assembled approval transaction. The approval will account for the sender's existing set allowance and what token is needed for the next step.

A quote response might look something like this:

{
id: "0xf04cca9127820d71ab8fe588ed9532d14d61ee883bfe29870873258646d8a03e",
originAmount: "1003793",
destinationAmount: "1000000",
blockNumber: "133945469",
timestamp: 1743489718527,
estimatedExecutionTimeMs: 62000,
intent: {
originChainId: 10,
originTokenAddress: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
destinationChainId: 8453,
destinationTokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
buyAmountWei: "1000000",
sender: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
receiver: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
},
transactions: [
{
chainId: 10,
to: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
data: "0x...",
type: "eip1559",
id: "0x723a578f5f04178f410da8e2029c138d4cad76900a9d9e650603fc64e56e113b",
action: "approval",
}, {
to: "0x81d57DD01a15BC1C19563693902df621500D4d2A",
value: "0",
data: "0x...",
chainId: 10,
from: "0x2a4f24F935Eb178e3e7BA9B53A5Ee6d8407C0709",
type: "eip1559",
action: "buy",
id: "0x3f0cb9f8a3e8649284d5c3f44648237f821c19de490fce9572509d79292867dc",
}
],
}

To execute this bridge with the TypeScript SDK, use sendAndConfirmTransaction to send each transaction, and wait for a successful Bridge.status response for each non-approval transaction:

import { Bridge, sendAndConfirmTransaction } from "thirdweb";
for (const tx of preparedBuy.transactions) {
const hash = await sendAndConfirmTransaction({
transaction: prepareTransaction(tx),
account, // Learn to generate a thirdweb account https://portal.thirdweb.com/connect/wallet/get-started
});
if (tx.action !== "approval") {
// Wait for Bridge.status to return "COMPLETED" status
}
}

It's that easy to implement bridging and swapping in your app. Want to get started? You can find the full API reference here.

Toomas Oosalu

Insight now supports webhooks so you can build pipelines and receive notifications when specific blockchain events or transactions occur!

What does this mean?

With the introduction of webhook support in Insight, you can now seamlessly integrate blockchain data into your applications or workflows. Webhooks allow you to automatically receive near real-time notifications whenever specific blockchain events or transactions occur, eliminating the need for constant polling of the blockchain.

What can I do with it?

  • Automate Workflows: Trigger actions in your applications or services when a specific blockchain event happens (e.g., a token transfer, contract interaction, or wallet activity).
  • Monitor Blockchain Events: Stay updated on relevant events without manually querying the blockchain.
  • Build Custom Pipelines: Use webhooks to feed blockchain data into analytics tools, databases, or other systems for further processing.
  • Filter Specific Data: Configure webhooks to only receive notifications for events or transactions that meet your specific criteria, such as a particular contract address or event type.

Can I receive decoded events and transactions?

Yes! Insight webhooks provide decoded data for events and transactions. This means you’ll receive human-readable payloads that include all relevant details, such as parameters and values associated with the event or transaction. This makes it easier to process and use the data directly in your applications without additional decoding steps.
To enable this, you have to define specific event signatures / function signatures and partial ABIs in the webhook filter configurations.

For more details on setting up and managing webhooks, visit the following resources:


📖 Learn more about Insight - it’s open source and ready to power your applications!

Yash Kumar
Samina Kabir

We’ve released the Agglayer Module, designed to enable secure and seamless cross-chain transfers of ERC-20 tokens using Agglayer, an interoperability protocol. Learn more about Agglayer.

Please note: This module is currently in beta while the Agglayer bridge is not live in implementation. This means deployments are limited to Sepolia and Cardona as it requires Ethereum as an L1 and zkEVM as L2.

🧩 What is it?

The Agglayer Module is a module contract that can be added to any ERC-20 modular contract built with thirdweb’s modular framework. It allows developers to bridge ERC-20 tokens across any EVM-compatible chain.

🌐 Why it matters

As the Ethereum ecosystem continues to grow with the introduction of more Layer 2 networks, fragmented liquidity and isolated user experiences have become major challenges. Without interoperability, assets are locked within specific chains, limiting usability and adoption.

The Agglayer Module helps address this by enabling interoperability at the contract level—allowing tokens to move freely across chains, reducing fragmentation, and improving the overall developer and user experience.

✅ Key Benefits

  • EVM-compatible – Works across all EVM chains
  • Modular and upgradeable – Can be installed or removed from any ERC-20 modular contract
  • Dashboard integration – Easily install through the thirdweb dashboard with no additional configuration
  • Cross-chain functionality – Mint tokens and send them to other chains seamlessly

⚠️ Requirements

  • The module currently only works with ERC-20 modular contracts
  • It must be installed on the contract in order to function

🛠 How to use it

  1. Use or deploy an ERC-20 modular contract
  2. Add the Agglayer Module through the thirdweb dashboard
  3. Mint and bridge tokens as needed

📚 View the full tutorial

As always, please don't hesitate to contact us for any questions or support.

Toomas Oosalu

Insight added support for querying a wallet's transactions (both inbound and outbound). Previously this had to be two separate queries, but can now be done by a single query.

Try it out in our playground

To fetch a wallet's transactions on Ethereum

const getWalletTransactions = async (walletAddress: string) => {
try {
const response = await fetch(
`https://1.insight.thirdweb.com/v1/wallets/${walletAddress}/transactions`,
{
headers: {
"x-client-id": <THIRDWEB_CLIENT_ID>,
},
},
);
const res = await response.json();
return res.data;
} catch (error) {
console.error("Error:", error);
}
};

📖 Learn more about Insight - it’s open source and ready to power your applications!

Greg

With v5.93.0 of the TypeScript SDK, we've added full beta functionality for thirdweb's new Universal Bridge. The bridge currently covers 50+ chains and over 30,000 routes.

  • Bridge.Buy - Specify an exact destination amount to receive
    • quote: Get estimates without a wallet connection
    • prepare: Get finalized quotes with transaction data
  • Bridge.Sell - Specify the exact origin amount to send
    • quote: Get estimates without a wallet connection
    • prepare: Get finalized quotes with transaction data

How to Send Transactions

When you call prepare, you might get multiple transactions back. You must send all transactions in order and sequentially for the full route to succeed. Before sending each transaction, call Bridge.status for the previous transaction until it returns COMPLETED. Do not simply wait for the transaction receipt, as this doesn't account for the destination chain transaction (if there is one).

The transactions returned do not include approvals. Send any necessary approvals before their corresponding transactions.

Route Discovery & Transaction Tracking

  • Bridge.routes - Advanced function to discover and filter available bridge routes
    • Filter by token address, chain ID, or both
    • Full pagination support with customizable limit and offset
  • Bridge.status - Comprehensive transaction status tracking
    • Clear status indicators: "COMPLETED", "PENDING", "FAILED", or "NOT_FOUND"
    • Detailed transaction reporting including origin and destination amounts and chains

Types

  • Standardized error handling with descriptive, formatted error messages
  • Four underlying types are exported for use with the bridging functions:
    • Route: Defines bridge routes between chains and tokens
    • Status: Represents bridge transaction status data
    • Quote: Contains detailed bridge transaction quote information
    • PreparedQuote: Extends Quote with complete transaction data

Implementation Examples

Bridge.Buy Usage Example

import { Bridge, toWei, NATIVE_TOKEN_ADDRESS } from "thirdweb";
// First, get a quote to see approximately how much you'll pay
const buyQuote = await Bridge.Buy.quote({
originChainId: 1, // Ethereum
originTokenAddress: NATIVE_TOKEN_ADDRESS,
destinationChainId: 10, // Optimism
destinationTokenAddress: NATIVE_TOKEN_ADDRESS,
buyAmountWei: toWei("0.01"), // I want to receive 0.01 ETH on Optimism
client: thirdwebClient,
});
console.log(
`To get ${buyQuote.destinationAmount} wei on destination chain, you need to pay ${buyQuote.originAmount} wei`,
);
// When ready to execute, prepare the transaction
const preparedBuy = await Bridge.Buy.prepare({
originChainId: 1,
originTokenAddress: NATIVE_TOKEN_ADDRESS,
destinationChainId: 10,
destinationTokenAddress: NATIVE_TOKEN_ADDRESS,
buyAmountWei: toWei("0.01"),
sender: "0x...", // Your wallet address
receiver: "0x...", // Recipient address (can be the same as sender)
client: thirdwebClient,
});
// The prepared quote contains the transactions you need to execute
console.log(
`Transactions to execute: ${preparedBuy.transactions.length}`,
);

Bridge.Sell Usage Example

import { Bridge, toWei } from "thirdweb";
// First, get a quote to see approximately how much you'll receive
const sellQuote = await Bridge.Sell.quote({
originChainId: 1, // Ethereum
originTokenAddress: NATIVE_TOKEN_ADDRESS,
destinationChainId: 10, // Optimism
destinationTokenAddress: NATIVE_TOKEN_ADDRESS,
sellAmountWei: toWei("0.01"), // I want to sell 0.01 ETH from Ethereum
client: thirdwebClient,
});
console.log(
`If you send ${sellQuote.originAmount} wei, you'll receive approximately ${sellQuote.destinationAmount} wei`,
);
// When ready to execute, prepare the transaction
const preparedSell = await Bridge.Sell.prepare({
originChainId: 1,
originTokenAddress: NATIVE_TOKEN_ADDRESS,
destinationChainId: 10,
destinationTokenAddress: NATIVE_TOKEN_ADDRESS,
sellAmountWei: toWei("0.01"),
sender: "0x...", // Your wallet address
receiver: "0x...", // Recipient address (can be the same as sender)
client: thirdwebClient,
});
// Execute the transactions in sequence
for (const tx of preparedSell.transactions) {
// Send the transaction using your wallet
// Wait for it to be mined
}

Route Discovery Example

import { Bridge, NATIVE_TOKEN_ADDRESS } from "thirdweb";
// Get all available routes
const allRoutes = await Bridge.routes({
client: thirdwebClient,
});
// Filter routes for a specific token or chain
const filteredRoutes = await Bridge.routes({
originChainId: 1, // From Ethereum
originTokenAddress: NATIVE_TOKEN_ADDRESS,
destinationChainId: 10, // To Optimism
client: thirdwebClient,
});
// Paginate through routes
const paginatedRoutes = await Bridge.routes({
limit: 10,
offset: 0,
client: thirdwebClient,
});

Transaction Status Monitoring Example

import { Bridge } from "thirdweb";
// Check the status of a bridge transaction
const bridgeStatus = await Bridge.status({
transactionHash:
"0xe199ef82a0b6215221536e18ec512813c1aa10b4f5ed0d4dfdfcd703578da56d",
chainId: 8453, // The chain ID where the transaction was initiated
client: thirdwebClient,
});
// The status will be one of: "COMPLETED", "PENDING", "FAILED", or "NOT_FOUND"
if (bridgeStatus.status === "completed") {
console.log(`
Bridge completed!
Sent: ${bridgeStatus.originAmount} wei on chain ${bridgeStatus.originChainId}
Received: ${bridgeStatus.destinationAmount} wei on chain ${bridgeStatus.destinationChainId}
`);
} else if (bridgeStatus.status === "pending") {
console.log("Bridge transaction is still pending...");
} else {
console.log("Bridge transaction failed");
}

Error Handling Implementation

try {
await Bridge.Buy.quote({
// ...params
});
} catch (error) {
// Errors will have the format: "ErrorCode | Error message details"
console.error(error.message); // e.g. "AmountTooHigh | The provided amount is too high for the requested route."
}

Module Integration

The Bridge module is accessible as a top-level export:

import { Bridge } from "thirdweb";

Use Bridge.Buy, Bridge.Sell, Bridge.routes, and Bridge.status to access the corresponding functionality.

Or, import the functions directly from the module:

import { Buy, Sell, routes, status } from "thirdweb/bridge";