Changelog

Overview

The Solana Token Deployment endpoint enables you to create new fungible tokens on Solana with a single API call. It supports both the standard SPL Token program and the newer Token-2022 program with advanced features.

Endpoint: POST /v1/solana/deploy

Base URL: https://api.thirdweb.com


Authentication

This endpoint requires server-side authentication using your secret key. Never expose your secret key in client-side code.

x-secret-key: YOUR_SECRET_KEY

Request Parameters

ParameterTypeRequiredDescription
fromstringSolana wallet address that pays for deployment
chainIdstringNetwork identifier: solana:mainnet or solana:devnet
namestringToken name (1-32 characters)
symbolstringToken symbol (1-10 characters)
decimalsnumberDecimal places (0-9, default: 9)
initialSupplystringAmount to mint in base units
mintAuthoritystringAddress allowed to mint (defaults to from)
freezeAuthoritystringAddress allowed to freeze accounts
tokenProgramstringspl-token (default) or token-2022

Response

{
"result": {
"transactionId": "5ttCNobho7nk5F1Hh4pU4d9T2o1yAFn3...",
"mintAddress": "7GCihgDB8fe6KNjn2MYtkzZcRjQy3t9GHdC8uHYmW2hr"
}
}
FieldDescription
transactionIdThe Solana transaction signature
mintAddressThe address of your new token mint

Quick Start

Deploy a Basic Token

curl -X POST "https://api.thirdweb.com/v1/solana/deploy" \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "YOUR_WALLET_ADDRESS",
"chainId": "solana:devnet",
"name": "My Token",
"symbol": "MTK",
"decimals": 9
}'

Deploy with Initial Supply

Mint 1,000,000 tokens at deployment (with 9 decimals):

curl -X POST "https://api.thirdweb.com/v1/solana/deploy" \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "YOUR_WALLET_ADDRESS",
"chainId": "solana:devnet",
"name": "My Token",
"symbol": "MTK",
"decimals": 9,
"initialSupply": "1000000000000000"
}'
Note: initialSupply is in base units. For 9 decimals, multiply your desired amount by 10^9.

Deploy a Token-2022 Token

curl -X POST "https://api.thirdweb.com/v1/solana/deploy" \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "YOUR_WALLET_ADDRESS",
"chainId": "solana:devnet",
"name": "My Stable",
"symbol": "MYS",
"decimals": 6,
"tokenProgram": "token-2022"
}'

Deploy with Custom Authorities

curl -X POST "https://api.thirdweb.com/v1/solana/deploy" \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "YOUR_WALLET_ADDRESS",
"chainId": "solana:mainnet",
"name": "Governance Token",
"symbol": "GOV",
"decimals": 9,
"mintAuthority": "TREASURY_WALLET_ADDRESS",
"freezeAuthority": "ADMIN_WALLET_ADDRESS"
}'

Code Examples

TypeScript / JavaScript

const response = await fetch(
"https://api.thirdweb.com/v1/solana/deploy",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-secret-key": "YOUR_SECRET_KEY",
},
body: JSON.stringify({
from: "YOUR_WALLET_ADDRESS",
chainId: "solana:devnet",
name: "My Token",
symbol: "MTK",
decimals: 9,
initialSupply: "1000000000000000", // 1M tokens
}),
},
);
const { result } = await response.json();
console.log("Token deployed!");
console.log("Mint address:", result.mintAddress);
console.log("Transaction:", result.transactionId);

Python

import requests
response = requests.post(
"https://api.thirdweb.com/v1/solana/deploy",
headers={
"Content-Type": "application/json",
"x-secret-key": "YOUR_SECRET_KEY",
},
json={
"from": "YOUR_WALLET_ADDRESS",
"chainId": "solana:devnet",
"name": "My Token",
"symbol": "MTK",
"decimals": 9,
"initialSupply": "1000000000000000",
},
)
result = response.json()["result"]
print(f"Token deployed! Mint: {result['mintAddress']}")

Token Programs

SPL Token (Default)

The standard Solana token program. Recommended for most use cases.

  • ✅ Widely supported by wallets and DEXs
  • ✅ Lower transaction fees
  • ✅ Maximum compatibility

Token-2022

The newer Token Extensions program with advanced features.

  • ✅ Transfer fees
  • ✅ Interest-bearing tokens
  • ✅ Confidential transfers
  • ✅ Non-transferable tokens
  • ⚠️ Not all wallets/DEXs support Token-2022 yet

Decimal Places Guide

