[go: up one dir, main page]

Changelog

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.

Sei Testnet and Sei 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": 1329,
"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.

What's Changed

  • Added Login With Siwe node that works similarly to Login With OAuth, allowing you to either Sign In with an External Wallet or Link an External Wallet to an existing In-App/Ecosystem Wallet.
image
  • Improved authentication session cleanup and lifecycle handling.
  • Enhanced thread-safety for authentication callbacks.
  • Fixed various flows that might lead to a crash.

Links

Github | Fab Marketplace (2.4.0 will be approved on Fab in a few days)

Celo is now supported by thirdweb's EIP-7702 stack - you can now use our sponsored 7702 execution mode in the SDK (or implicitly, send transactions via the thirdweb API)

const wallet = inAppWallet({
// enable gasless transactions for the wallet
executionMode: {
mode: "EIP7702",
sponsorGas: true,
},
});

Documentation for sponsoring transactions available here.

Hyperliquid is now supported by thirdweb's ERC-4337 stack - you can now use Smart Wallets on Hyperliquid Testnet & Mainnet.

const wallet = inAppWallet({
executionMode: {
mode: "EIP4337",
smartAccount: {
chain: defineChain(998),
sponsorGas: true,
},
},
});

We hope to integrate EIP-7702 relaying as well once the HyperEVM supports it.

Documentation for sponsoring transactions available here.

Following our recent announcement of Solana API support, we're excited to bring Solana server wallet management directly into the thirdweb dashboard. You can now create, manage, and test Solana wallets through an intuitive interface, no code required.

What's New

Dashboard Support for Solana Server Wallets

The Vault in your project dashboard now supports Solana! Upgrade your vault to unlock the ability to create and manage Solana server wallets directly from the UI. Every wallet you create is immediately available for use with the Solana API we announced previously.

Key Features

Create Solana Server Wallets

Navigate to Transactions in your project sidebar and locate the Server Wallets card. If you're on an existing project, you'll be prompted to upgrade your vault to enable Solana support. New projects have this enabled by default. Just click "Create Wallet", select Solana as your chain, give it a label, and your wallet is provisioned instantly. No keypair management, no security headaches.

Each wallet gets:

  • A unique Solana address (mainnet and devnet supported)
  • Automatic secure key management
  • Immediate API access via your project's secret key
  • Full transaction history and monitoring

Send Test Transactions

Before going live, test your setup directly in the dashboard. The built-in transaction interface lets you send a 0 SOL transaction and view transaction status in real-time.

Perfect for testing integrations, verifying wallet balances, or running through your transaction flows before deployment.

Seamless API Integration

Every dashboard-created wallet works immediately with the Solana API endpoints:

  • Use POST /v1/solana/send to transfer tokens programmatically
  • Submit custom transactions with POST /v1/solana/transactions
  • Sign messages with POST /v1/solana/sign-message
  • List all your wallets with GET /v1/solana/wallets

Your wallet's label and address are available in both the dashboard UI and via API, making it easy to manage wallets across your team and your applications.

Getting Started

  1. Navigate to Transactions
    From your project dashboard, click "Transactions" in the sidebar.
  2. Upgrade Vault (Existing Projects Only)
    In the Server Wallets card, click "Enable Solana" if prompted. New projects can skip this step, Solana support is already enabled.
  3. Create Your First Wallet
    Click "Create Wallet", select "Solana" as the chain, choose mainnet or devnet, and give it a descriptive label like "my-treasury-wallet".
  4. Send a Test Transaction
    Click into your new wallet and use the "Send" interface to transfer some SOL. Watch the transaction confirm in real-time.
  5. Use with API
    Copy your wallet address and start using it with the Solana API endpoints. Authenticate with your project's secret key via the x-secret-key header.

Transaction Details

Click on any transaction to view comprehensive information including signature, signer address, slot number, confirmation time, block time, and instruction-level details. The detailed view breaks down each instruction with program IDs, account metadata, and raw transaction data. Perfect for debugging and understanding exactly what happened on-chain.