Use CaseRecommended Decimals
SOL-like tokens9
Stablecoins (USDC-like)6
NFT-adjacent tokens0
High-precision DeFi9

Error Responses

StatusDescription
400Invalid request parameters
401Missing or invalid authentication
500Server error during deployment
504Transaction confirmation timeout

Best Practices

  1. Test on Devnet first — Always deploy to solana:devnet before mainnet
  2. Secure your secret key — Use environment variables, never commit to code
  3. Verify the mint address — Check the returned mintAddress on a Solana explorer
  4. Plan your authorities — Consider who should control minting and freezing
  5. Calculate supply correctly — Remember to account for decimals in initialSupply

Related Resources

The Bridge widget iframe makes it easy to embed cross-chain swaps and fiat onramp UI into your app. Just add an iframe to your HTML and get a fully customizable widget - no client id required!

Features

  • Cross-chain token swaps across 85+ blockchains
  • Fiat onramp support to buy tokens with credit/debit cards
  • dark and light mode support
  • Set custom default token selections using query parameters
  • Display fiat values in multiple currencies

Example

<iframe
src="https://thirdweb.com/bridge/widget"
height="750px"
width="100%"
style="border: 0;"
/>

Learn More

View Documentation

Today, we are launching Dedicated Relayers—fully managed, private transaction infrastructure designed to give your application the dedicated resources it needs to scale.

Why Dedicated Relayers?

When you use a shared relayer, your transactions are processed alongside thousands of other applications using thirdweb. While this works for many use cases, high-scale applications need more control and reliability.

With a Dedicated Relayer, you get:

  • Guaranteed Throughput: Your transaction queue is yours alone. No rate limits caused by other users and no "noisy neighbor" problems.
  • Parallel Execution: Scale your transaction capacity by adding multiple executor wallets. Our Premium tier offers 10 executor wallets, allowing you to submit transactions in parallel for up to 10x higher throughput.
  • Multi-Chain Support: seamless operation across multiple chains. Configure your fleet to handle traffic on the networks that matter to you.
  • Dedicated Analytics: A brand new dashboard view to track your fleet's performance, including total gas spent, transaction success rates, and active chain metrics. The best part - you can build your own dashboards easily now, unlike with shared 4337 and 7702 infra, by simply collecting transactions initiating from your dedicated executor addresses.

Pricing Tiers

We’ve designed flexible tiers to match your growth stage:

  • Standard ($99/mo): Ideal for startups and apps with moderate volume. Includes support for 1 chain and a single executor wallet.
  • Premium ($299/mo): Built for enterprise-grade scale. Includes support for up to 2 chains and 10 executor wallets for maximum parallel throughput.
  • Custom: For applications operating at massive scale, we offer custom configurations with unlimited chains and executors.

Available Now

Dedicated Relayers are available today in the dashboard. Navigate to Wallets > Dedicated Relayer in your project settings to deploy your fleet and start scaling your

We shipped a change in our x402 stack that allows settling multiple payments with the same payment authorization, up to a maximum amount. This opens up a lot more x402 use cases like AI chat sessions, automations, scheduled actions and more!

This is possible using the new upto scheme, which authorizes a maximum amount to be withdrawn. Users can authorize $1 once, then spend 100 times $0.01 without having to resign anything.

Very useful for AI apps. Authorize once for the whole chat session, but still settle micro payments on every message.

0:00
/0:42

To make this work, use the upto scheme on the backend when verifying and settling payments with an optional minimum price. On the client, wrapFetchWithPayment and useFetchWithPayment will automatically cache and re-use the payment authorization while its still valid, no extra state needed.

Learn more in our developer documentation.

Happy building! 🛠️

You can now swap tokens held by your server wallets directly from the dashboard. Useful to convert the fees and payments you receive to the token / chain of your choice.

New swap feature for project server wallets

Simply head to your project dashboard, you'll find a new "Swap" button in your project wallet card. You'll need your project secret key to perform transactions with your wallet. Once entered, simply follow the steps in the swap UI to convert the held token to another one on the same chain or a different chain.

Happy building! 🛠️

We recently shipped 3 important improvements to the Bridge API and widgets.

1 - Batched transactions with ERC-5792

We reduced the number of confirmations required by half for erc20 token swaps in the Bridge widgets. Under the hood we leverage ERC-5792 enabled wallets to atomically perform approvals and swaps in one transaction.

2 - Faster token balances fetching

We dramatically improved the performance of our token fetching API, with up to 4x faster load times, especially for wallets with lots of tokens. This improvement is live on thirdweb.com/bridge, dashboard, playground and on v5.115.1 of the SDK.

3 - Slippage tolerance configuration

We also enabled configuring the slippage in the http API and typescript SDK. You can now set a % slippage when requesting a quote, useful for tokens with low liquidity. We continue to set the best automatic slippage by default if not set.

const quote = await Bridge.Buy.prepare({
originChainId: 1,
originTokenAddress: "0x..",
destinationChainId: 10,
destinationTokenAddress: "0x..",
amount: toWei("0.01"),
sender: "0x...",
receiver: "0x...",
client,
slippageToleranceBps: 500, // ex: 5% slippage tolerance
});

We just improved the Project Server Wallet management from the dashboard to easily view and withdraw funds for any token on any chain.

Every thirdweb project comes with a non custodial server wallet by default, you can use this for receiving fees, facilitating x402 transactions or any backend transaction. With this change, you can now quickly glance your balance for any token, and withdraw with one click.

Happy building!

We've updated our x402 client/server stack to enable dynamic payments, perfect for AI APIs that need to charge on a per-token basis.

The new upto payment scheme

You can now pass a scheme property to verifyPayment() and settlePayment() which lets you control the payment scheme:

  • exact (default) - The client pays the exact amount specified in the payment requirements.
  • upto (new) - The client pays any amount up to the specified maximum amount.

Example: charging for AI inference

This new payment scheme is ideal for AI inference APIs where costs are dynamic based on the number of tokens used in each request.

const paymentArgs = {
resourceUrl: "https://api.example.com/premium-content",
method: "GET",
paymentData,
payTo: "0x1234567890123456789012345678901234567890",
network: arbitrum,
scheme: "upto", // enables dynamic pricing
price: "$0.10", // max payable amount
facilitator: thirdwebFacilitator,
};
// First verify the payment is valid for the max amount
const verifyResult = await verifyPayment(paymentArgs);
if (verifyResult.status !== 200) {
return Response.json(verifyResult.responseBody, {
status: verifyResult.status,
headers: verifyResult.responseHeaders,
});
}
// Do the expensive work that requires payment
const { answer, tokensUsed } = await callExpensiveAIModel();
// Now settle the payment based on actual usage
const pricePerTokenUsed = 0.00001; // ex: $0.00001 per AI model token used
const settleResult = await settlePayment({
...paymentArgs,
price: tokensUsed * pricePerTokenUsed, // adjust final price based on usage
});
//
return Response.json(answer);

This can be generalized to any type of API that uses variable amount of units of work, like RPC node APIs for example.

On the client side, the upto scheme is supported in v5.114.0 and above.

A fully working template

We recently open sourced a fully functional AI application that charges per tokens used, check out the repository on Github.

GitHub - thirdweb-example/x402-ai-inference: Pay for inference with x402
Pay for inference with x402. Contribute to thirdweb-example/x402-ai-inference development by creating an account on GitHub.

Learn more

To learn more about how to set this up in your own projects, check out the documentation.

x402 Server
Accept x402 payments in your APIs from any x402-compatible client.

We are excited to announce full support for EIP-7702 Session Keys in the Wallets API. This feature allows you to create secure, scoped permissions for your backend to execute transactions on behalf of your users—without ever taking custody of their main keys.

This is perfect for:

  • AI Agents: Allow an agent to trade or interact with contracts within strict limits.
  • Automated DeFi: Execute recurring payments or rebalancing without user confirmation for every step.
  • Gaming: Perform background actions (like crafting or harvesting) while the user is offline.

How It Works

  1. Create a Session Key: Your server generates a new "Server Wallet". This wallet will act as the authorized signer grantee.
  2. Grant Permissions: The user (client-side) signs a transaction authorizing this Session Key. You can restrict it to specific contracts, functions, or spending limits.
  3. Execute: Your server uses the Session Key to sign and send transactions. The blockchain treats these transactions as if they came from the user's main account.

End-to-End Example

Here is a complete, reproducible example using fetch. We will simulate a full flow: creating a guest user, generating a session key, granting permissions, and executing a transaction.

Prerequisites

  • Secret Key: For server-side calls (backend).
  • Client ID: For client-side calls (frontend/simulation).

Step 1: Create a Guest User (Client-Side)

First, we simulate a user logging in. We'll use the "guest" auth method to instantly generate a wallet and get an authentication token.