Introduces a new GET /v1/bridge/routes endpoint to list supported bridge routes with pagination and optional filters for source/destination chains and tokens.

Added

  • GET /v1/bridge/routes — list all supported bridge routes
  • Supports filters:
    • by origin/destination chain
    • by token address
    • by max steps (e.g. single-hop routes)
  • Pagination with limit, page, and hasMore

Examples

# Basic
curl -X GET "https://api.thirdweb.com/v1/bridge/routes?limit=10&page=1" \
-H "x-secret-key: YOUR_SECRET_KEY"
# From Ethereum → Base
curl -X GET "https://api.thirdweb.com/v1/bridge/routes?originChainId=1&destinationChainId=8453" \
-H "x-secret-key: YOUR_SECRET_KEY"
# Single-hop
curl -X GET "https://api.thirdweb.com/v1/bridge/routes?maxSteps=1" \
-H "x-secret-key: YOUR_SECRET_KEY"
# Filter by token
curl -X GET "https://api.thirdweb.com/v1/bridge/routes?originChainId=1&originTokenAddress=0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" \
-H "x-secret-key: YOUR_SECRET_KEY"
# Combined filters
curl -X GET "https://api.thirdweb.com/v1/bridge/routes?originChainId=1&destinationChainId=8453&originTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&maxSteps=2" \
-H "x-secret-key: YOUR_SECRET_KEY"

Response Format

{
"result": {
"routes": [
{
"originToken": {
"chainId": 1,
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"symbol": "USDC",
"name": "USD Coin",
"decimals": 6,
"iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
},
"destinationToken": {
"chainId": 8453,
"address": "0xfA980cEd6895AC314E7dE34Ef1bFAE90a5AdD21b",
"symbol": "PRIME",
"name": "Prime",
"decimals": 18,
"iconUri": "https://coin-images.coingecko.com/coins/images/29053/large/prime-logo-small-border_%282%29.png?1696528020"
}
}
],
"pagination": {
"limit": 1,
"page": 1,
"hasMore": true
}
}
}

Improved Transaction Details page - now with Bridge Status and a cleaner, explorer-style design

Bridge Status

Transactions that are part of a bridge now display a dedicated Bridge section showing cross-chain details, token amounts, and status.

Example: https://thirdweb.com/polygon/tx/0x28486b565957a64eec8e408f149e796d455537f360b23442e51cbec812df233f

Transaction Details with Bridge Status

UI Improvements

The general transaction details layout has been updated to align with the standard design used in most chain explorers, making it more user-friendly

We’ve added a new Webhook Events view for Bridge webhooks to help monitor and debug webhook deliveries more easily.

You can now:

  • View all delivery attempts - see every webhook event sent to your endpoint, along with status codes, timestamps, and payload details.
  • Inspect payloads and responses - review the exact JSON payload and the response returned by your endpoint.
  • Resend webhooks - trigger a webhook delivery again with the same payload, which is useful for testing or retrying failed events.
Webhook Events

We're proud to announce initial support for Solana via the thirdweb API. This is the first of many releases making Solana more accessible to Ethereum developers.

Note: For the time being, you must create a new project from the thirdweb dashboard and use its secret key (server-side) to authenticate to the Solana APIs via the x-secret-key header.

Getting Started

All Solana endpoints are available at https://api.thirdweb.com/v1/solana/* and require authentication via the x-secret-key header:

x-secret-key: YOUR_SECRET_KEY

The API supports both Solana Mainnet (solana:mainnet) and Solana Devnet (solana:devnet) networks.


Create a Solana Wallet

Create or retrieve a managed Solana wallet using a unique label. If a wallet with the given label already exists, it will be returned instead of creating a new one.

Endpoint: POST https://api.thirdweb.com/v1/solana/wallets

Example Request:

curl -X POST https://api.thirdweb.com/v1/solana/wallets \
-H "x-secret-key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"label": "my-treasury-wallet"
}'

Example Response:

{
"result": {
"address": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"label": "my-treasury-wallet",
"createdAt": "2025-10-11T14:22:11.000Z",
"updatedAt": "2025-10-11T14:22:11.000Z"
}
}

The wallet is securely stored and can be used for signing transactions and messages.


List Solana Wallets

Retrieve all Solana wallets created for your project with pagination support.

Endpoint: GET https://api.thirdweb.com/v1/solana/wallets

Query Parameters:

  • page (optional): Page number, defaults to 1
  • limit (optional): Number of wallets per page (1-500), defaults to 100

Example Request:

curl -X GET "https://api.thirdweb.com/v1/solana/wallets?page=1&limit=50" \
-H "x-secret-key: YOUR_SECRET_KEY"

Example Response:

{
"result": {
"wallets": [
{
"address": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"label": "my-treasury-wallet",
"createdAt": "2025-10-11T14:22:11.000Z",
"updatedAt": "2025-10-11T14:22:11.000Z"
}
],
"pagination": {
"totalCount": 125,
"page": 1,
"limit": 50
}
}
}

Send Tokens

Transfer native SOL or SPL tokens with a single API call. The API automatically handles SPL token account creation if needed.

Endpoint: POST https://api.thirdweb.com/v1/solana/send

Send Native SOL

Example Request:

curl -X POST https://api.thirdweb.com/v1/solana/send \
-H "x-secret-key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"to": "FhtwVYF1wKAm7fWmE2N5P2eCv13wt2aT8W4Q9NQ9YcJH",
"amount": "1000000",
"chainId": "solana:devnet"
}'
Note: Amounts are specified in lamports (1 SOL = 1,000,000,000 lamports)

Send SPL Tokens (Like USDC)

Example Request:

curl -X POST https://api.thirdweb.com/v1/solana/send \
-H "x-secret-key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"to": "FhtwVYF1wKAm7fWmE2N5P2eCv13wt2aT8W4Q9NQ9YcJH",
"amount": "1000000",
"chainId": "solana:devnet",
"tokenAddress": "HZW5eXoaZySUdkGFwmkpfMoP1jmvYzu3PV6PvUCa3y7F"
}'

Example Response:

{
"result": {
"transactionId": "solana-tx-queue-id-abc123"
}
}

Transactions are queued and processed asynchronously. Use the returned transactionId to poll for status.


Send Transaction

For advanced use cases, submit custom Solana transactions with one or more instructions. This gives you full control over program interactions.

Endpoint: POST https://api.thirdweb.com/v1/solana/transactions

Example Request (SOL Transfer):

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

Instruction Fields:

  • programId: The Solana program to invoke
  • accounts: Array of account metadata (address, isSigner, isWritable)
  • data: Instruction data in hex or base64 encoding
  • encoding: Either "hex" or "base64" (defaults to "base64")

Example Response:

{
"result": {
"transactionId": "solana-tx-queue-id-xyz789"
}
}

Get Transaction

Check the status of any queued transaction using its transaction ID.

Endpoint: GET https://api.thirdweb.com/v1/solana/transactions/{transactionId}

Example Request:

curl -X GET https://api.thirdweb.com/v1/solana/transactions/solana-tx-queue-id-abc123 \
-H "x-secret-key: YOUR_SECRET_KEY"

Example Response:

{
"result": {
"id": "solana-tx-queue-id-abc123",
"chainId": "solana:devnet",
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"signature": "5j8k9L4mN3pQ2rS7tU6vW8xY9zA1bC2dE3fG4hH5iJ6kK7lL8mM9nN0oO1pP2qQ3rR4sS5tT6uU7vV8wW9xX0yY",
"status": "CONFIRMED",
"confirmedAt": "2025-10-11T14:23:45.000Z",
"confirmedAtSlot": "123456789",
"blockTime": 1728654225,
"createdAt": "2025-10-11T14:23:11.000Z",
"errorMessage": null,
"clientId": "your-client-id"
}
}