const API_URL = "https://api.thirdweb.com/v1";
const CLIENT_ID = "your-client-id";
// 1. Create a Guest Wallet (User)
const guestResponse = await fetch(`${API_URL}/auth/complete`, {
method: "POST",
headers: {
"x-client-id": CLIENT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
method: "guest",
sessionId: `session-${Date.now()}`, // Unique session ID
}),
});
const guestData = await guestResponse.json();
const userToken = guestData.token; // JWT for user authentication
const userAddress = guestData.walletAddress; // The user's smart account address
console.log("User Address:", userAddress);
console.log("User Token:", userToken);

Step 2: Create a Server Wallet (Session Key Target)

Your backend creates a fresh wallet that will act as the session key.

const SECRET_KEY = "your-secret-key";
// 2. Create a new Server Wallet to act as the Session Key
const sessionKeyResponse = await fetch(`${API_URL}/wallets/server`, {
method: "POST",
headers: {
"x-secret-key": SECRET_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
identifier: `session-key-${Date.now()}`,
}),
});
const sessionKeyData = await sessionKeyResponse.json();
const sessionKeyAddress = sessionKeyData.result.address;
console.log("Session Key Address:", sessionKeyAddress);

Step 3: User Grants Permission (Client-Side)

The user approves the session key using their auth token.

// 3. Grant permissions to the Session Key
const grantResponse = await fetch(
`${API_URL}/wallets/create-session-key`,
{
method: "POST",
headers: {
Authorization: `Bearer ${userToken}`, // Authenticate as the user
"x-client-id": CLIENT_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
chainId: 84532, // e.g., Base Sepolia
sessionKeyAddress: sessionKeyAddress,
durationInSeconds: 3600, // Valid for 1 hour
grantFullPermissions: true,
// Optional: Restrict to specific contracts/functions using 'callPolicies'
}),
},
);
const grantData = await grantResponse.json();
console.log("Permission Grant Tx ID:", grantData.transactionId);

Step 4: Execute Transaction (Server-Side)

Finally, your server executes a transaction. The server uses the Session Key to sign, but the transaction is executed on the User's account.

// 4. Execute a transaction
const executeResponse = await fetch(`${API_URL}/wallets/send`, {
method: "POST",
headers: {
"x-secret-key": SECRET_KEY,
"Content-Type": "application/json",
// Context Headers:
"x-account-address": userAddress, // The User's account (context)
"x-session-key-address": sessionKeyAddress, // The Session Key (signer)
},
body: JSON.stringify({
chainId: 84532,
from: sessionKeyAddress, // The signer must match x-session-key-address
recipients: [
{
address: userAddress, // Sending 0 ETH back to self as a test
quantity: "0",
},
],
}),
});
const executeData = await executeResponse.json();
console.log("Execution Tx ID:", executeData.result.transactionIds[0]);

Summary

With just three API calls, you've set up a secure, non-custodial automation flow. The user retains full control and can revoke the session key at any time, while your server gets the convenience of programmatic execution.

Try It Yourself

Visit our API reference here.

We just shipped the new useFetchWithPayment() React hook in thirdweb v5.113.0, making it easier than ever to integrate x402 payment flows into your React applications with built-in UI for wallet connection, funding, and payment error handling.

0:00
/0:38

Features

The useFetchWithPayment() hook provides a complete payment experience out of the box:

  • Automatic Payment Handling - Detects 402 responses and creates payment authorization headers automatically
  • Wallet Connection Flow - Prompts users to connect their wallet with a beautiful modal when needed
  • Wallet Funding Integration - Shows a BuyWidget to help users top up their wallet when they have insufficient funds
  • Error Handling UI - Displays modals with retry options when payments fail
  • Response Parsing - Automatically parses responses as JSON by default (configurable)
  • Fully Customizable - Customize themes, wallet options, funding widget, and more
  • React Query Integration - Built on `@tanstack/react-query` for state management

Usage

import { useFetchWithPayment } from "thirdweb/react";
import { createThirdwebClient } from "thirdweb";
const client = createThirdwebClient({ clientId: "your-client-id" });
function MyComponent() {
const { fetchWithPayment, isPending } = useFetchWithPayment(client);
const handleApiCall = async () => {
// Handle wallet connection, funding, and payment errors automatically
// Response is parsed as JSON by default
const data = await fetchWithPayment(
"https://api.example.com/paid-endpoint",
);
console.log(data);
};
return (
<button onClick={handleApiCall} disabled={isPending}>
{isPending ? "Loading..." : "Make Paid API Call"}
</button>
);
}

Customization Options

const { fetchWithPayment } = useFetchWithPayment(client, {
// Maximum payment amount (in base units)
maxValue: 5000000n, // 5 USDC
// Response parsing: "json" (default), "text", or "raw"
parseAs: "json",
// UI theme: "dark" (default) or "light"
theme: "light",
// Disable UI to handle errors manually
uiEnabled: true,
// Customize the funding widget
fundWalletOptions: {
title: "Add Funds",
description: "Top up your wallet to continue",
},
// Customize the wallet connection modal
connectOptions: {
wallets: [inAppWallet(), createWallet("io.metamask")],
title: "Sign in to continue",
},
});

Platform Support

The hook is available for both web and React Native:

  • Web: Full UI support with modals for connection, funding, and errors
  • React Native: Core functionality without modal UI (coming soon)

Resources

Getting Started

Install the thirdweb SDK if you haven't already:

npm install thirdweb

Then import and use the hook in your React components as shown above.

Happy Building! 🛠️

We just introduced the ability to set your own developer fees for all x402 transactions. This unlocks new monetization streams for platforms building with of x402 payments.

If you're building an platform that lets your users pay other users using x402, you can set your own fee to monetize your platform.

Behind the scenes, whenever your server wallet facilitates a x402 transaction, your portion of the fee will be deducted and sent to the wallet of your choice, all in one atomic transaction.

Simply set up your fee amount and recipient address in your project dashboard under the new x402 section to get started.

We just added comprehensive analytics for your x402 enabled APIs, so you can see payments and volume by resource, buyer and chain.

Navigate to the new x402 section of your project to see it in action, or learn how to get started monetizing your applications with x402.

Happy building! 🛠️

Solana just joined the list of supported networks for x402 payments. That means you can now gate, verify, and settle Solana transactions through your own facilitator wallets — fully end-to-end.

This release adds everything you need to spin up your own server wallet, prepare payment payloads, and handle verification + settlement directly on Solana (devnet or mainnet). No middle layers. No bloat.


What’s new

  • Solana facilitator flow — create or register a Solana server wallet, quote pricing with /v1/payments/x402/accepts, and settle signed transactions with /v1/payments/x402/settle.
  • Unified verify path/v1/payments/x402/verify now validates Solana payloads the same way it does for EVM, so you can reuse your middleware checks across chains.
  • End-to-end examples — refreshed snippets for Node environments that show the exact headers, payloads, and success envelopes you should expect in production.

Fast start guide

Create a facilitator wallet

const response = await fetch(
"https://api.thirdweb.com/v1/solana/wallets",
{
method: "POST",
headers: {
"x-secret-key": "YOUR_SECRET_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
label: "my-solana-facilitator",
}),
},
);
const wallet = await response.json();
console.log(wallet.result.address);

The returned address is the server-side payer for settles, so double-check that it appears in your project’s server wallet list.

Fund the wallet: Top up SOL for fees on the target cluster (devnet or mainnet-beta).

Settle on-chain with your facilitator wallet

const settleResponse = await fetch(
"https://api.thirdweb.com/v1/payments/x402/settle",
{
method: "POST",
headers: {
"x-secret-key": "YOUR_SECRET_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
paymentPayload: SIGNED_PAYMENT_PAYLOAD,
paymentRequirements,
waitUntil: "submitted",
}),
},
);
const settleData = await settleResponse.json();
console.log(settleData.transaction);

Use waitUntil: "confirmed" if you need finality before responding to the client.

Verify before you settle

const verifyResponse = await fetch(
"https://api.thirdweb.com/v1/payments/x402/verify",
{
method: "POST",
headers: {
"x-secret-key": "YOUR_SECRET_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
paymentPayload: SIGNED_PAYMENT_PAYLOAD,
paymentRequirements,
}),
},
);
const verifyData = await verifyResponse.json();
console.log(verifyData.isValid);

A truthy isValid means the signatures, blockhash, and amounts all check out.

Let payers fetch protected resources. If the client hits the protected endpoint first, have it replay the request through /v1/payments/x402/fetch. The api will answer with the payload you need for verification and settlement.

const fetchResponse = await fetch(
"https://api.thirdweb.com/v1/payments/x402/fetch?" +
new URLSearchParams({
url: "https://example.com/solana-protected",
from: "PAYER_SOLANA_ADDRESS",
chainId: "solana:devnet",
}),
{
method: "POST",
headers: {
"x-secret-key": "YOUR_SECRET_KEY",
},
},
);
const fetchData = await fetchResponse.json();

Quote access with /v1/payments/x402/accepts