Transaction Statuses:

  • QUEUED: Transaction is waiting to be submitted
  • SUBMITTED: Transaction has been submitted to the network
  • CONFIRMED: Transaction is confirmed on-chain
  • FAILED: Transaction failed (check errorMessage for details)

Sign Message

Sign arbitrary messages with your Solana wallet. Supports both plain text and hexadecimal formats with automatic detection.

Endpoint: POST https://api.thirdweb.com/v1/solana/sign-message

Example Request (Plain Text):

curl -X POST https://api.thirdweb.com/v1/solana/sign-message \
-H "x-secret-key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"message": "Welcome to my dApp!"
}'

Example Request (Hex Format):

curl -X POST https://api.thirdweb.com/v1/solana/sign-message \
-H "x-secret-key: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "8JBLmveV4YF5AQ7EVnKJgyj6etGgVkPp3tYqQMTu3p5B",
"message": "0x48656c6c6f20536f6c616e61"
}'

Example Response:

{
"result": {
"signature": "5Nftk1W4nN6Xr2y4griH4sHqY2cD3rPrXg5BDJ9Y6hHSF3oURaUz6VXo4Qzv6TQ2Jj3MdE4Y5nVkq"
}
}

The signature is returned in Base58 format and can be used for authentication and verification.


Coming Soon

We're actively working on expanding our Solana support. Here's what's coming next:

Official thirdweb Solana RPCs

High-performance, globally distributed RPC endpoints optimized for Solana applications.

Solana Swap API

Seamlessly swap tokens on Solana with the best rates from top DEXs like Jupiter and Raydium.

Solana Token Deployment API

Deploy your own SPL tokens with a single API call, including support for Token-2022 program features.


Need Help?

We can't wait to see what you build with Solana on thirdweb! 🚀

We have added support for creating and deploying ZK Proof based token contracts with Stylus. The templates provide you with Stylus contracts, ZK circuit files, and a ready-to-deploy Next.js app + API for proof generation and minting.

This guide walks you through building a privacy-preserving ERC721 token system using Zero-Knowledge proofs on Arbitrum Stylus. Users can mint tokens by proving they own a minimum amount of ETH without revealing their exact balance.

What You'll Build

  • ZK Circuit: Proves token ownership without revealing exact balances
  • Stylus Contract: Rust-based ERC721 contract that verifies ZK proofs
  • Frontend: Next.js app for generating proofs and minting tokens
  • Oracle System: Secure balance verification mechanism

Prerequisites

Step 1: Project Setup

Using thirdweb CLI

npx thirdweb create-stylus

Select "Stylus ZK ERC721" from the dropdown menu. This will:

  • Clone the repository to your machine
  • Set up the project structure
  • Install basic dependencies

Manual Setup (Alternative)

git clone https://github.com/thirdweb-example/stylus-zk-erc721.git
cd stylus-zk-erc721

Step 2: Install Dependencies

Install dependencies for all components:

# Install root dependencies
pnpm install
# Install circuit dependencies
cd circuits
pnpm install
cd ..
# Install frontend dependencies
cd app
pnpm install
cd ..

Step 3: Generate Cryptographic Keys

Run the setup script to generate oracle keys and build the ZK circuit:

chmod +x setup.sh
./setup.sh

This script will:

  • Generate a random oracle secret key
  • Inject the secret into the ZK circuit
  • Compile the circuit with circom
  • Generate proving and verification keys
  • Create the trusted setup for Groth16

⚠️ Important: The oracle secret is critical for security. Keep it private!

Step 4: Deploy the Contract

Using thirdweb CLI

cd contracts
npx thirdweb@latest deploy-stylus -k <THIRDWEB_SECRET_KEY>

Using Stylus CLI (Alternative)

cd contracts
cargo stylus deploy --endpoint arbitrum-sepolia

Copy the deployed contract address - you'll need it for the frontend.

Step 5: Configure the Frontend

Update the contract address in your frontend:

cd app
# Edit pages/index.tsx or lib/config.ts
# Update ZK_MINT_CONTRACT_ADDRESS with your deployed address

Create environment file:

# app/.env.local
RPC_URL=https://sepolia-rollup.arbitrum.io/rpc
ORACLE_SECRET_KEY=<your_oracle_secret_from_setup>

Step 6: Run the Application

cd app
pnpm dev
# Visit http://localhost:3000

Step 7: Test the System

  1. Connect Wallet: Connect to Arbitrum Sepolia testnet
  2. Generate Proof: Click "Generate ZK Proof" - this proves you have sufficient balance
  3. Mint Tokens: Use the proof to mint ERC721 tokens

Customizing the ZK Logic

Understanding the Circuit

The core circuit (circuits/token_ownership.circom) has these components:

template TokenOwnership(oracle_secret) {
// Private inputs (hidden from public)
signal input actual_balance; // Real balance from oracle
signal input salt; // Randomness for uniqueness
// Public inputs (visible on-chain)
signal input min_required_balance; // Minimum threshold
signal input token_contract_hash; // Which token to check
signal input user_address_hash; // User's address hash
signal input timestamp; // When oracle signed data
signal input oracle_commitment; // Oracle's commitment
// Output
signal output nullifier; // Prevents replay attacks
}

Customization Examples

1. Change Balance Threshold Logic

Replace the balance check with custom logic:

// Original: Simple greater-than check
component gte = GreaterEqThan(64);
gte.in[0] <== actual_balance;
gte.in[1] <== min_required_balance;
gte.out === 1;
// Custom: Logarithmic scaling
component log_check = LogarithmicCheck();
log_check.balance <== actual_balance;
log_check.threshold <== min_required_balance;
log_check.out === 1;

2. Add Multiple Token Support

Extend the circuit to verify multiple token balances:

template MultiTokenOwnership(oracle_secret, num_tokens) {
signal input actual_balances[num_tokens];
signal input min_required_balances[num_tokens];
signal input token_addresses[num_tokens];
// Verify each token separately
component checks[num_tokens];
for (var i = 0; i < num_tokens; i++) {
checks[i] = GreaterEqThan(64);
checks[i].in[0] <== actual_balances[i];
checks[i].in[1] <== min_required_balances[i];
checks[i].out === 1;
}
}

3. Add Time-Based Constraints

Add expiration logic to proofs:

// Add time validation
component time_check = LessThan(64);
time_check.in[0] <== timestamp;
time_check.in[1] <== max_timestamp; // New public input
time_check.out === 1;

Rebuilding After Changes

After modifying the circuit:

cd circuits
pnpm run build
# Re-inject verification keys
cd ..
node scripts/inject-vk.js
# Recompile contract
cd contracts
cargo build

Additional Resources

Support

Need help? Please reach out to our support team.

We’ve made several updates to the BuyWidget component to make it more flexible, interactive, and user-friendly - giving users more control while simplifying integration.

New BuyWidget UI

Token and Chain selection can now be changed in the widget UI

Clicking on the selected token opens a Modal that allows changing the selected chain and token. chain, and amount props are now optional

Both fiat and token amounts are editable

Both the fiat and token amount fields can be edited, making it easier to input custom fiat amounts beyond just selecting the suggested fiat amounts.

The wallet's current balance is also shown in the bottom-right corner which helps in choosing the buy amount

Connected wallet displayed

A button is added on the top-right corner that shows the connected wallet, Clicking on it opens the Wallet Details modal, which allows switching the active wallet or disconnecting the wallet

Try it out

Try out the new and improved BuyWidget in playground

TLDR: The thirdweb API from fields when transacting are now optional - this is powered by the newly launched Project Wallets - go set one up!

What’s new

When you’re orchestrating transactions from your backend, repeating the same sender address in every payload is the definition of busywork. Starting today, you can skip it. Authenticate with your project’s secret key, leave off the from field, and we’ll launch those transactions straight from your project wallet.

  • Automatic sender fallback for server-side flows that use your project secret key.
  • Works everywhere you submit encoded calls, trigger wallet actions, deploy or write contracts, mint tokens, process payments, or swap via the bridge API.
  • Still honors explicit from values when you need to override the default.