const acceptsResponse = await fetch(
"https://api.thirdweb.com/v1/payments/x402/accepts",
{
method: "POST",
headers: {
"x-secret-key": "YOUR_SECRET_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
resourceUrl: "https://example.com/solana-protected",
method: "POST",
network: "solana:devnet",
price: {
amount: "0",
asset: {
address: "So11111111111111111111111111111111111111112",
decimals: 9,
tokenProgram: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
},
},
serverWalletAddress: "YOUR_SOLANA_FACILITATOR_ADDRESS",
}),
},
);
const { accepts } = await acceptsResponse.json();
const paymentRequirements = accepts[0];

Keep paymentRequirements around—clients will sign against it, and the facilitator will reuse it when settling.

Watch your server wallet dashboard or any Solana explorer for the transaction signature the settle endpoint returns.

We've made some major UI changes and grouped the core wallet and transaction functionality into a single Wallets sidebar section in your Project view, with easier access to related functionality for each, let's dive in.

User Wallets

Overview

The first section is for your user wallets, previously in-app wallets, attached to authenticated users on your frontend. It contains general analytics as well as a searchable list of users.

Configuration

The configuration section contains your User Wallet configurable options such as custom authentication and branding for OTP emails.

Server Wallets

Overview

Similarly to User Wallets, you can view analytics about transactions made from your backend as well as the EVM and Solana server wallets you have configured. This was previously all of the UI from the Transactions tab.

Configuration

The Vault section has moved here, it is what powers Server Wallets and you can manage it there. By default, no action is needed and it is managed automatically, but you can choose to eject from it and pass extra x-vault-access-token to our APIs and SDKs to interact with your server wallets if you do so.

Gas Sponsorship

Overview

This section shows you your gas sponsorship usage regardless of the interface (or EIP/execution mode) used to sponsor said gas. You can track your usage here easily.

Configuration

You can configure your sponsorship policies granularly here.

Notes

No functionally relevant pages have been removed, they're at most been moved to the new sections that hopefully feel more natural now.

Various bug fixes were integrated as part of this change, as well as link fixes.

You may still access some of these configurations from the project settings, which will redirect to the new pages as needed.

If you have any questions or need support, please reach out to our support team.

We have added support for creating and deploying modular contracts with Stylus. Users can now install rust based modules into the original solidity based modular contracts as described in the main design doc.

This plug-n-play model also allows users to write their own custom minting logic in rust, taking advantage of Stylus' interoperability and gas savings. These modules work with existing router contracts and modules written in solidity.

What's new?

| Learn how to deploy and interact with Stylus contracts through thirdweb documentation.

Deploy through dashboard

Here's a quick overview of how to deploy and setup your modular contracts via thirdweb dashboard.

  • Navigate to thirdweb explore page and select one of the core contracts to use. For e.g. Modular NFT Collection:
  • Once you have deployed one of these contracts, the modules come pre-installed, both solidity and rust ones.
  • If you wish to install / uninstall, navigate to modules tab on your contract page:

In addition, you can also write your own modules in rust and deploy / publish those using thirdweb CLI.

Additional Resources

Support

Need help? Please reach out to our support team

What's New

GET /v1/solana/swap - Get Swap Quote

Get a quote for swapping Solana tokens without executing the transaction. See the expected output amount, USD values, and slippage before committing.

Example: Get quote to swap 0.1 SOL for USDC

curl -X GET "https://api.thirdweb.com/v1/solana/swap?address=YOUR_WALLET_ADDRESS&tokenIn=So11111111111111111111111111111111111111112&tokenOut=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&amount=100000000&chainId=solana:mainnet" \
-H "x-secret-key: YOUR_SECRET_KEY"

Response:

{
"result": {
"inputMint": "So11111111111111111111111111111111111111112",
"outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"inputAmount": "100000000",
"outputAmount": "15423156",
"inputUsdValue": 15.45,
"outputUsdValue": 15.42,
"slippageBps": 34,
"requestId": "019a5f00-fab2-747d-bba2-b77f993314a0"
}
}

POST /v1/solana/swap - Execute Swap

Execute a complete token swap with automatic signing, execution, and on-chain confirmation. The swap is confirmed on Solana within 30 seconds or returns a timeout error.

Example: Swap 0.1 SOL for USDC

curl -X POST "https://api.thirdweb.com/v1/solana/swap" \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"address": "YOUR_WALLET_ADDRESS",
"tokenIn": "So11111111111111111111111111111111111111112",
"tokenOut": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount": "100000000",
"chainId": "solana:mainnet"
}'

Response:

{
"result": {
"signature": "5ttCNobho7nk5F1Hh4pU4d9T2o1yAFn3p1w8z8jk2jKd9KWCKN6dzyuT5xP1ny4wz9f5xCLjAF6Y9s9EoTW4aE1X",
"inputMint": "So11111111111111111111111111111111111111112",
"outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"inputAmount": "100000000",
"outputAmount": "15423156",
"inputUsdValue": 15.45,
"outputUsdValue": 15.42,
"requestId": "019a5f00-fab2-747d-bba2-b77f993314a0"
}
}

View transaction: https://solscan.io/tx/5ttCNobho7nk5F1Hh4pU4d9T2o1yAFn3p1w8z8jk2jKd9KWCKN6dzyuT5xP1ny4wz9f5xCLjAF6Y9s9EoTW4aE1X

Key Features

Aggregated Liquidity - Best prices across multiple DEXs and liquidity sources
💰 USD Value Display - See real-time USD values for input and output amounts
Automatic Execution - No need to manually sign or submit transactions
🔒 Confirmed Results - Returns only after transaction is confirmed on-chain
🌐 Mainnet Only - Swaps available on Solana mainnet (solana:mainnet)
💸 Gasless Support - Qualifying swaps ($10+ with <0.01 SOL) may be gasless

Common Token Addresses

TokenMint Address
SOLSo11111111111111111111111111111111111111112
USDCEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
USDTEs9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB

Request Parameters

ParameterTypeRequiredDescription
addressstringYesWallet address executing the swap
tokenInstringYesInput token mint address (token being sold)
tokenOutstringYesOutput token mint address (token being bought)
amountstringYesAmount in smallest unit (e.g., lamports for SOL)
chainIdstringYesMust be solana:mainnet

Response Fields

FieldTypeDescription
signaturestringTransaction signature (POST only)
inputMintstringInput token mint address
outputMintstringOutput token mint address
inputAmountstringAmount of input token swapped
outputAmountstringAmount of output token received
inputUsdValuenumberUSD value of input amount
outputUsdValuenumberUSD value of output amount
slippageBpsnumberSlippage tolerance in basis points
requestIdstringUnique request identifier

Amount Formatting

Amounts must be in the token's smallest unit (before decimals):

  • SOL (9 decimals): 1 SOL = 1000000000 lamports = "1000000000"
  • USDC (6 decimals): 1 USDC = 1000000 = "1000000"
  • 0.1 SOL: "100000000" (100 million lamports)
  • 10 USDC: "10000000" (10 million)

Error Handling

The API returns detailed error messages for common issues:

Insufficient Balance:

{
"error": {
"message": "Insufficient funds",
"statusCode": 400
}
}

Minimum Swap Amount ($10+ for gasless):

{
"error": {
"message": "Minimum $10 for gasless",
"statusCode": 400
}
}

Transaction Timeout:

{
"error": {
"message": "Swap transaction was not confirmed within timeout period",
"statusCode": 504
}
}

Ready to start swapping? Check out the full API documentation for more details.

New Endpoints

🔐 Sign Transaction (POST /v1/solana/sign-transaction)

Sign a Solana transaction without broadcasting it. Perfect for workflows where you need to inspect, store, or conditionally broadcast transactions.

Features:

  • Sign serialized transactions or assemble from instructions
  • Configure priority fees and compute limits
  • Returns both signature and signed transaction payload

Example - Sign from instructions:

curl -X POST https://api.thirdweb.com/v1/solana/sign-transaction \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"chainId": "solana:devnet",
"instructions": [
{
"programId": "11111111111111111111111111111111",
"accounts": [
{
"address": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"isSigner": true,
"isWritable": true
},
{
"address": "FhtwVYF1wKAm7fWmE2N5P2eCv13wt2aT8W4Q9NQ9YcJH",
"isSigner": false,
"isWritable": true
}
],
"data": "02000000e803000000000000",
"encoding": "hex"
}
],
"priorityFee": {
"type": "manual",
"microLamportsPerUnit": 1000
}
}'

Response:

{
"result": {
"signature": "3TZx4Ev7fWN7jk7CHTrxmsf9cXB1LQjs44aYGuC9kPYcyJ8D1V8efFgAfL9QGmxZXZMpDnwhzUbBeAf7dByoDwyx",
"signedTransaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIAAQIDBAUGBwgJ..."
}
}

📡 Broadcast Transaction (POST /v1/solana/broadcast-transaction)

Broadcast a previously signed transaction and wait for confirmation. The endpoint polls the network until the transaction is confirmed or times out after 30 seconds.

Features:

  • Broadcasts signed transactions to Solana
  • Waits for confirmation before returning
  • Detailed error messages for failed transactions
  • Returns signature (Solana's equivalent of transaction hash)

Example:

curl -X POST https://api.thirdweb.com/v1/solana/broadcast-transaction \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"chainId": "solana:devnet",
"signedTransaction": "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgIAAQIDBAUGBwgJ..."
}'

Success Response:

{
"result": {
"signature": "5ttCNobho7nk5F1Hh4pU4d9T2o1yAFn3p1w8z8jk2jKd9KWCKN6dzyuT5xP1ny4wz9f5xCLjAF6Y9s9EoTW4aE1X"
}
}

Error Response (Transaction Failed):

{
"message": "Transaction failed at instruction 0",
"error": {
"transactionError": {
"InstructionError": [
0,
"InsufficientFunds"
]
},
"instructionIndex": 0,
"instructionError": "InsufficientFunds",
"signature": "5ttCNobho7nk5F1Hh4pU4d9T2o1yAFn3p1w8z8jk2jKd9KWCKN6dzyuT5xP1ny4wz9f5xCLjAF6Y9s9EoTW4aE1X"
}
}

Complete Workflow Example

Sign a transaction, then broadcast it:

# Step 1: Sign the transaction
SIGNED_TX=$(curl -X POST https://api.thirdweb.com/v1/solana/sign-transaction \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"chainId": "solana:devnet",
"instructions": [...]
}' | jq -r '.result.signedTransaction')
# Step 2: Broadcast the signed transaction
curl -X POST https://api.thirdweb.com/v1/solana/broadcast-transaction \
-H "Content-Type: application/json" \
-H "x-secret-key: YOUR_SECRET_KEY" \
-d "{
\"chainId\": \"solana:devnet\",
\"signedTransaction\": \"$SIGNED_TX\"
}"

Error Handling

The broadcast endpoint provides detailed error information:

  • 400: Transaction failed (simulation or on-chain) - includes error details, instruction index, and signature
  • 504: Transaction timeout - not confirmed within 30 seconds
  • 500: Server error during broadcast

All errors include the transaction signature when available, allowing you to look up the transaction on Solana explorers for debugging.

Notes

  • Signature = Transaction Hash: In Solana, the "signature" is equivalent to an EVM transaction hash - use it to look up transactions on explorers
  • Confirmation: The broadcast endpoint waits for "confirmed" status before returning (typically 1-2 seconds on Solana)
  • Timeout: 30-second maximum wait time for confirmation
  • Preflight Checks: Failed transactions are caught during simulation before being sent to the network when possible

Arc Testnet is now supported by both of thirdweb's Account Abstraction solutions, EIP-4337 Smart Wallets and EIP-7702 stack - you can now use our sponsored execution features across all our interfaces. x402 via Nexus soon as well.

Support in API

curl https://api.thirdweb.com/v1/transactions \
--request POST \
--header 'Content-Type: application/json' \
--header 'x-secret-key: nnD...LafQ' \
--data '{
"chainId": 5042002,
"transactions": [
{
"data": "0x",
"to": "vitalik.eth",
"value": "0"
}
]
}'

Support in Typescript/React

const wallet = inAppWallet({
executionMode: {
mode: "EIP7702",
sponsorGas: true,
},
});

Support in .NET/Unity

var wallet = await InAppWallet.Create(
client: myThirdwebClient,
authProvider: AuthProvider.Guest,
executionMode: ExecutionMode.EIP7702Sponsored
);

Documentation for sponsoring transactions available here.

Etherlink Testnet and Etherlink Mainnet are now supported by thirdweb's EIP-7702 stack - you can now use our sponsored 7702 execution mode via all our interfaces.

Support in API

curl https://api.thirdweb.com/v1/transactions \
--request POST \
--header 'Content-Type: application/json' \
--header 'x-secret-key: nnD...LafQ' \
--data '{
"chainId": 128123,
"transactions": [
{
"data": "0x",
"to": "vitalik.eth",
"value": "0"
}
]
}'

Support in Typescript/React

const wallet = inAppWallet({
executionMode: {
mode: "EIP7702",
sponsorGas: true,
},
});

Support in .NET/Unity

var wallet = await InAppWallet.Create(
client: myThirdwebClient,
authProvider: AuthProvider.Guest,
executionMode: ExecutionMode.EIP7702Sponsored
);

Documentation for sponsoring transactions available here.