Why you’ll love it

Removing boilerplate means less room for typos, quicker prototyping, and cleaner shared helpers. Your integrations stay lean while every transaction still resolves to the right wallet.

Try it now

curl https://api.thirdweb.com/v1/transactions \
-H "Content-Type: application/json" \
-H "x-secret-key: <your-secret-key>" \
-d '{
"chainId": 421614,
"transactions": [
{
"data": "0x",
"to": "vitalik.eth",
"value": "0"
}
]
}'

No from required—just the secret key that unlocks your project wallet.

We’ve introduced Project Wallets as a first-class part of the dashboard so every project comes with a managed server wallet you can see, fund, and control right from the overview screen.

Persistent wallet card

The Project Wallet section will stick around under Overview, giving teams a home base for balances, addresses, and actions.

Send funds or refresh balances right from the card, with labels and addresses trimmed for clarity.

Send & receive in one place

Kick off transfers or open the funding modal without leaving the page.

Change the default wallet

When multiple server wallets exist, pick a new default directly from the card. The change propagates instantly across integrations.

Other Integrations

You can autifill your project wallet in the Create a Payment and Earn Fees flows.

Secure

When using a managed Vault, you can use your secret key to interact with the Project Wallet - if you eject from the managed Vault, you may be prompted for an additional vault access token to interact with it. Via API, this looks like an additional x-vault-access-token header.

What’s next

  • Integration for gasless deployments — Token and Contract flows
  • Integration into thirdweb API — will be used when a from address is not specified for your backend flows.
  • Integration into any Transaction Button ("Execute" flow) you might encounter during your dashboard journey, from places like contract explorers for example.

Links

Create a new project now!

Feel free to provide feedback @ https://thirdweb.com/support

You can now pay for any x402 compatible endpoint using the the new /v1/payments/x402/fetch API.

What's new

The new /v1/payments/x402/fetch in the thirdweb API proxies any url, and upon receiving HTTP 402 payment required response, automatically handles the payment with the authenticated wallet.

Query params

  • url - target endpoint to fetch
  • from - the wallet address to pay with
  • method - optional HTTP method for the endpoint to fetch (defaults to POST)
  • maxValue - optional max amount that can be paid
  • asset - optional payment token, if not specified defaults to the target endpoint payment method
  • chainId - optional payment chain, if not specified defaults to the target endpoint payment chain

Request body and headers will be forwarded to the target url.

Usage

You can use this from any language, any platform. Use it with your server wallets (using your project secret key) or with user in-app wallets (using the user JWT).

This makes is much easier to implement x402 payments for apps and agents.

Simply call this endpoint in your frontend or your agent tool to automatically pay for any x402 compatible endpoint.

Learn more

Happy building! 🛠️

New Endpoints

We just shipped a pair of routes that make it painless to manage external wallets (via Sign-In-With-Ethereum aka SIWE) and other common authentication methods on user accounts. Both endpoints live under https://api.thirdweb.com and return fully normalized linked-account data so you don’t have to juggle different provider shapes.

POST /v1/auth/link

Link an additional authentication method or wallet to your account.

Authentication Required: Client token + Wallet token

Request Body:

{
"accountAuthTokenToConnect": "string"
}

Response:

{
"linkedAccounts": [
{
"type": "siwe" | "guest" | ...,
"id": "string",
"details": { ... }
}
]
}

POST /v1/auth/unlink

Unlink an authentication provider from your account.

Authentication Required: Client token + Wallet token

Request Body:

{
"type": "siwe" | "guest" | ...,
"details": {
"address": "0x...", // optional
"walletAddress": "0x...", // optional
"email": "...", // optional
"phone": "...", // optional
"id": "..." // optional
},
"allowAccountDeletion": false // optional
}

Note: At least one identifier in details is required.

Response:

{
"linkedAccounts": [
{
"type": "siwe" | "guest" | ...,
"id": "string",
"details": { ... }
}
]
}