diff --git a/apps/portal/src/app/Header.tsx b/apps/portal/src/app/Header.tsx
index 5799322e43a..4451b001fb4 100644
--- a/apps/portal/src/app/Header.tsx
+++ b/apps/portal/src/app/Header.tsx
@@ -31,14 +31,6 @@ const links = [
href: "/wallets",
name: "Wallets",
},
- {
- href: "/transactions",
- name: "Transactions",
- },
- {
- href: "/contracts",
- name: "Contracts",
- },
{
href: "/x402",
name: "x402",
@@ -52,31 +44,12 @@ const links = [
name: "Tokens",
},
{
- href: "/reference",
- name: "API Reference",
- },
-];
-
-const toolLinks = [
- {
- href: "https://thirdweb.com/chainlist",
- name: "Chain List",
- },
- {
- href: "https://thirdweb.com/tools/wei-converter",
- name: "Wei Converter",
- },
- {
- href: "https://thirdweb.com/tools/hex-converter",
- name: "Hex Converter",
- },
- {
- href: "/account/api-keys",
- name: "API Keys",
+ href: "/ai/chat",
+ name: "AI",
},
{
- href: "/cli",
- name: "CLI",
+ href: "/reference",
+ name: "API Reference",
},
];
@@ -122,44 +95,6 @@ export const connectLinks: Array<{
},
] as const;
-const apisLinks = [
- {
- href: "https://api.thirdweb.com/reference",
- name: "HTTP API",
- },
- {
- href: "/insight",
- name: "Insight",
- },
- {
- href: "https://engine.thirdweb.com/reference#tag/write",
- name: "Transactions",
- },
- {
- href: "https://bridge.thirdweb.com/reference",
- name: "Payments",
- },
- {
- href: "/bundler",
- name: "Bundler",
- },
-];
-
-const aiLinks = [
- {
- href: "/ai/chat",
- name: "Blockchain LLM",
- },
- {
- href: "/ai/mcp",
- name: "MCP",
- },
- {
- href: "/ai/llm-txt",
- name: "LLMs.txt",
- },
-];
-
const sdkLinks = [
{
href: "/references/typescript/v5",
@@ -300,27 +235,11 @@ export function Header() {
-
setShowBurgerMenu(false)}
- />
setShowBurgerMenu(false)}
/>
- setShowBurgerMenu(false)}
- />
-
- setShowBurgerMenu(false)}
- />
-
-
AI
- {aiLinks.map((link) => (
- setShowBurgerMenu(false)}
- />
- ))}
-
-
SDKs
{sdkLinks.map((link) => (
@@ -380,18 +287,6 @@ export function Header() {
))}
-
-
APIs
- {apisLinks.map((link) => (
- setShowBurgerMenu(false)}
- />
- ))}
-
-
Support
{supportLinks.map((link) => (
@@ -409,18 +304,6 @@ export function Header() {
name="Changelog"
onClick={() => setShowBurgerMenu(false)}
/>
-
-
-
Tools
- {toolLinks.map((link) => (
- setShowBurgerMenu(false)}
- />
- ))}
-
)}
diff --git a/apps/portal/src/app/ai/chat/page.mdx b/apps/portal/src/app/ai/chat/page.mdx
index b546c41c1ba..81686dd4b18 100644
--- a/apps/portal/src/app/ai/chat/page.mdx
+++ b/apps/portal/src/app/ai/chat/page.mdx
@@ -2,19 +2,22 @@ import { Tabs, TabsContent, TabsList, TabsTrigger, OpenApiEndpoint } from "@doc"
# Blockchain LLM
-The thirdweb API exposes a standard OpenAI-compatible chat completion API that allows you to interact with the thirdweb AI model, optimized for blockchain interactions.
+The thirdweb API provides an OpenAI-compatible chat completion interface optimized for blockchain interactions.
-- Query real-time data from the blockchain
+You can use it to:
+
+- Query on-chain data
- Analyze transactions
-- Fetch token balances, prices and metadata
-- Execute or prepare any contract call or transaction
-- Execute or prepare swaps from/to any token pair
+- Fetch token info and prices
+- Execute or prepare contract calls and swaps
- Deploy contracts
-- Generate images
-- Search the web
-- And more!
+- Generate images and search the web
+
+and more.
+
+## QuickStart
-You can use the API with the HTTP API directly, the AI SDK or with any OpenAI-compatible client library.
+You can use thirdweb AI with the HTTP API directly, the AI SDK, or with any OpenAI-compatible client library.
diff --git a/apps/portal/src/app/ai/faq/page.mdx b/apps/portal/src/app/ai/faq/page.mdx
new file mode 100644
index 00000000000..ddc7cdf1314
--- /dev/null
+++ b/apps/portal/src/app/ai/faq/page.mdx
@@ -0,0 +1,26 @@
+import { createMetadata, Details } from "@doc";
+
+export const metadata = createMetadata({
+ title: "AI FAQs | thirdweb documentation",
+ description: "",
+ image: {
+ title: "AI FAQs",
+ icon: "wallets",
+ },
+});
+
+# AI FAQ
+
+## General
+
+
+ The context size or window is 128k tokens or approximately 96,000 words which may vary depending on the specific language and text characteristics.
+
+
+
+ The AI supports reading and writing capabilities on any supported EVM chain. View the full list of supported chains.
+
+
+
+ Yes, you may prompt it in any spoken language.
+
\ No newline at end of file
diff --git a/apps/portal/src/app/ai/sidebar.tsx b/apps/portal/src/app/ai/sidebar.tsx
index 371b7ed46d7..5f9b6a9c612 100644
--- a/apps/portal/src/app/ai/sidebar.tsx
+++ b/apps/portal/src/app/ai/sidebar.tsx
@@ -4,19 +4,20 @@ import type { SideBar } from "@/components/Layouts/DocLayout";
export const sidebar: SideBar = {
links: [
{
- name: "Blockchain LLM",
+ name: "Get Started",
+ href: "/ai/chat",
+ icon: ,
+ },
+ {
+ href: "https://playground.thirdweb.com",
+ name: "Playground",
+ icon: ,
+ },
+ { separator: true },
+ {
+ name: "Guides",
isCollapsible: false,
links: [
- {
- name: "Get Started",
- href: "/ai/chat",
- icon: ,
- },
- {
- name: "Playground",
- href: "https://playground.thirdweb.com/ai/chat",
- icon: ,
- },
{
name: "Transaction Execution",
href: "/ai/chat/execution",
@@ -26,12 +27,17 @@ export const sidebar: SideBar = {
href: "/ai/chat/streaming",
},
{
- name: "Vercel AI SDK",
- href: "/ai/chat/ai-sdk",
- },
- {
- name: "OpenAI SDK",
- href: "/ai/chat/openai-sdk",
+ name: "Integrations",
+ links: [
+ {
+ name: "Vercel AI SDK",
+ href: "/ai/chat/ai-sdk",
+ },
+ {
+ name: "OpenAI SDK",
+ href: "/ai/chat/openai-sdk",
+ },
+ ],
},
{
name: "API Reference",
@@ -41,14 +47,31 @@ export const sidebar: SideBar = {
},
{ separator: true },
{
- name: "MCP Server",
- icon: ,
- href: "/ai/mcp",
+ name: "Agent Tools",
+ isCollapsible: false,
+ links: [
+ {
+ name: "MCP Server",
+ icon: ,
+ href: "/ai/mcp",
+ },
+ {
+ name: "llms.txt",
+ icon: ,
+ href: "/ai/llm-txt",
+ },
+ ],
},
+ { separator: true },
{
- name: "llms.txt",
- icon: ,
- href: "/ai/llm-txt",
+ name: "Resources",
+ isCollapsible: false,
+ links: [
+ {
+ href: "/ai/faq",
+ name: "FAQ",
+ },
+ ],
},
],
name: "AI",
diff --git a/apps/portal/src/app/bridge/faq/page.mdx b/apps/portal/src/app/bridge/faq/page.mdx
index 920202dd4e8..1dab63ea1a4 100644
--- a/apps/portal/src/app/bridge/faq/page.mdx
+++ b/apps/portal/src/app/bridge/faq/page.mdx
@@ -13,49 +13,49 @@ export const metadata = createMetadata({
### General
-
-Bridge is an asset router that combines thirdweb's own onchain infrastructure with existing bridging and swapping protocols to find the optimal route for any given transaction.
-This can include intents, native bridges, third party bridges, cross-chain messaging protocols, thirdweb's custom bridges, and more. All routes are monitored and planned continuously for
-health, price, and speed to guarantee the best path every time.
+
+Bridge is an asset router that combines thirdweb's own onchain infrastructure with existing bridging and swapping protocols to find the optimal route for any given transaction. This can include intents, native bridges, third party bridges, cross-chain messaging protocols, thirdweb's custom bridges, and more. All routes are monitored and planned continuously for health, price, and speed to guarantee the best path every time.
-
-Yes, Bridge is designed to be agnostic to wallet infrastructure. You can use it with any wallet service.
+
+Yes, Bridge is designed to be agnostic to wallet infrastructure. You can use it with any wallet service.
### Fees
-
-thirdweb does not charge any fees for buy with fiat. Any fees on onramping are based on the onramp provider.
+
+Fees for onramping are based on the onramp provider. thirdweb does not determine nor take a cut from onramp provider fees.
+
+[Learn more about onramp fees](/bridge/resources/fee-breakdown).
-
-For buying with crypto or swap fees, thirdweb charges a 0.3% protocol fee. Developers may monetize their application by charging additional fees on swap transactions. To set a fee in your project page, navigate to Payments > Settings to set this fee.
+
+For buying with crypto or swap fees, thirdweb charges a 0.3% protocol fee. Developers may monetize their application by charging additional fees on swap transactions. To set a fee in your project page, navigate to Bridge > Configuration to set the fee.
-
+
Network fees, also referred to as miner fees, are paid to the miner for processing crypto transactions and securing the respective network. These fees do not go to thirdweb.
-
+
Fiat payouts are not currently available.
### Token & Region Support
-
+
We're able to support most tokens that meet the following criteria:
- The token must have sufficient liquidity
-- The token must be on a [supported Payments Chain](https://thirdweb.com/chainlist?service=pay).
+- The token must be on a supported chain.
-To request support for a token, please visit the Payments tab in your project dashboard > Settings > "Don't see your token listed?" component and fill out the chain and token address information.
+To request support for a token, please visit the Bridge tab in your project dashboard > Settings > "Don't see your token listed?" component and fill out the chain and token address information.
-The service will automatically kick off the token route discovery process. Please check back the Payments modal after 20-40 minutes for the requested token.
+The service will automatically kick off the token route discovery process. Please check back the modal after 20-40 minutes for the requested token.
-
-**Buy With Fiat** is available 160+ countries. The following countries are _UNSUPPORTED_:
+
+Buy With Fiat is available 160+ countries. The following countries are UNSUPPORTED:
- Afghanistan
- Africa (All Countries)
@@ -82,21 +82,21 @@ The service will automatically kick off the token route discovery process. Pleas
All United States are supported, excluding Hawaii.
-
-Bridge can support any currency on our [supported chains](https://thirdweb.com/chainlist?service=pay).
+
+[View the full list](https://thirdweb.com/tokens) of supported tokens on Bridge.
-
+
Apple Pay and Google Pay are supported through the onramp providers depending on region. Coinbase, Stripe, and Transak currently support Apple Pay. Transak supports Google Pay.
-
-We currently require a $1 minimum purchase for both stablecoin and non-stablecoin purchases through Buy With Fiat.
+
+We currently require a $1 minimum purchase for both stablecoin and non-stablecoin purchases through onramp.
Our transaction maximum starts from $1500 per week for new users and can increase over time to $10,000 per week.
-
+
We offer direct onramping **internationally** to the following tokens:
- Mainnet (Ethereum)
@@ -105,30 +105,29 @@ We offer direct onramping **internationally** to the following tokens:
We offer direct onramping to the following tokens in the **US only**:
-- ETH (Base)\*
+- ETH (Base)*
- USDC (Ethereum)
-- USDC (Polygon)\*
-- USDC (Avalanche)\*
-- USDC (Base)\*
+- USDC (Polygon)*
+- USDC (Avalanche)*
+- USDC (Base)*
All other tokens will require an additional Buy With Crypto step.
-\* Not available in New York or the EU.
+* Not available in New York or the EU.
-
+
Prices are set depending on the liquidity provider used to route your transaction.
### KYC & Compliance
-Onramp options all require minimal KYC. This is done to comply with local regulations and to ensure the safety of our users.
-Please note: onramping with Coinbase does not require KYC for a purchase below $500 with debit card.
+Onramp options all require minimal KYC. This is done to comply with local regulations and to ensure the safety of our users. Please note: onramping with Coinbase does not require KYC for a purchase below $500 with debit card.
-
-Users will be required to complete KYC verification for their first purchase using 'Buy with Fiat.' After that, no further KYC will be needed for future purchases on the same platform.
+
+Users will be required to complete KYC verification for their first purchase using onramp. After that, no further KYC will be needed for future purchases on the same platform.
diff --git a/apps/portal/src/app/bridge/onramp-providers/page.mdx b/apps/portal/src/app/bridge/onramp-providers/page.mdx
index 113f49d4c57..d0de481e8c9 100644
--- a/apps/portal/src/app/bridge/onramp-providers/page.mdx
+++ b/apps/portal/src/app/bridge/onramp-providers/page.mdx
@@ -2,39 +2,32 @@ import { createMetadata } from "@doc";
export const metadata = createMetadata({
image: {
- title: "thirdweb Payments - Onramp Providers",
+ title: "thirdweb Bridge - Onramp Providers",
icon: "thirdweb",
},
- title: "thirdweb Payments - Onramp Providers | thirdweb",
+ title: "thirdweb Bridge - Onramp Providers | thirdweb",
description:
"Integrate onramp providers for any onchain transaction and set preferred providers",
});
# Onramp Providers
-**Onramp Providers** are services that allow users to buy crypto with fiat. Payments supports the following onramp providers:
+**Onramp Providers** are services that allow users to buy crypto with fiat.
-- **Coinbase**
-- **Transak**
-- **Stripe**
+Bridge integrates the following onramp providers:
-## Provider Fees
+- [**Coinbase**](https://docs.cdp.coinbase.com/onramp-&-offramp/introduction/welcome)
+- [**Transak**](https://transak.com/)
+- [**Stripe**](https://docs.stripe.com/crypto/onramp)
-Each provider has different fees associated with their services which often depend on various factors. Onramp provider fees are set by the provider and are not controlled by thirdweb.
+## Provider Fees & Regions
-| Provider | Fees |
-| -------- | ---- |
-| Coinbase | [Learn more about Coinbase Fees](https://help.coinbase.com/en/coinbase/trading-and-funding/pricing-and-fees/fees) |
-| Transak | [Learn more about Transak Fees](https://support.transak.com/en/articles/7845942-how-does-transak-calculate-prices-and-fees)|
-| Stripe | [Learn more about Stripe Fees](https://stripe.com/legal/crypto-onramp). |
+Each provider sets its own fees, which may vary based on several factors. These fees are determined solely by the onramp provider and are not controlled or influenced by thirdweb.
+Each provider also has different regions and currencies they support.
-## Provider Regions
-
-Each provider has different regions they support. You can learn more about the supported regions for each provider in the links below.
-
-| Provider | Regions |
-| -------- | ------- |
-| Coinbase | [View Regions](https://docs.cdp.coinbase.com/onramp/docs/api-configurations) |
-| Transak | [View Regions](https://transak.com/global-coverage) |
-| Stripe | [View Regions](https://support.stripe.com/questions/crypto-supportability-and-availability-by-region) |
\ No newline at end of file
+| | Fees | Regions |
+| -------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
+| Coinbase | [View Fees](https://docs.cdp.coinbase.com/onramp-&-offramp/developer-guidance/faq#what-fees-do-you-charge%3F) | [View Regions](https://docs.cdp.coinbase.com/onramp-&-offramp/developer-guidance/faq#which-countries-are-supported-by-coinbase-onramp%3F) |
+| Stripe | N/A | [View Regions](https://support.stripe.com/questions/crypto-supportability-and-availability-by-region) |
+| Transak | [View Fees](https://transak.notion.site/On-Ramp-Payment-Methods-Fees-Other-Details-b0761634feed4b338a69f4f186d906a5) | [View Regions](https://transak.com/global-coverage) |
\ No newline at end of file
diff --git a/apps/portal/src/app/bridge/sidebar.tsx b/apps/portal/src/app/bridge/sidebar.tsx
index e863f3aa788..d9312f1d428 100644
--- a/apps/portal/src/app/bridge/sidebar.tsx
+++ b/apps/portal/src/app/bridge/sidebar.tsx
@@ -1,4 +1,4 @@
-import { ZapIcon } from "lucide-react";
+import { ExternalLinkIcon, ZapIcon } from "lucide-react";
import type { SideBar } from "@/components/Layouts/DocLayout";
import { EngineIcon, ReactIcon, TypeScriptIcon, UnityIcon } from "@/icons";
import { UnrealEngineIcon } from "../../icons/sdks/UnrealEngineIcon";
@@ -12,6 +12,11 @@ export const sidebar: SideBar = {
name: "Get Started",
icon: ,
},
+ {
+ href: "https://playground.thirdweb.com",
+ name: "Playground",
+ icon: ,
+ },
{ separator: true },
{
isCollapsible: false,
@@ -64,9 +69,9 @@ export const sidebar: SideBar = {
isCollapsible: false,
links: [
{
- href: `https://payments.thirdweb.com/reference`,
+ href: `/reference`,
icon: ,
- name: "REST API",
+ name: "HTTP API",
},
{
href: "/references/typescript/v5",
diff --git a/apps/portal/src/app/insight/agents-and-llms/llmstxt/page.mdx b/apps/portal/src/app/insight/agents-and-llms/llmstxt/page.mdx
deleted file mode 100644
index 052d21b821b..00000000000
--- a/apps/portal/src/app/insight/agents-and-llms/llmstxt/page.mdx
+++ /dev/null
@@ -1,510 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "thirdweb Insight For Agents & LLMs",
- description:
- "thirdweb Insight query documentation formatted for use with LLMs and agents",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Thirdweb Insight
-Insight is a powerful tool that lets you retrieve blockchain data from any EVM chain, enrich it with metadata, and transform it using custom logic. Whether you're building a gaming inventory system, tracking DeFi metrics, or analyzing NFT collections, Insight makes it easy to get the data you need with simple API calls.
-
-## Things to Keep in Mind
-
-- **Rate Limiting**: The API has rate limits based on your authentication tier. Monitor your usage and implement appropriate retry logic.
-
-- **Pagination**: When retrieving large datasets, use pagination parameters (`page` and `limit`) to avoid timeouts and manage response sizes effectively.
-
-- **Chain Selection**: Always verify you're querying the correct chain ID. Using an incorrect chain ID will return a 404 error.
-
-- **Data Freshness**: There may be a slight delay between on-chain events and their availability in the API due to block confirmation times.
-
-- **Error Handling**: Implement proper error handling for both HTTP errors (400/500) and network issues. Consider implementing retries for transient failures.
-
-- **Query Optimization**:
- - Use specific filters to reduce response size and improve performance
- - Avoid overly broad date ranges when possible
- - Consider using aggregations for large datasets
-
-- **Authentication**: Keep your authentication credentials secure and don't expose them in client-side code.
-
-- **Response Processing**: Some numeric values are returned as strings to maintain precision. Convert them appropriately in your application.
-
-## Aggregation Examples
-
-Insight supports various aggregation functions that can be used to analyze blockchain data. Here are some common examples:
-
-### Basic Aggregations
-
-```typescript
-// Count all transactions
-const count = await fetch('https://10.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count');
-
-// Get total value transferred (in wei)
-const totalValue = await fetch('https://10.insight.thirdweb.com/v1/transactions?aggregate=sum(value) AS total_value_wei');
-
-// Get average gas used
-const avgGas = await fetch('https://10.insight.thirdweb.com/v1/transactions?aggregate=avg(gas_used) AS avg_gas_used');
-```
-
-### Wallet-Specific Aggregations
-
-```typescript
-// Get wallet transaction count and total value
-const walletStats = await fetch(
- 'https://10.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei'
-);
-
-// Calculate total fees paid by a wallet
-const walletFees = await fetch(
- 'https://10.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=sum(gas_used * gas_price) AS total_fees_wei'
-);
-```
-
-### Block Data Aggregations
-
-```typescript
-// Get block statistics
-const blockStats = await fetch(
- 'https://10.insight.thirdweb.com/v1/blocks?aggregate=sum(transaction_count) AS total_transactions&aggregate=avg(transaction_count) AS avg_transactions_per_block'
-);
-
-// Get block range
-const blockRange = await fetch(
- 'https://10.insight.thirdweb.com/v1/blocks?aggregate=min(number) AS min_block_number&aggregate=max(number) AS max_block_number'
-);
-```
-
-### Filtering with Aggregations
-
-```typescript
-// Get transaction stats for a specific time period
-const txStats = await fetch(
- 'https://10.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&filter_timestamp_gte=2024-01-01&filter_timestamp_lte=2024-01-31'
-);
-
-// Get block metrics for recent blocks
-const recentBlocks = await fetch(
- 'https://10.insight.thirdweb.com/v1/blocks?aggregate=sum(transaction_count) AS total_transactions&filter_number_gte=18000000'
-);
-```
-
-## API URL
-
-```typescript
-const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;
-```
-
-## Authentication
-
-The API supports three authentication methods:
-
-```typescript
-// 1. Header Authentication
-const headers = {
- "x-client-id": "{{clientId}}", // thirdweb Client ID
-};
-
-// 2. Query Parameter
-const url = `https://{{chainId}}.insight.thirdweb.com/v1/events?clientId={{clientId}}`;
-
-// 3. Bearer Token
-const headers = {
- Authorization: "Bearer {{jwtToken}}",
-};
-
-// Example using fetch with header auth
-async function getEvents() {
- const response = await fetch(`https://{{chainId}}.insight.thirdweb.com/v1/events`, {
- headers: {
- "x-client-id": "{{clientId}}",
- },
- });
- return await response.json();
-}
-```
-
-## Core Concepts
-
-### Chain IDs
-
-The API supports chain IDs in the following formats:
-
-- As a subdomain:
-```typescript
-// Example
-const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;
-```
-
-- As a query parameter (this is useful if you want to query multiple chains):
-```typescript
-// Example for a single chain
-const url = `https://insight.thirdweb.com/v1/events?chain={{chainId}}`;
-// Example for multiple chains
-const url = `https://insight.thirdweb.com/v1/events?chain=1&chain=137`;
-```
-
-We won't duplicate multichain examples for each endpoint, but you can pass multiple chains in the query parameters pretty much everywhere!
-
-### Base Response Structure
-
-```typescript
-interface BaseResponse {
- data: T[];
- meta: {
- chain_id: number; // Required
- page: number; // Required
- limit: number; // Required
- total_items: number; // Required
- total_pages: number; // Required
- address?: string; // Optional
- signature?: string; // Optional
- }
-}
-
-// Example response from getting events
-{
- "data": [
- {
- "chain_id": 1,
- "block_number": "17859301",
- "transaction_hash": "0x123...",
- "address": "0x456...",
- "data": "0x789...",
- "topics": ["0xabc..."]
- }
- ],
- "meta": {
- "chain_id": 1,
- "page": 0,
- "limit": 20,
- "total_items": 150,
- "total_pages": 8
- }
-}
-```
-
-## API Examples
-
-### Events API
-
-```typescript
-// 1. Get All Events
-async function getAllEvents(): Promise> {
- const response = await fetch(`https://{{chainId}}.insight.thirdweb.com/v1/events`, {
- headers: { "x-client-id": "{{clientId}}" },
- });
- return await response.json();
-}
-
-// 2. Get Contract Events with Filtering
-async function getContractEvents(contractAddress: string): Promise> {
- const params = new URLSearchParams({
- filter_block_number_gte: "{{blockNumber}}",
- sort_by: "block_timestamp",
- sort_order: "desc",
- limit: "50",
- });
-
- const url = `https://{{chainId}}.insight.thirdweb.com/v1/events/${contractAddress}?${params}`;
- const response = await fetch(url, {
- headers: { "x-client-id": "{{clientId}}" },
- });
- return await response.json();
-}
-```
-
-### Token Balance API
-
-```typescript
-// 1. Get ERC20 Balances
-async function getERC20Balances(ownerAddress: string): Promise {
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc20/${ownerAddress}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- const data = await response.json();
- // Example response:
- // {
- // "data": [
- // {
- // "tokenAddress": "0x123...",
- // "balance": "1000000000000000000"
- // }
- // ]
- // }
- return data;
-}
-
-// 2. Get NFT Balances
-async function getNFTBalances(ownerAddress: string) {
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc721/${ownerAddress}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- const data = await response.json();
- // Example response:
- // {
- // "data": [
- // {
- // "collectionAddress": "0x456...",
- // "tokenId": "1",
- // "balance": "1"
- // }
- // ]
- // }
- return data;
-}
-```
-
-### Using Filters
-
-```typescript
-// Example: Get events with complex filtering
-async function getFilteredEvents() {
- const params = new URLSearchParams({
- // Block filters
- filter_block_number_gte: "{{startBlock}}",
- filter_block_number_lte: "{{endBlock}}",
-
- // Time filters
- filter_block_timestamp_gte: "{{startTimestamp}}",
-
- // Transaction filters
- filter_from_address: "{{fromAddress}}",
- filter_value_gte: "{{minValue}}", // 1 ETH
-
- // Pagination
- page: "0",
- limit: "20",
-
- // Sorting
- sort_by: "block_timestamp",
- sort_order: "desc",
- });
-
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/events?${params}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- return await response.json();
-}
-```
-
-### Error Handling
-
-```typescript
-async function safeApiCall() {
- try {
- const response = await fetch(`https://{{chainId}}.insight.thirdweb.com/v1/events`, {
- headers: { "x-client-id": "{{clientId}}" },
- });
-
- if (!response.ok) {
- const errorData = await response.json();
- // Example error response:
- // { "error": "Invalid client ID" }
- throw new Error(errorData.error);
- }
-
- return await response.json();
- } catch (error) {
- console.error("API Error:", error.message);
- throw error;
- }
-}
-```
-
-## Webhooks
-
-Webhooks allow you to receive notifications when specific blockchain events or transactions occur. This enables you to build event-driven AI agents that can react to on-chain activity in real-time.
-
-### Use Cases for AI Agents
-
-- **Real-time Monitoring**: An agent can monitor for specific events (e.g., a large transfer to a whale wallet) and trigger alerts or other actions.
-- **Automated Workflows**: When a specific on-chain action occurs (e.g., a new NFT is minted), an agent can automatically kick off a downstream process, like updating a database or sending a notification.
-- **Data Aggregation**: Use webhooks to feed on-chain data into a vector database or other data store for later analysis by an LLM.
-
-### Creating a Webhook
-
-Webhooks are created and managed via the Insight API. You can find more details in the [Managing Webhooks documentation](/insight/webhooks/managing-webhooks).
-
-### Filtering
-
-You can create powerful filters to specify exactly which events or transactions you want to be notified about.
-
-For example, to receive a notification for both ERC-20 and ERC-721 `Transfer` events, you can use a filter like this:
-
-```typescript
-{
- "v1.events": {
- "chain_ids": ["1"],
- "signatures": [
- {
- "sig_hash": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "abi": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"
- }
- ]
- }
-}
-```
-
-This allows an agent to monitor multiple token standards with a single webhook. For more on filtering, see the [Filtering documentation](/insight/webhooks/filtering).
-
-### Payload
-
-The webhook payload contains the event or transaction data. Your agent will need to parse this payload to extract the relevant information. See the [Payload documentation](/insight/webhooks/payload) for details on the payload structure.
-
-## API Reference
-
-### Events API
-
-1. **Get All Events**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/events
-```
-
-or
-
-```typescript
-GET https://insight.thirdweb.com/v1/events?chainId={{chainId1}}&chainId={{chainId2}}
-```
-
-2. **Get Contract Events**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/events/:contractAddress
-```
-
-3. **Get Specific Event Type**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/events/:contractAddress/:signature
-```
-
-### Transactions API
-
-1. **Get All Transactions**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/transactions
-```
-
-2. **Get Contract Transactions**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/transactions/:contractAddress
-```
-
-3. **Get Specific Transaction Type**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/transactions/:contractAddress/:signature
-```
-
-### Token Balance API
-
-1. **ERC20 Balances**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc20/:ownerAddress
-
-interface ERC20Response {
- data: ERC20Balance[];
-}
-
-interface ERC20Balance {
- tokenAddress: string;
- balance: string;
-}
-```
-
-2. **ERC721 & ERC1155 Balances**
-
-```typescript
-GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc721/:ownerAddress
-GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc1155/:ownerAddress
-
-interface TokenBalance {
- data: NFTBalance[];
-}
-
-interface NFTBalance {
- collectionAddress: string;
- tokenId: string;
- balance: string;
-}
-```
-
-## Query Parameters
-
-### Common Parameters
-
-```typescript
-interface CommonQueryParams {
- page?: number; // Default: 0
- limit?: number; // Default: 20, must be > 0
- sort_by?: "block_number" | "block_timestamp" | "transaction_index";
- sort_order?: "asc" | "desc";
- group_by?: string;
- aggregate?: string[];
-}
-```
-
-### Filter Types
-
-1. **Block Filters**
-
-```typescript
-interface BlockFilters {
- filter_block_number?: number; // Example: 1000000
- filter_block_number_gte?: number; // Example: 1000000
- filter_block_number_gt?: number; // Example: 1000000
- filter_block_number_lte?: number; // Example: 1000000
- filter_block_number_lt?: number; // Example: 1000000
- filter_block_hash?: string; // Example: "0x3a1fba5..."
-}
-```
-
-2. **Time Filters**
-
-```typescript
-interface TimeFilters {
- filter_block_timestamp?: number; // Example: 1715222400
- filter_block_timestamp_gte?: number; // Example: 1715222400
- filter_block_timestamp_gt?: number; // Example: 1715222400
- filter_block_timestamp_lte?: number; // Example: 1715222400
- filter_block_timestamp_lt?: number; // Example: 1715222400
-}
-```
-
-3. **Transaction Filters**
-
-```typescript
-interface TransactionFilters {
- filter_transaction_index?: number;
- filter_transaction_hash?: string;
- filter_from_address?: string;
- filter_value?: number;
- filter_gas_price?: number;
- filter_gas?: number;
- // Additional gte, gt, lte, lt variants for numeric fields
-}
-```
-
-## Error Handling
-
-All endpoints return standard error responses for 400 and 500 status codes:
-
-```typescript
-// 400 Bad Request
-// 500 Internal Server Error
-interface ErrorResponse {
- error: string; // Required
-}
-```
diff --git a/apps/portal/src/app/insight/agents-and-llms/page.mdx b/apps/portal/src/app/insight/agents-and-llms/page.mdx
deleted file mode 100644
index 3871cd2a772..00000000000
--- a/apps/portal/src/app/insight/agents-and-llms/page.mdx
+++ /dev/null
@@ -1,531 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "thirdweb Insight For Agents & LLMs",
- description:
- "thirdweb Insight query documentation formatted for use with LLMs and agents",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# For Agents & LLMs
-
-
-Insight is a powerful tool that can be used to power AI agents and LLMs with blockchain data. To use the API in your AI agent you can use the llms.txt file bellow.
-
-
-- [llms.txt file](/insight/agents-and-llms/llmstxt)
-- For developers who prefer working with OpenAPI specifications, our complete API documentation is available in OpenAPI format [here](https://insight.thirdweb.com/openapi.json).
-
-If you prefer to use the API in an LLM prompt, the schema below can be copied and pasted into the AI assistant of your choice. Feed this to your assistant, then ask your assistant to construct Insight queries on your behalf, asking it for certain onchain information.
-
-````markdown
-# ATTENTION LLMs - API Usage Instructions
-
-## API URL
-
-```typescript
-const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;
-```
-
-## Authentication
-
-The API supports three authentication methods:
-
-```typescript
-// 1. Header Authentication
-const headers = {
- "x-client-id": "{{clientId}}", // thirdweb Client ID
-};
-
-// 2. Query Parameter
-const url = "https://{{chainId}}.insight.thirdweb.com/v1/events?clientId={{clientId}}";
-
-// 3. Bearer Token
-const headers = {
- Authorization: "Bearer {{jwtToken}}",
-};
-
-// Example using fetch with header auth
-async function getEvents() {
- const response = await fetch("https://{{chainId}}.insight.thirdweb.com/v1/events", {
- headers: {
- "x-client-id": "{{clientId}}",
- },
- });
- return await response.json();
-}
-```
-
-## Core Concepts
-
-### Chain IDs
-
-- As a subdomain:
-```typescript
-// Example
-const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;
-```
-
-- As a query parameter (this is useful if you want to query multiple chains):
-```typescript
-// Example for a single chain
-const url = `https://insight.thirdweb.com/v1/events?chain={{chainId}}`;
-// Example for multiple chains
-const url = `https://insight.thirdweb.com/v1/events?chain=1&chain=137`;
-```
-
-We won't duplicate multichain examples for each endpoint, but you can pass multiple chains in the query parameters pretty much everywhere!
-
-### Base Response Structure
-
-```typescript
-interface BaseResponse {
- data: T[];
- meta: {
- chain_id: number; // Required
- page: number; // Required
- limit: number; // Required
- total_items: number; // Required
- total_pages: number; // Required
- address?: string; // Optional
- signature?: string; // Optional
- }
-}
-
-// Example response from getting events
-{
- "data": [
- {
- "chain_id": 1,
- "block_number": "{{blockNumber}}",
- "transaction_hash": "{{transactionHash}}",
- "address": "{{contractAddress}}",
- "data": "{{data}}",
- "topics": ["{{topic}}"]
- }
- ],
- "meta": {
- "chain_id": 1,
- "page": 0,
- "limit": 20,
- "total_items": 150,
- "total_pages": 8
- }
-}
-```
-
-## API Examples
-
-### Events API
-
-```typescript
-// 1. Get All Events
-async function getAllEvents() {
- const response = await fetch("https://{{chainId}}.insight.thirdweb.com/v1/events", {
- headers: { "x-client-id": "{{clientId}}" },
- });
- return await response.json();
-}
-
-// 2. Get Contract Events with Filtering
-async function getContractEvents(contractAddress: string) {
- const params = new URLSearchParams({
- filter_block_number_gte: blockNumber,
- sort_by: "block_timestamp",
- sort_order: "desc",
- limit: "{{limit}}",
- });
-
- const url = `https://{{chainId}}.insight.thirdweb.com/v1/events/{{contractAddress}}?${params}`;
- const response = await fetch(url, {
- headers: { "x-client-id": "{{clientId}}" },
- });
- return await response.json();
-}
-```
-
-### Token Balance API
-
-```typescript
-// 1. Get ERC20 Balances
-async function getERC20Balances(ownerAddress: string) {
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc20/${ownerAddress}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- const data = await response.json();
- // Example response:
- // {
- // "data": [
- // {
- // "tokenAddress": "0x123...",
- // "balance": "1000000000000000000"
- // }
- // ]
- // }
- return data;
-}
-
-// 2. Get NFT Balances
-async function getNFTBalances(ownerAddress: string) {
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc721/${ownerAddress}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- const data = await response.json();
- // Example response:
- // {
- // "data": [
- // {
- // "collectionAddress": "0x456...",
- // "tokenId": "1",
- // "balance": "1"
- // }
- // ]
- // }
- return data;
-}
-```
-
-### Aggregations
-
-Insight supports powerful aggregation functions that can be used to analyze blockchain data. Here's how to use them:
-
-```typescript
-// Basic aggregation structure
-const response = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/endpoint?aggregate=function(field) AS alias',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-
-// Multiple aggregations in one request
-const response = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/endpoint?aggregate=count() AS total&aggregate=sum(value) AS total_value',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-
-// With filters
-const response = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/transactions?aggregate=count() AS tx_count&filter_timestamp_gte=2024-01-01',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-```
-
-#### Aggregation Presets available in the playground as examples
-
-1. **Default Aggregations**
- - `count() AS count_all` - Count all items
- - `sum(gas_used) AS total_gas_used` - Total gas used
- - `avg(gas_used) AS avg_gas_used` - Average gas used
- - `min(gas_used) AS min_gas_used` - Minimum gas used
- - `max(gas_used) AS max_gas_used` - Maximum gas used
- - `countDistinct(column_name) AS unique_count` - Count distinct values
-
-2. **Events Specific**
- - `count() AS event_count` - Count events
- - `countDistinct(address) AS unique_addresses` - Unique addresses
- - `min(block_number) AS min_block` - Minimum block number
- - `max(block_number) AS max_block` - Maximum block number
-
-3. **Transactions Specific**
- - `count() AS transaction_count` - Count transactions
- - `sum(value) AS total_value_wei` - Total value transferred
- - `sum(gas_used) AS total_gas_used` - Total gas used
- - `avg(value) AS avg_value_wei` - Average value
- - `avg(gas_used) AS avg_gas_used` - Average gas used
- - `countDistinct(from_address) AS unique_senders` - Unique senders
- - `countDistinct(to_address) AS unique_receivers` - Unique receivers
-
-4. **Wallet Transactions**
- - `count() AS transaction_count` - Transaction count
- - `sum(value) AS total_value_wei` - Total value
- - `avg(value) AS avg_value_wei` - Average value
- - `sum(gas_used * gas_price) AS total_fees_wei` - Total fees
-
-5. **Blocks Specific**
- - `sum(transaction_count) AS total_transactions` - Total transactions
- - `avg(transaction_count) AS avg_transactions_per_block` - Avg tx/block
- - `sum(gas_used) AS total_gas_used` - Total gas used
- - `min(number) AS min_block_number` - Min block number
- - `max(number) AS max_block_number` - Max block number
-
-#### Common Aggregation Examples
-
-```typescript
-// 1. Get transaction statistics
-const txStats = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&aggregate=avg(gas_used) AS avg_gas_used',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-
-// 2. Get wallet transaction stats
-const walletStats = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&aggregate=sum(gas_used * gas_price) AS total_fees_wei',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-```
-
-#### Filtering with Aggregations
-
-```typescript
-// Get transaction stats for a specific time period
-const txStats = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&filter_timestamp_gte=2024-01-01&filter_timestamp_lte=2024-01-31',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-
-// Get block metrics for recent blocks
-const blockStats = await fetch(
- 'https://{{chainId}}.insight.thirdweb.com/v1/blocks?aggregate=sum(transaction_count) AS total_transactions&aggregate=avg(transaction_count) AS avg_transactions_per_block&filter_number_gte=18000000',
- { headers: { 'x-client-id': '{{clientId}}' } }
-);
-```
-
-### Using Filters
-
-```typescript
-// Example: Get events with complex filtering
-async function getFilteredEvents() {
- const params = new URLSearchParams({
- // Block filters
- filter_block_number_gte: blockNumberStart,
- filter_block_number_lte: blockNumberEnd,
-
- // Time filters
- filter_block_timestamp_gte: "{{timestamp}}",
-
- // Transaction filters
- filter_from_address: "{{fromAddress}}",
- filter_value_gte: "{{value}}", // 1 ETH
-
- // Pagination
- page: "{{page}}",
- limit: "{{limit}}",
-
- // Sorting
- sort_by: "{{sortBy}}",
- sort_order: "{{sortOrder}}",
- });
-
- const response = await fetch(
- `https://{{chainId}}.insight.thirdweb.com/v1/events?${params}`,
- { headers: { "x-client-id": "{{clientId}}" } },
- );
- return await response.json();
-}
-```
-
-### Error Handling
-
-```typescript
-async function safeApiCall() {
- try {
- const response = await fetch("https://{{chainId}}.insight.thirdweb.com/v1/events", {
- headers: { "x-client-id": "{{clientId}}" },
- });
-
- if (!response.ok) {
- const errorData = await response.json();
- // Example error response:
- // { "error": "Invalid client ID" }
- throw new Error(errorData.error);
- }
-
- return await response.json();
- } catch (error) {
- console.error("API Error:", error.message);
- throw error;
- }
-}
-```
-
-## Webhooks
-
-Webhooks are a powerful tool for building event-driven AI agents that can react to on-chain activity in real-time. By subscribing to specific blockchain events or transactions, your agent can receive notifications and trigger automated workflows.
-
-### Use Cases for AI Agents
-
-- **Real-time Monitoring**: An agent can monitor for specific events (e.g., a large transfer to a whale wallet) and trigger alerts or other actions.
-- **Automated Workflows**: When a specific on-chain action occurs (e.g., a new NFT is minted), an agent can automatically kick off a downstream process, like updating a database or sending a notification.
-- **Data Aggregation**: Use webhooks to feed on-chain data into a vector database or other data store for later analysis by an LLM.
-
-### Getting Started with Webhooks
-
-To get started, you can create and manage webhooks through the Insight API. For detailed instructions, refer to the [Managing Webhooks documentation](/insight/webhooks/managing-webhooks).
-
-### Filtering Events
-
-Insight's webhooks feature a powerful filtering system that lets you subscribe to only the events and transactions you care about. For example, you can create a single webhook that notifies your agent of both ERC-20 and ERC-721 `Transfer` events by providing multiple ABIs in the filter.
-
-```typescript
-{
- "v1.events": {
- "chain_ids": ["1"],
- "signatures": [
- {
- "sig_hash": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "abi": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"
- }
- ]
- }
-}
-```
-
-For more advanced filtering options, see the [Filtering documentation](/insight/webhooks/filtering).
-
-### Understanding the Payload
-
-When a webhook is triggered, it sends a payload to your specified endpoint. This payload contains the event or transaction data that your agent will need to process. To learn more about the structure of this payload, see the [Payload documentation](/insight/webhooks/payload).
-
-## API Reference
-
-### Events API
-
-1. **Get All Events**
-
-```typescript
-GET /v1/events
-
-interface EventsResponse {
- data: Event[];
- meta: MetaData;
-}
-```
-
-2. **Get Contract Events**
-
-```typescript
-GET /v1/events/:contractAddress
-```
-
-3. **Get Specific Event Type**
-
-```typescript
-GET /v1/events/:contractAddress/:signature
-```
-
-### Transactions API
-
-1. **Get All Transactions**
-
-```typescript
-GET /v1/transactions
-```
-
-2. **Get Contract Transactions**
-
-```typescript
-GET /v1/transactions/:contractAddress
-```
-
-3. **Get Specific Transaction Type**
-
-```typescript
-GET /v1/transactions/:contractAddress/:signature
-```
-
-### Token Balance API
-
-1. **ERC20 Balances**
-
-```typescript
-GET /v1/tokens/erc20/:ownerAddress
-
-interface ERC20Response {
- data: {
- tokenAddress: string; // Required
- balance: string; // Required
- }[];
-}
-```
-
-2. **ERC721 & ERC1155 Balances**
-
-```typescript
-GET /v1/tokens/erc721/:ownerAddress
-GET /v1/tokens/erc1155/:ownerAddress
-
-interface TokenBalanceResponse {
- data: {
- collectionAddress: string; // Required
- tokenId: string; // Required
- balance: string; // Required
- }[];
-}
-```
-
-## Query Parameters
-
-### Common Parameters
-
-```typescript
-interface CommonQueryParams {
- page?: number; // Default: 0
- limit?: number; // Default: 20, must be > 0
- sort_by?: "block_number" | "block_timestamp" | "transaction_index";
- sort_order?: "asc" | "desc";
- group_by?: string; // Group results by a specific field
- aggregate?: string[]; // Apply aggregate functions (count, sum, avg, etc.) to grouped results
-}
-```
-
-### Filter Types
-
-1. **Block Filters**
-
-```typescript
-interface BlockFilters {
- filter_block_number?: number; // Example: 1000000
- filter_block_number_gte?: number; // Example: 1000000
- filter_block_number_gt?: number; // Example: 1000000
- filter_block_number_lte?: number; // Example: 1000000
- filter_block_number_lt?: number; // Example: 1000000
- filter_block_hash?: string; // Example: "0x3a1fba5..."
-}
-```
-
-2. **Time Filters**
-
-```typescript
-interface TimeFilters {
- filter_block_timestamp?: number; // Example: 1715222400
- filter_block_timestamp_gte?: number; // Example: 1715222400
- filter_block_timestamp_gt?: number; // Example: 1715222400
- filter_block_timestamp_lte?: number; // Example: 1715222400
- filter_block_timestamp_lt?: number; // Example: 1715222400
-}
-```
-
-3. **Transaction Filters**
-
-```typescript
-interface TransactionFilters {
- filter_transaction_index?: number;
- filter_transaction_hash?: string;
- filter_from_address?: string;
- filter_value?: string; // Value in wei (e.g., "1000000000000000000" for 1 ETH)
- filter_value_gte?: string;
- filter_value_gt?: string;
- filter_value_lte?: string;
- filter_value_lt?: string;
- filter_gas_price?: number;
- filter_gas?: number;
- // Additional gte, gt, lte, lt variants for numeric fields
-}
-```
-
-## Error Handling
-
-All endpoints return standard error responses for 400 and 500 status codes:
-
-```typescript
-// 400 Bad Request
-// 500 Internal Server Error
-interface ErrorResponse {
- error: string; // Required
-}
-```
-````
\ No newline at end of file
diff --git a/apps/portal/src/app/insight/blueprints/page.mdx b/apps/portal/src/app/insight/blueprints/page.mdx
deleted file mode 100644
index 7da1a1f0f92..00000000000
--- a/apps/portal/src/app/insight/blueprints/page.mdx
+++ /dev/null
@@ -1,223 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Insight Blueprints | thirdweb Infrastructure",
- description:
- "Learn what are Insight Blueprints and how to use them",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Blueprints
-
-A blueprint is an API that provides access to on-chain data in a user-friendly format. There's no need for ABIs, decoding, RPC, or web3 knowledge to fetch blockchain data. Every chain exposes the default blueprints below
-
-All blueprints support [multichain queries](/insight/multichain-queries)!
-
-## Events Blueprint
-
-Blockchain events offers developers a powerful way to track and analyze blockchain events emitted by smart contracts. This endpoint provides access to detailed event information, such as the address of the contract that generated the event, the transaction that triggered it, and when and where the event occurred on the blockchain. By offering data points like event topics, block numbers, and transaction hashes, developers can easily filter and search for specific event types, such as token transfers or contract executions. With precise timestamps and block references, the Events Blueprint ensures that developers have real-time access to critical on-chain activity, enabling them to build responsive, high-performance applications that can monitor, analyze, and react to blockchain events seamlessly. Whether working on DeFi, NFTs, or general dApps, this endpoint helps unlock the full potential of blockchain data in any project.
-
-### Blueprint details
-
-| Name | Description | Example |
-| ----------- | ----------- | ----------- |
-| Address | The `address` is the identifier of the smart contract or account that emitted the event. It tells you who or what generated the event. | If the event is related to an ERC-20 token transfer, the address would be the smart contract address of the token. For instance, if you're tracking events for the USDT token, the address would be the contract address of USDT on Ethereum. |
-| Chain ID | The `chain_id` is a unique identifier for the blockchain network where the event occurred. Different blockchain networks (e.g., Ethereum, Binance Smart Chain, Polygon) have their own unique chain IDs. | Ethereum's mainnet has a chain_id of 1, while Binance Smart Chain has a chain_id of 56. This field ensures you know which network the event is coming from, which is crucial when interacting with multiple EVM chains.
-| Data | The `data` field contains additional information specific to the event. In many cases, it's the raw output of the smart contract event. | In an ERC-20 Transfer event, the data might include the number of tokens transferred in raw hexadecimal format. For instance, if 1000 USDT were transferred, this value would be encoded in the event's data field.
-| Log Index | The `log_index` is the order of the log (event) in the list of all events within the block. It helps you pinpoint exactly where this event is located in the block. | If multiple events occurred within the same block (e.g., multiple token transfers), the log_index tells you the sequence of this particular event. For example, it might be the 3rd event in the block.
-| Topics | The `topics` array contains indexed parameters of the event, often used for filtering or categorizing events. The first topic contains the event signature (the function name), while the remaining topics contain indexed event arguments. | In an ERC-20 Transfer event, the first topic would be the hash of the event signature `Transfer(address,address,uint256)`. The second topic would be the sender's address, and the third would be the receiver's address. This allows filtering to track all Transfer events for a specific address.
-| Transaction Hash | The `transaction_hash` is the unique identifier for the transaction that triggered the event. It helps you link the event to the specific transaction that caused it. | If you transfer 1 ETH to another wallet, the transaction hash might be 0x5c7b6f... which uniquely identifies that transaction. Using this hash, you can look up the transaction in any block explorer (e.g., Etherscan) to see all the details.
-| Transaction Index | The `transaction_index` tells you the position of the transaction within the block. This helps you identify where in the block this particular transaction was placed relative to others. | If multiple transactions occurred within the same block (e.g., multiple token transfers), the transaction_index tells you the sequence of this particular transaction. For example, it might be the 3rd transaction in the block. | If a block contains 100 transactions, the transaction_index might indicate that this event was triggered by the 45th transaction in the block. This is useful for debugging or tracing the order of execution.
-| Block Hash | A `block_hash` is the unique identifier of a block, generated after the block is confirmed. It's like a tamper-proof record of all the transactions and events in that block. | If you wanted to verify that a particular transaction or event was part of a block, you could use the block hash to check its integrity. Think of it as a digital signature for the entire block, such as 0x91d... representing all transactions within that specific block.
-| Block Number | The `block_number` indicates the position of the block in the blockchain. It tells you when (in terms of blockchain sequence) the event occurred. | Block number 12,345,678 on Ethereum might contain transactions from a particular moment, such as the transfer of 10 ETH between two accounts. You can think of block numbers like page numbers in a ledger.
-| Block Timestamp | The `block_timestamp` is the exact time when the block was mined and added to the blockchain. | If block 12,345,678 was mined on July 1, 2023, at 12:30 PM UTC, the timestamp will reflect this exact moment. This helps you pinpoint when an event, such as a token transfer, actually happened in real time.
-
-### Aggregations Examples
-
-#### Get Event Statistics
-```typescript
-// Get total event count and unique addresses
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/events?aggregate=count() AS event_count&aggregate=countDistinct(address) AS unique_addresses'
-);
-```
-
-#### Track Collection Activity
-```typescript
-// Get min/max block numbers and unique topics
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/events?aggregate=min(block_number) AS min_block&aggregate=max(block_number) AS max_block&aggregate=countDistinct(topic0) AS unique_topics'
-);
-```
-
-#### Custom Aggregations
-```typescript
-// Custom aggregations for specific analysis
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/events?aggregate=count() AS transfers&aggregate=countDistinct(from_address) AS unique_senders&aggregate=countDistinct(to_address) AS unique_recipients'
-);
-```
-
-## Transactions Blueprint
-
-Transaction data equips developers with the tools they need to interact with blockchain data efficiently and effectively. By providing clear, actionable insights into each transaction, the API helps streamline tasks like monitoring smart contract interactions, tracking asset transfers, and debugging. Developers can rely on this endpoint to access essential transaction details, enabling faster troubleshooting and more informed decision-making. Whether building DeFi platforms, dApps, or blockchain-based analytics tools, transaction data is the essence for all interactions with any chains.
-
-### Blueprint details
-
-| Name | Description | Example |
-| ----------- | ----------- | ----------- |
-| From Address | This is the address that initiated the transaction. It represents the sender who paid for the gas to execute the transaction. | If a user sends 1 ETH from their wallet, the `from_address` will be the sender's Ethereum address, such as `0xabc123...`.
-| To Address | This is the recipient of the transaction. It could be another wallet or a smart contract. | If sending ETH to a friend, their wallet address, like `0xdef456...`, would be the `to_address`. In the case of interacting with a DeFi platform, the address of the smart contract being called would be the `to_address`.
-| Hash | The unique identifier (hash) of the transaction. This hash can be used to look up and verify the transaction on the blockchain. | A transaction might have a hash like `0x5c7b6f...`. You can use this hash to check the transaction status on a block explorer like Etherscan.
-| Value | This is the amount of cryptocurrency (in wei) being transferred in the transaction. | If transferring 1 ETH, the `value` would be 1,000,000,000,000,000,000 wei (1 ETH = 10^18 wei).
-| Gas | This is the maximum amount of gas units the sender is willing to pay for the transaction to be processed. It limits how much work the transaction can perform on the blockchain. | A simple ETH transfer might require 21,000 gas, while calling a complex smart contract function could require significantly more, such as 100,000 gas.
-| Gas Price | The price per gas unit the sender is willing to pay, expressed in wei (the smallest unit of ETH). The total transaction cost is calculated as `gas` * `gas_price`. | If the `gas_price` is 100 gwei (1 gwei = 1 billion wei), the sender will pay `100 gwei * 21,000 gas` for a basic ETH transfer.
-| Max Fee Per Gas | This is the maximum amount of gas fees (in wei) the sender is willing to pay for each gas unit. It was introduced in EIP-1559 to provide a cap on gas costs. | If `max_fee_per_gas` is set to 200 gwei, the sender is ensuring that they will never pay more than this for each gas unit, even during periods of high network congestion.
-| Max Priority Fee Per Gas | This is the maximum additional fee the sender is willing to pay to incentivize miners to prioritize their transaction. Also introduced in EIP-1559. | A transaction might specify a `max_priority_fee_per_gas` of 2 gwei, which acts as a "tip" for miners to get their transaction included faster in a block.
-| Data | The `data` field contains additional information required by a transaction, such as the input parameters for interacting with a smart contract. | In a call to a DeFi contract's `swap` function, the `data` field will include the encoded function call and arguments (e.g., token amount, recipient address).
-| Nonce | The `nonce` is the number of transactions sent from the sender's address. It ensures that transactions are processed in the correct order and prevents double-spending. | If the sender has sent 5 transactions before, the nonce will be 5. This helps in tracking the sequence of transactions and ensuring that each one is processed correctly. | If the `nonce` is 12, it means this is the 13th transaction (starting from 0) sent from the `from_address`
-| Transaction Index | The position of the transaction within the block. It indicates the order in which the transaction was included relative to other transactions | If the `transaction_index` is 5, this was the 6th transaction included in the block.
-| Transaction Type | The type of transaction, typically either legacy (type `0x0` ) or one of the newer types introduced in EIP-1559 (e.g., type `0x2` for transactions that use the new gas fee mechanism). | A `transaction_type` of `0x2` indicates the transaction follows the new EIP-1559 rules for gas fees.
-| Access List | The `access_list` is an optional field introduced in EIP-2930 that specifies which addresses and storage slots the transaction intends to interact with. It's used to optimize gas costs by pre-declaring the data access needed. | When a transaction interacts with a smart contract, the `access_list` may declare the contract address and storage slots the transaction intends to read from or write to. For example, interacting with a DeFi smart contract could include its contract address and the storage slots holding user balances.
-| Chain ID | The `chain_id` identifies the blockchain network on which the transaction was conducted. It prevents replay attacks across different networks. | On Ethereum mainnet, the chain ID is `1`, while on Base Mainnet, the chain ID is `8453` . This field tells you which network the transaction belongs to.
-| Block Hash | This is the unique identifier (or "fingerprint") of the block that includes this transaction. The hash ensures that the block hasn't been altered. | If the transaction is included in block `12,345,678`, the block's hash might look like `0xabc123...`, and this hash can be used to reference that particular block on the blockchain.
-| Block Number | The `block_number` indicates the specific position of the block in the blockchain that contains the transaction. | If a transaction is included in block `12,345,678`, this number can be used to quickly locate the block and all the transactions it contains.
-| Block Timestamp | This is the exact time when the block containing the transaction was mined and added to the blockchain. | If the transaction was confirmed on July 1, 2023, at 12:30 PM UTC, the block timestamp will reflect this moment. It's useful for analyzing when specific activities (like token transfers) occurred.
-| r, s, v | These are the cryptographic components of the transaction signature. They prove that the transaction was signed by the private key associated with the sender's address. | The `r`, `s`, and `v` values are produced during the signing process and are necessary to verify the authenticity of the transaction on the blockchain.
-
-### Aggregations Examples
-
-#### Get Transaction Statistics
-```typescript
-// Get total transaction count and total value transferred
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value'
-);
-```
-
-#### Analyze Gas Usage
-```typescript
-// Get average and max gas used
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/transactions?aggregate=avg(gas_used) AS avg_gas&aggregate=max(gas_used) AS max_gas'
-);
-```
-
-## Wallet Transactions Blueprint
-
-The Wallet Transactions Blueprint provides detailed transaction history for specific wallet addresses, making it easy to track all activities associated with a particular address.
-
-### Aggregation Examples
-
-#### Get Wallet Summary
-```typescript
-// Get total transaction count and total value for a wallet
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value'
-);
-```
-
-#### Calculate Total Fees Paid
-```typescript
-// Calculate total fees paid by a wallet
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=sum(gas_used * gas_price) AS total_fees'
-);
-```
-
-## Blocks Blueprint
-
-The Blocks Blueprint provides access to blockchain block data, including block details, transaction counts, and gas usage statistics.
-
-### Aggregation Examples
-
-#### Get Block Statistics
-```typescript
-// Get total block count and total transactions
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/blocks?aggregate=count() AS block_count&aggregate=sum(transaction_count) AS total_transactions'
-);
-```
-
-#### Analyze Block Metrics
-```typescript
-// Get average transactions per block and total gas used
-const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/blocks?aggregate=avg(transaction_count) AS avg_transactions&aggregate=sum(gas_used) AS total_gas_used'
-);
-```
-
-## Tokens Blueprint
-
-Tokens on blockchain can be of different standards, but ones of the most widely used ones are:
-- ERC-20 for fungible tokens
-- ERC-721 and ERC-1155 for NFTs
-
-This blueprint provides access to such tokens' balances information for a given owner address.
-
-### Blueprint details
-
-#### ERC-20 balances of an address
-
-```yaml
-GET /v1/{clientId}/tokens/erc20/:ownerAddress
-```
-
-Path Parameters:
-- `ownerAddress` *(required)*: The address of the owner of the tokens.
-- `clientId` *(required)*: The thirdweb client ID of your project.
-
-Successful response schema:
-```json
-[
- {
- "tokenAddress": "…",
- "balance": "…"
- }
-]
-```
-
-#### ERC-721 tokens of an address
-
-```yaml
-GET /v1/{clientId}/tokens/erc721/:ownerAddress
-```
-
-Path Parameters:
-- `ownerAddress` *(required)*: The address of the owner of the tokens.
-- `clientId` *(required)*: The thirdweb client ID of your project.
-
-Successful response schema:
-```json
-[
- {
- "collectionAddress": "…",
- "tokenId": "…",
- "balance": "…"
- }
-]
-```
-
-#### ERC-1155 tokens of an address
-
-```yaml
-GET /v1/{clientId}/tokens/erc1155/:ownerAddress
-```
-
-Path Parameters:
-- `ownerAddress` *(required)*: The address of the owner of the tokens.
-- `clientId` *(required)*: The thirdweb client ID of your project.
-
-Successful response schema:
-```json
-[
- {
- "collectionAddress": "…",
- "tokenId": "…",
- "balance": "…"
- }
-]
-```
diff --git a/apps/portal/src/app/insight/faqs/page.mdx b/apps/portal/src/app/insight/faqs/page.mdx
deleted file mode 100644
index bb785becee4..00000000000
--- a/apps/portal/src/app/insight/faqs/page.mdx
+++ /dev/null
@@ -1,30 +0,0 @@
-# Insight FAQs
-
-## Aggregation Queries
-
-### How do I use aggregations in my queries?
-You can include aggregation functions directly in your API requests. Here's an example:
-```typescript
-// Get total transaction value and average gas used
-const response = await fetch(
- 'https://10.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&aggregate=avg(gas_used) AS avg_gas_used'
-);
-```
-
-### Where can I find examples of using aggregations?
-You can find working examples and experiment with different aggregation presets in the Insight Playground. The Playground provides a user-friendly interface to build and test your aggregation queries.
-
-### What are some common use cases for aggregations?
-- Calculating total trading volume
-- Finding average transaction values
-- Counting unique users/wallets
-- Analyzing gas usage patterns
-- Tracking NFT collection statistics
-
-### Can I create custom aggregations?
-Yes, you can create custom aggregations using standard SQL aggregation functions like `count()`, `sum()`, `avg()`, `min()`, `max()`, and `countDistinct()`. The presets are just convenient shortcuts for common operations.
-
-### Where can I learn more about available presets?
-You can find the complete list of available aggregation presets in the Insight Playground, where you can also test them with real blockchain data.
-
-More information coming soon.
\ No newline at end of file
diff --git a/apps/portal/src/app/insight/get-started/page.mdx b/apps/portal/src/app/insight/get-started/page.mdx
deleted file mode 100644
index 17451f66b78..00000000000
--- a/apps/portal/src/app/insight/get-started/page.mdx
+++ /dev/null
@@ -1,251 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Getting started with Insight | thirdweb Infrastructure",
- description:
- "Learn how to use thirdweb Insight to query blockchain events",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Get Started
-
-In this guide we will learn how to use the events blueprint in insight.
-
-## Pre-requisites
-
-- [Create a project](https://thirdweb.com/team) and navigate to the project settings to get a client ID
-- Use insight API with the base URL below.
-- To authenticate use your client ID in the `x-client-id` header or `clientId` query parameter
-
-```
-https://.insight.thirdweb.com
-```
-
-## Basic Usage
-```typescript
-const getUsdtTransfers = async () => {
- try {
- const response = await fetch('https://1.insight.thirdweb.com/v1/events/0xdAC17F958D2ee523a2206206994597C13D831ec7/Transfer(address,address,uint256)?limit=5', {
- headers: {
- 'x-client-id':
- }
- });
- const transfersInfo = await response.json();
- return transfersInfo
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-Once you execute the query above you will receive a result similar to this:
-
-```json
-{
- "meta": {
- "chain_id": 1,
- "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
- "signature": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "page": 0,
- "limit": 5,
- "total_items": 5,
- "total_pages": 0
- },
- "data": [
- {
- "chain_id": 1,
- "block_number": 14705663,
- "block_hash": "0x8f7014ff29e3ea83ee03354bd968741d01b92d4c3ddf02bfa5121465b8240736",
- "block_timestamp": 1651594686,
- "transaction_hash": "0xf5009000b57b761900010bf7f365c12ce34438ac3afdef9778b46055c26353b3",
- "transaction_index": 193,
- "log_index": 278,
- "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
- "data": "0x0000000000000000000000000000000000000000000000000000000005f5e100",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x000000000000000000000000b8418cdb539069e075b4c6c6675114879ffd441b",
- "0x000000000000000000000000515ea78a0ff34aef46a5e323d759935e05de4827"
- ]
- },
- {
- "chain_id": 1,
- "block_number": 14705664,
- "block_hash": "0x916d67589f2bc37600faf055309fd9f654d0c0030df35d31c04e22fef8d24ff2",
- "block_timestamp": 1651594701,
- "transaction_hash": "0x0999f86751fe5b8f2bc5446e38abf3f0e01ee1c7ff5ce6288abbea506ac3cebf",
- "transaction_index": 41,
- "log_index": 120,
- "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
- "data": "0x0000000000000000000000000000000000000000000000000000000014dc9380",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000005041ed759dd4afc3a72b8192c143f72f4724081a",
- "0x0000000000000000000000000f69fce36dc680512d836526fc1abb9cd6bdcdd4"
- ]
- },
- {
- "chain_id": 1,
- "block_number": 14705664,
- "block_hash": "0x916d67589f2bc37600faf055309fd9f654d0c0030df35d31c04e22fef8d24ff2",
- "block_timestamp": 1651594701,
- "transaction_hash": "0x0f25b357155dca3186700e69a7586ee0153f1d7d75304a158aab9be210b31a56",
- "transaction_index": 72,
- "log_index": 133,
- "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
- "data": "0x0000000000000000000000000000000000000000000000000000000643e6c140",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000007b29bee9cb744122edcd7e8223efcdf8d8d8e0a4",
- "0x0000000000000000000000001724aabcef350d3f3433804e6167d4c4137aab01"
- ]
- },
- {
- "chain_id": 1,
- "block_number": 14705664,
- "block_hash": "0x916d67589f2bc37600faf055309fd9f654d0c0030df35d31c04e22fef8d24ff2",
- "block_timestamp": 1651594701,
- "transaction_hash": "0x10da03bea7828722c92c86704522c7e1ce7dd2947d633ec6c1fb36680cb256e5",
- "transaction_index": 145,
- "log_index": 229,
- "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
- "data": "0x00000000000000000000000000000000000000000000000000000000163d3a0d",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x00000000000000000000000056eddb7aa87536c09ccc2793473599fd21a8b17f",
- "0x0000000000000000000000002b38e18192a442ed923addb4739e0a7724945d3c"
- ]
- },
- {
- "chain_id": 1,
- "block_number": 14705664,
- "block_hash": "0x916d67589f2bc37600faf055309fd9f654d0c0030df35d31c04e22fef8d24ff2",
- "block_timestamp": 1651594701,
- "transaction_hash": "0x20967f489b5237c0c6ffcbf7afcd921303e0db9e49382f9dc37809874e674b8b",
- "transaction_index": 188,
- "log_index": 295,
- "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
- "data": "0x0000000000000000000000000000000000000000000000000000000011b9e2b6",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000003cd751e6b0078be393132286c442345e5dc49699",
- "0x0000000000000000000000000e6eeff72188094c78b2478b693bbdbf9b13aaac"
- ]
- }
- ]
-}
-```
-
-## Using Aggregations
-
-Insight provides several predefined aggregation presets that make it easy to analyze your blockchain data. These presets are available in the Insight Playground, where you can experiment with them using a user-friendly interface.
-
-### Example: Get Transaction Statistics
-
-```typescript
-const getTransactionStats = async () => {
- try {
- const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value&aggregate=avg(gas_used) AS avg_gas',
- {
- headers: {
- 'x-client-id': ''
- }
- }
- );
- const stats = await response.json();
- return stats;
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-### Example: Get Block Metrics
-
-```typescript
-const getBlockMetrics = async () => {
- try {
- const response = await fetch(
- 'https://1.insight.thirdweb.com/v1/blocks?aggregate=count() AS block_count&aggregate=sum(transaction_count) AS total_transactions&aggregate=avg(transaction_count) AS avg_transactions',
- {
- headers: {
- 'x-client-id': ''
- }
- }
- );
- const metrics = await response.json();
- return metrics;
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-### Explore in the Playground
-
-For a more interactive experience, try out the aggregation presets in the Insight Playground. The Playground allows you to:
-- Browse available presets for each endpoint
-- See real-time results
-- Generate code snippets for your application
-- Test different aggregation combinations
-
-## Multichain Queries
-
-Insight also supports querying multiple chains in a single API call. This is useful when you need to retrieve data across different networks without making separate requests.
-
-```typescript
-const getMultichainTransfers = async () => {
- try {
- // Query USDT transfers on Ethereum (1) and Polygon (137)
- const response = await fetch('https://insight.thirdweb.com/v1/events?chain=1&chain=137&limit=10', {
- headers: {
- 'x-client-id':
- }
- });
- const transfersInfo = await response.json();
- return transfersInfo
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-When querying multiple chains, the response includes a `chain_ids` array in the metadata and each item in the data array includes its `chain_id`:
-
-```json
-{
- "meta": {
- "chain_ids": [1, 137],
- "total_items": 10,
- "limit_per_chain": 5,
- "page": 0,
- "limit": 10,
- "total_pages": 1
- },
- "data": [
- {
- "chain_id": 1,
- "block_number": 14705663,
- // ... other Ethereum event data
- },
- {
- "chain_id": 137,
- "block_number": 25631042,
- // ... other Polygon event data
- }
- // ... more events from both chains
- ]
-}
-```
-
-Key points about multichain queries:
-- Use the base URL `https://insight.thirdweb.com` instead of the chain-specific subdomain
-- Add multiple `chain` query parameters (e.g., `chain=1&chain=137`)
-- The response includes a `chain_ids` array and `limit_per_chain` in the metadata
-- Each item in the data array includes its `chain_id` for identification
-
-For more detailed information and advanced use cases, check out our [Multichain Queries](/insight/multichain-queries) documentation.
diff --git a/apps/portal/src/app/insight/layout.tsx b/apps/portal/src/app/insight/layout.tsx
deleted file mode 100644
index 3aaed384197..00000000000
--- a/apps/portal/src/app/insight/layout.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { createMetadata } from "@doc";
-import { DocLayout } from "@/components/Layouts/DocLayout";
-import { sidebar } from "./sidebar";
-
-export default async function Layout(props: { children: React.ReactNode }) {
- return (
-
- {props.children}
-
- );
-}
-
-export const metadata = createMetadata({
- description: "Query, transform and analyze blockchain data",
- image: {
- icon: "insight",
- title: "Insight",
- },
- title: "Insight",
-});
diff --git a/apps/portal/src/app/insight/multichain-queries/page.mdx b/apps/portal/src/app/insight/multichain-queries/page.mdx
deleted file mode 100644
index 573315377c2..00000000000
--- a/apps/portal/src/app/insight/multichain-queries/page.mdx
+++ /dev/null
@@ -1,245 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Multichain Queries | thirdweb Insight",
- description:
- "Learn how to query multiple blockchains simultaneously with thirdweb Insight",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Multichain Queries
-
-Insight now supports querying multiple blockchain networks in a single API call. This powerful feature allows you to retrieve and analyze data across different chains without making separate requests for each network.
-
-## Why Use Multichain Queries?
-
-- **Efficiency**: Reduce the number of API calls needed to fetch data from multiple chains
-- **Simplicity**: Consolidate cross-chain data in a single request and response
-- **Performance**: Minimize latency by avoiding sequential requests to different chains
-- **Consistency**: Process data from different networks using a unified format
-
-## How to Use Multichain Queries
-
-Instead of using the chain-specific subdomain approach, multichain queries use the base URL with multiple `chain` query parameters:
-
-```typescript
-// Traditional single-chain query (using subdomain)
-const singleChainUrl = `https://1.insight.thirdweb.com/v1/events`;
-
-// Multichain query (using base URL with chain parameters)
-const multiChainUrl = `https://insight.thirdweb.com/v1/events?chain=1&chain=137`;
-```
-
-### Authentication
-
-Authentication works the same way as with single-chain queries:
-
-```typescript
-// Using client ID in header
-const headers = {
- "x-client-id": "{{clientId}}"
-};
-
-// Or as a query parameter
-const url = `https://insight.thirdweb.com/v1/events?chain=1&chain=137&clientId={{clientId}}`;
-```
-
-## Response Format
-
-Responses for multichain queries include additional metadata to help you identify which data belongs to which chain:
-
-```json
-{
- "meta": {
- "chain_ids": [1, 137], // List of queried chain IDs
- "total_items": 113, // Total count across all chains
- "limit_per_chain": 100, // Per-chain limit derived from the request
- "page": 0,
- "limit": 200,
- "total_pages": 1
- },
- "data": [
- {
- "chain_id": 1, // Each item includes its chain ID
- "block_number": "17859301",
- "transaction_hash": "0x123...",
- // ... other fields
- },
- {
- "chain_id": 137,
- "block_number": "48392021",
- // ... other fields
- }
- ]
-}
-```
-
-Key differences in the response format:
-- The `meta` object includes a `chain_ids` array listing all queried chains
-- A `limit_per_chain` field indicates how many items were requested per chain
-- Each item in the `data` array includes a `chain_id` field to identify its network
-
-## Pagination and Limits
-
-When using multichain queries, the `limit` parameter applies to each chain individually:
-
-```typescript
-// This will return up to 20 items from each chain (potentially 40 total items)
-const url = `https://insight.thirdweb.com/v1/events?chain=1&chain=137&limit=20`;
-```
-
-The `limit_per_chain` in the response metadata shows how many items were requested per chain, while the overall `limit` represents the maximum total items across all chains.
-
-## Examples
-
-### Example 1: Query Events Across Multiple Chains
-
-```typescript
-const getMultichainEvents = async () => {
- try {
- // Query events on Ethereum (1) and Polygon (137)
- const response = await fetch(
- 'https://insight.thirdweb.com/v1/events?chain=1&chain=137&limit=10',
- {
- headers: {
- 'x-client-id': ''
- }
- }
- );
- return await response.json();
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-### Example 2: Track Token Balances Across Networks
-
-```typescript
-const getMultichainTokenBalances = async (ownerAddress) => {
- try {
- // Get ERC-20 balances on Ethereum, Polygon, and Arbitrum
- const response = await fetch(
- `https://insight.thirdweb.com/v1/tokens/erc20/${ownerAddress}?chain=1&chain=137&chain=42161`,
- {
- headers: {
- 'x-client-id': ''
- }
- }
- );
- return await response.json();
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-### Example 3: Monitor NFT Collections Across Chains
-
-```typescript
-const getMultichainNFTs = async (ownerAddress) => {
- try {
- // Get NFTs on Ethereum and Base
- const response = await fetch(
- `https://insight.thirdweb.com/v1/tokens/erc721/${ownerAddress}?chain=1&chain=8453`,
- {
- headers: {
- 'x-client-id': ''
- }
- }
- );
- return await response.json();
- } catch (error) {
- console.error('Error:', error);
- }
-};
-```
-
-## Supported Endpoints
-
-All Insight blueprints support multichain queries:
-
-- **Events Blueprint**: `/v1/events` - Returns events from specified chains
-- **Transactions Blueprint**: `/v1/transactions` - Provides transactions from multiple chains
-- **Tokens Blueprint**:
- - `/v1/tokens/erc20/:ownerAddress` - Consolidates ERC-20 token balances across chains
- - `/v1/tokens/erc721/:ownerAddress` - Consolidates NFT holdings across chains
- - `/v1/tokens/erc1155/:ownerAddress` - Consolidates ERC-1155 token balances across chains
-
-## Best Practices
-
-1. **Limit Chain Count**: While you can query multiple chains, it's best to limit the number of chains in a single request to avoid timeouts.
-
-2. **Use Appropriate Limits**: Set reasonable `limit` values to control response size and processing time.
-
-3. **Handle Chain-Specific Errors**: Some chains might return errors while others succeed. Your code should handle partial successes.
-
-4. **Process Data by Chain**: When analyzing the response, group or filter data by `chain_id` for chain-specific analysis.
-
-5. **Consider Rate Limits**: Multichain queries count against your rate limits for each chain queried.
-
-## Use Cases
-
-### Cross-Chain Portfolio Tracking
-
-Track a user's assets across multiple networks to provide a comprehensive view of their holdings:
-
-```typescript
-const getPortfolio = async (address) => {
- // Get ERC-20 tokens across major chains
- const erc20Response = await fetch(
- `https://insight.thirdweb.com/v1/tokens/erc20/${address}?chain=1&chain=137&chain=42161&chain=10&chain=8453`,
- { headers: { 'x-client-id': '' } }
- );
-
- // Get NFTs across the same chains
- const nftResponse = await fetch(
- `https://insight.thirdweb.com/v1/tokens/erc721/${address}?chain=1&chain=137&chain=42161&chain=10&chain=8453`,
- { headers: { 'x-client-id': '' } }
- );
-
- return {
- tokens: await erc20Response.json(),
- nfts: await nftResponse.json()
- };
-};
-```
-
-### Cross-Chain Activity Monitoring
-
-Monitor transactions or events across multiple chains for a specific address:
-
-```typescript
-const getRecentActivity = async (address) => {
- const response = await fetch(
- `https://insight.thirdweb.com/v1/transactions?filter_from_address=${address}&chain=1&chain=137&chain=42161&sort_by=block_timestamp&sort_order=desc&limit=10`,
- { headers: { 'x-client-id': '' } }
- );
-
- return await response.json();
-};
-```
-
-### Cross-Chain Protocol Analysis
-
-Analyze protocol activity across different deployments on multiple chains:
-
-```typescript
-const getProtocolActivity = async (protocolAddresses) => {
- // protocolAddresses = { 1: "0x123...", 137: "0x456...", 42161: "0x789..." }
-
- const queryParams = Object.entries(protocolAddresses)
- .map(([chainId, address]) => `chain=${chainId}&filter_address=${address}`)
- .join('&');
-
- const response = await fetch(
- `https://insight.thirdweb.com/v1/events?${queryParams}&limit=50`,
- { headers: { 'x-client-id': '' } }
- );
-
- return await response.json();
-};
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/insight/page.mdx b/apps/portal/src/app/insight/page.mdx
deleted file mode 100644
index 7ea1e511cce..00000000000
--- a/apps/portal/src/app/insight/page.mdx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { OpenSourceCard, DocImage, Grid, ArticleCard, FeatureCard } from "@doc";
-import { createMetadata } from "@/components/Document";
-import SupportedChains from "../_images/supported-chains.png";
-import { WalletIcon, FileIcon, MessageCircleIcon, BracesIcon, BotIcon, BlocksIcon, AlbumIcon, ServerIcon, ZapIcon, FunctionSquareIcon } from "lucide-react";
-
-
-export const metadata = createMetadata({
- title: "thirdweb Insight",
- description: "Query, transform and analyze blockchain data",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Insight
-
-Insight is a tool that lets you retrieve blockchain data from any EVM chain, enrich it with metadata, and transform it using custom logic.
-
-
-
-## Features
-
-
- }
- />
-
- }
- />
-
- }
- href="/insight/get-started#using-aggregations"
- />
-
- }
- />
-
- }
- />
-
-
-## Video Tutorials
-
-
-
-## Supported Chains
-Insight is supported on select EVM compatible chains. To view the full list, visit [thirdweb chainlist](https://thirdweb.com/chainlist?service=insight).
-
-
diff --git a/apps/portal/src/app/insight/sidebar.tsx b/apps/portal/src/app/insight/sidebar.tsx
deleted file mode 100644
index eb896bfa69e..00000000000
--- a/apps/portal/src/app/insight/sidebar.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import {
- AlbumIcon,
- BoxIcon,
- BracesIcon,
- BrainIcon,
- MessageCircleQuestionIcon,
- NetworkIcon,
- RocketIcon,
- StickyNoteIcon,
- WebhookIcon,
- WrenchIcon,
-} from "lucide-react";
-import type { SideBar } from "@/components/Layouts/DocLayout";
-
-const insightSlug = "/insight";
-
-export const sidebar: SideBar = {
- links: [
- {
- href: "/insight",
- icon: ,
- name: "Overview",
- },
- {
- href: `${insightSlug}/use-cases`,
- icon: ,
- name: "Use Cases",
- },
- {
- href: `${insightSlug}/get-started`,
- icon: ,
- name: "Get Started",
- },
- {
- href: `${insightSlug}/blueprints`,
- icon: ,
- name: "Blueprints",
- },
- {
- href: `${insightSlug}/multichain-queries`,
- icon: ,
- name: "Multichain Queries",
- },
- {
- href: `${insightSlug}/agents-and-llms`,
- icon: ,
- links: [
- {
- href: `${insightSlug}/agents-and-llms/llmstxt`,
- name: "llms.txt",
- },
- ],
- name: "Agents & LLMs",
- },
- {
- href: `${insightSlug}/webhooks`,
- icon: ,
- links: [
- {
- href: `${insightSlug}/webhooks`,
- name: "Get Started",
- },
- {
- href: `${insightSlug}/webhooks/managing-webhooks`,
- name: "Managing Webhooks",
- },
- {
- href: `${insightSlug}/webhooks/filtering`,
- name: "Filtering",
- },
- {
- href: `${insightSlug}/webhooks/payload`,
- name: "Payload",
- },
- {
- href: "https://insight.thirdweb.com/reference#tag/webhooks",
- name: "API Reference",
- },
- ],
- name: "Webhooks",
- },
- {
- href: "https://insight.thirdweb.com/reference",
- icon: ,
- name: "API Reference",
- },
- {
- href: `${insightSlug}/troubleshoot`,
- icon: ,
- name: "Troubleshoot",
- },
- {
- href: `${insightSlug}/faqs`,
- icon: ,
- name: "FAQs",
- },
- ],
- name: "Insight",
-};
diff --git a/apps/portal/src/app/insight/troubleshoot/page.mdx b/apps/portal/src/app/insight/troubleshoot/page.mdx
deleted file mode 100644
index c71da06a250..00000000000
--- a/apps/portal/src/app/insight/troubleshoot/page.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-# Insight Troubleshoot Guide
-
-More information coming soon.
\ No newline at end of file
diff --git a/apps/portal/src/app/insight/use-cases/page.mdx b/apps/portal/src/app/insight/use-cases/page.mdx
deleted file mode 100644
index 2e208abb8e7..00000000000
--- a/apps/portal/src/app/insight/use-cases/page.mdx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Insight Use Cases | thirdweb Infrastructure",
- description: "Example use cases for thirdweb Insight",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Insight Use Cases
-
-Insight offers versatile use cases for using blockchain data within applications, enabling developers to track and analyze a wide array of on-chain activities.
-With Insight, you can efficiently monitor transfer events, transactions, token ownership, NFT collections, and staking activities across multiple chains, and more,
-making it a powerful tool for building dynamic blockchain applications.
-
-| Use Case | Blueprint(s) |
-| --- | --- |
-| Display in-game assets such as items or tokens (ERC-20, ERC-721, or ERC-1155) tied to the player's wallet. | Use Events Blueprint to fetch transfer events where the player’s wallet is the recipient, showing all NFTs or in-game items acquired by the player. |
-| Display earned tokens based on achievements or progress rewarded to players in games. | Use Transactions Blueprint to track transactions where the game’s smart contract sends tokens to a player’s wallet.
Use Events Blueprint to filter transfer events from the game’s contract to list all tokens awarded to players. |
-| Analyze token economics such as daily trading volume to understand token liquidity or market activity. | Use the Transactions Blueprint to get transactions involving any token and then aggregate data based on timestamps to calculate 24-hour transaction volumes.
**Example Aggregations:**
- `sum(value) AS daily_volume`
- `count() AS transaction_count`
- `avg(value) AS avg_tx_value` |
-| Analyze gas consumption of different transactions to help minimize gas fees for users by evaluating high-gas transactions or commonly used functions. | Use Transactions Blueprint to summarize gas usage across transactions for specific functions, helping to analyze and optimize protocol functions for efficiency.
**Example Aggregations:**
- `avg(gas_used) AS avg_gas_used`
- `max(gas_used) AS max_gas_used`
- `sum(gas_used * gas_price) AS total_fees_wei` |
-| Analyze token ownership to understand community health and investment risks. | Use Events Blueprint to track token transfer events, allowing users to analyze the distribution and concentration of token holders. |
-| Track the movements of an entire NFT collection. | Use Events Blueprint to capture all transfer events for a specified collection and show ownership history or current trading volume for the collection.
**Example Aggregations:**
- `countDistinct(from_address) AS unique_sellers`
- `countDistinct(to_address) AS unique_buyers`
- `count() AS total_transfers` |
-| Fetch all NFTs owned by a specific wallet address. | Use Events Blueprint to fetch transfer events for each NFT contract where the specified wallet address is the recipient. |
-| Fetch all transactions emitted by a single wallet across multiple chains. | Use Transactions Blueprint to filter transactions by wallet address across different chain_ids to provide a historical view of cross-chain transactions.
**Example Aggregations:**
- `count() AS total_transactions`
- `sum(value) AS total_value_transferred` |
-| Fetch all tokens owned by a specific wallet address. | Use Events Blueprint to find transfer events where the wallet address is the recipient, providing a list of token balances. |
-| Detect wallet staking activity on platforms such as AAVE or other DeFi protocols. | Use Events Blueprint to filter for staking-related events such as deposits, and monitor which wallets are actively staking. |
-
diff --git a/apps/portal/src/app/insight/webhooks/assets/create-filters.png b/apps/portal/src/app/insight/webhooks/assets/create-filters.png
deleted file mode 100644
index 852a5000d71..00000000000
Binary files a/apps/portal/src/app/insight/webhooks/assets/create-filters.png and /dev/null differ
diff --git a/apps/portal/src/app/insight/webhooks/assets/create-webhooks.png b/apps/portal/src/app/insight/webhooks/assets/create-webhooks.png
deleted file mode 100644
index b0aecda1405..00000000000
Binary files a/apps/portal/src/app/insight/webhooks/assets/create-webhooks.png and /dev/null differ
diff --git a/apps/portal/src/app/insight/webhooks/assets/test-webhook.png b/apps/portal/src/app/insight/webhooks/assets/test-webhook.png
deleted file mode 100644
index 0db034292e0..00000000000
Binary files a/apps/portal/src/app/insight/webhooks/assets/test-webhook.png and /dev/null differ
diff --git a/apps/portal/src/app/insight/webhooks/filtering/page.mdx b/apps/portal/src/app/insight/webhooks/filtering/page.mdx
deleted file mode 100644
index 50c5f8496bd..00000000000
--- a/apps/portal/src/app/insight/webhooks/filtering/page.mdx
+++ /dev/null
@@ -1,161 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Insight Webhooks | thirdweb Infrastructure",
- description: "Filtering",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Filtering
-
-## Webhook Topics
-
-### `v1.events`
-
-Subscribes to blockchain log events.
-
-### `v1.transactions`
-
-Subscribes to blockchain transactions.
-
-## Webhook Filters
-
-You can filter webhook notifications based on specific criteria.
-Each webhook must have either an events filter or a transactions filter (or both).
-
-### Event Filters
-```typescript
-{
- "v1.events": {
- chain_ids: string[], // Filter by specific chains
- addresses: string[], // Filter by contract addresses
- signatures: { // Filter by event signatures
- sig_hash: string, // Event signature hash
- abi?: string, // Optional: A single ABI object or an array of ABI objects as a string for data decoding
- params?: Record // Filter on decoded parameters
- }[]
- }
-}
-```
-
-### Transaction Filters
-```typescript
-{
- "v1.transactions": {
- chain_ids: string[], // Filter by specific chains
- from_addresses: string[], // Filter by sender addresses
- to_addresses: string[], // Filter by recipient addresses
- signatures: { // Filter by function signatures
- sig_hash: string, // Function signature hash
- abi?: string, // Optional: A single ABI object or an array of ABI objects as a string for data decoding
- params?: Record // Filter on decoded parameters
- }[]
- }
-}
-```
-
-### ABIs
-
-You can specify partial ABIs to have decoded data sent in the webhook payload. For this you also need to give the `sig_hash` of the event or function call.
-
-The following example will filter for `Transfer` events on Ethereum for the contract `0x1f9840a85d5af5bf1d1762f925bdaddc4201f984`
-```typescript
-{
- ...
- filters: {
- "v1.events": {
- chain_ids: ["1"],
- addresses: ["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"],
- signatures: [
- {
- sig_hash:
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- abi: '{"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"}',
- },
- ],
- },
- },
- ...
-}
-```
-
-### Supporting Multiple Event ABIs
-
-In some cases, different token standards use the same event signature. For example, both ERC-20 and ERC-721 standards have a `Transfer` event. The ERC-20 `Transfer(address,address,uint256)` event has a non-indexed `value` parameter, while the ERC-721 `Transfer(address,address,uint256)` has an indexed `tokenId` parameter.
-
-To support these scenarios, you can provide an array of ABIs in the `abi` field. This allows the webhook to attempt decoding with each ABI until one succeeds.
-
-The `abi` field accepts a string that can be either a single JSON object `"{}"` or a JSON array of objects `'[{},{}]'`.
-
-Here is an example of a webhook that filters for both ERC-20 and ERC-721 `Transfer` events across all contracts on the Ethereum mainnet:
-
-```typescript
-{
- ...
- "filters": {
- "v1.events": {
- "chain_ids": ["1"],
- "signatures": [
- {
- "sig_hash": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "abi": "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}]"
- }
- ]
- }
- }
- ...
-}
-```
-
-And this example will filter for `Approve` function calls on Ethereum for the contract `0x1f9840a85d5af5bf1d1762f925bdaddc4201f984`
-```typescript
-{
- ...
- filters: {
- "v1.transactions": {
- chain_ids: ["1"],
- addresses: ["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"],
- signatures: [
- {
- sig_hash: "0x095ea7b3",
- abi: '{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"rawAmount","type":"uint256"}],"name":"approve","type":"function"}',
- },
- ],
- },
- },
- ...
-}
-```
-
-### Params
-
-`params` on the `signatures` object will allow you to filter based on the decoded data. Only strict equality is supported at the moment.
-
-For example, if you want to filter for `Transfer` events where the `from` address is `0x1f9840a85d5af5bf1d1762f925bdaddc4201f984`, you can use the following:
-```typescript
-{
- ...
- "filters": {
- "v1.events": {
- "chain_ids": ["1"],
- "addresses": ["0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"],
- "signatures": [{
- "sig_hash": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "abi": "{\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"}",
- "params": {
- "from": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"
- }
- }]
- }
- }
- ...
-}
-```
-
-### Notes
-- You can specify ABIs to receive decoded event/transaction data
-- Parameter filtering supports equality matching only
-- At least one filter criteria must be specified
diff --git a/apps/portal/src/app/insight/webhooks/managing-webhooks/page.mdx b/apps/portal/src/app/insight/webhooks/managing-webhooks/page.mdx
deleted file mode 100644
index a274e835b8e..00000000000
--- a/apps/portal/src/app/insight/webhooks/managing-webhooks/page.mdx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- title: "Insight Webhooks | thirdweb Infrastructure",
- description: "Managing Insight webhooks",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Managing Webhooks
-
-For most up to date technical spec refer to https://insight-api.thirdweb.com/reference#tag/webhooks.
-
-## List Webhooks
-`GET /v1/webhooks`
-
-Retrieve all webhooks for your project or get details for a specific webhook by ID.
-
-## Create Webhook
-`POST /v1/webhooks`
-
-Creates a new webhook subscription.
-It may take up to a minute to start working.
-
-## Update Webhook
-`PATCH /v1/webhooks/:webhook_id`
-
-You can modify the URL or filters of a webhook. Additionally you can enable and disable the webhook.
-Changes may take up to a minute to take effect.
-
-
-## Delete Webhook
-`DELETE /v1/webhooks/:webhook_id`
-
-Permanently removes a webhook subscription. This action cannot be undone.
-
-## Test Webhook
-`POST /v1/webhooks/test`
-
-Sends a sample payload signed with a test secret ('test123').
-Useful for testing your receiver endpoint before creating actual webhooks.
diff --git a/apps/portal/src/app/insight/webhooks/page.mdx b/apps/portal/src/app/insight/webhooks/page.mdx
deleted file mode 100644
index 68582ae05b4..00000000000
--- a/apps/portal/src/app/insight/webhooks/page.mdx
+++ /dev/null
@@ -1,80 +0,0 @@
-import { createMetadata, Steps, Step, DocImage } from "@doc";
-import CreateWebhook from './assets/create-webhooks.png'
-import CreateFilters from './assets/create-filters.png'
-import TestWebhook from './assets/test-webhook.png'
-
-export const metadata = createMetadata({
- title: "Insight Webhooks | thirdweb Infrastructure",
- description: "Receive real-time notifications for blockchain events",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Webhooks
-
-Webhooks allow you to receive notifications when specific blockchain events or transactions occur. This enables you to automate workflows and keep your applications in sync with on-chain activity.
-
-### Data Delivery
-Webhook events are collected and delivered in batches for optimal performance and reliability. This makes webhooks ideal for:
-- Tracking when specific blockchain events occur
-- Aggregating on-chain data
-- Building analytics and monitoring systems
-- Triggering downstream processes
-
-### Delivery Guarantees
-Events are guaranteed to be delivered *at least once*. Your application should implement idempotency and deduplication logic using the unique event ID in the payload. Please note, events may occasionally be delivered out of order.
-
-### Performance Requirements
-- Your receiving endpoint must respond within 3 seconds
-- If your endpoint consistently fails to respond in time, the webhook will be automatically suspended
-- We recommend implementing a queue system if you need to perform time-consuming operations
-
-## Get started
-
-Webhooks can be configured in the thirdweb dashboard (recommended) by creating a project or [programmatically using the Insight API](/insight/webhooks/managing-webhooks).
-
-
-
-Creating a webhook requires a project. If you don't have a project yet, create one in the thirdweb dashboard and navigate to the Webhooks section.
-
-
-
-Select New Webhook and provide the following:
-- **Name**: A descriptive name for your webhook
-- **Endpoint URL**: The URL where you want to receive webhook notifications
-- **Events**: Select an event or transaction filter type:
- - **Event**: Triggered by specific blockchain events (e.g., token transfers, contract interactions)
- - **Transaction**: Triggered by transactions matching specific criteria (e.g., from/to address, value)
-
-
-
-
-You can set up filters to narrow down the events or transactions that trigger the webhook.
-
-For EVENTS:
-
-- **Chain IDs**: Select the blockchain networks you want to monitor (e.g., Ethereum, Polygon)
-- **Contract Addresses**: Specify contract addresses to filter events related to specific contracts
-- **Event Signatures**: For event filters, you can specify event signatures to target specific events
-- **ABI**: For event filters, you can provide the ABI of the contract- providing the contract's address will usually automatically fetch the ABI.
-
-For TRANSACTION:
-
-- **Chain IDs**: Select the blockchain networks you want to monitor
-- **From/To Addresses**: Specify addresses to filter transactions by sender or recipient
-- **Function Signatures**: For transaction filters, you can specify function signatures to target specific contract interactions
-- **ABI**: For transaction filters, you can provide the ABI of the contract- providing the contract's address will usually automatically fetch the ABI.
-
-
-
-
-
-After creating the webhook, you can test it by sending a sample event. This allows you to verify that your endpoint is correctly configured to receive and process webhook notifications.
-
-After successful testing, click "Create Webhook" to finalize the setup.
-
-
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/insight/webhooks/payload/page.mdx b/apps/portal/src/app/insight/webhooks/payload/page.mdx
deleted file mode 100644
index f1c34894cd1..00000000000
--- a/apps/portal/src/app/insight/webhooks/payload/page.mdx
+++ /dev/null
@@ -1,202 +0,0 @@
-import { createMetadata } from "@doc";
-import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
-
-export const metadata = createMetadata({
- title: "Insight Webhooks | thirdweb Infrastructure",
- description: "Payload",
- image: {
- title: "Insight",
- icon: "insight",
- },
-});
-
-# Webhook Payload
-
-## Payload Format
-```typescript
-{
- topic: string, // topic of the data
- timestamp: string, // timestamp of when the payload was sent in seconds
- data: [
- {
- data: object, // data of the event or transaction
- status: "new" | "reverted",
- type: "event" | "transaction",
- id: string // unique id of the data
- }
- ]
-}
-```
-
-Example Response:
-
-
-
-
- Events
- Transactions
-
-
-
-```json
-{
- "timestamp": 1743164112,
- "topic": "v1.events",
- "data": [
- {
- "data": {
- "chain_id": "1",
- "block_number": 22140383,
- "block_hash": "0x85bd4045d947c34b6b568fc84c7550c0efa741f71c834bbb3d3950e9da27842e",
- "block_timestamp": 1743104207,
- "transaction_hash": "0x460ced3718d0e09145eae8b63fd985dc366adfc4523c791116f24dc051e8363a",
- "transaction_index": 93,
- "log_index": 230,
- "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
- "data": "0x000000000000000000000000000000000000000000000000009440c61e928cca",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x000000000000000000000000d360131b77ead72f1f23fb185b4896fe01dc8cb5",
- "0x00000000000000000000000085cd07ea01423b1e937929b44e4ad8c40bbb5e71"
- ],
- "decoded": {
- "name": "Transfer",
- "indexed_params": {
- "from": "0xd360131b77ead72f1f23fb185b4896fe01dc8cb5",
- "to": "0x85cd07ea01423b1e937929b44e4ad8c40bbb5e71"
- },
- "non_indexed_params": {
- "amount": "41729516213800138"
- }
- }
- },
- "status": "new",
- "type": "event",
- "id": "76b81da4ec46486f0a6e325596f506cad13ebd629520aded104efcaa37a419d5"
- }
- ]
-}
-```
-
-
-
-```json
-{
- "timestamp": 1743165030,
- "topic": "v1.transactions",
- "data": [
- {
- "data": {
- "chain_id": "1",
- "hash": "0xceba210be88785cac0884127cb42d370bcde8248e11e490af0deeb6ded2bb421",
- "nonce": 5,
- "block_hash": "0x86cfe1e32fb3e5091bc2533b78d1503a4539936f50ff5a33b09df639f1572fdd",
- "block_number": 22145183,
- "block_timestamp": 1743162179,
- "transaction_index": 62,
- "from_address": "0xcd1785a6a49748948059d3c27d8f55ad0ef94c8c",
- "to_address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
- "value": "0",
- "gas": 50000,
- "gas_price": "2000000000",
- "data": "0xa9059cbb00000000000000000000000028c6c06298d514db089934071355e5743bf21d60000000000000000000000000000000000000000000000024ac7a2466fe6d4000",
- "function_selector": "0xa9059cbb",
- "max_fee_per_gas": "2000000000",
- "max_priority_fee_per_gas": "2000000000",
- "transaction_type": 2,
- "r": "93121701149456501424579980283392650303695688563543540003926043202730906996706",
- "s": "5712073776861917154895012394334633911928305143620822626852008432451821415527",
- "v": "1",
- "access_list_json": "[]",
- "contract_address": null,
- "gas_used": 35318,
- "cumulative_gas_used": 9124496,
- "effective_gas_price": "2000000000",
- "blob_gas_used": 0,
- "blob_gas_price": "0",
- "logs_bloom": "0x40000000000000000000000000000000000000000020000000000000000000000000000000000000000001000000001000008000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000008000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "status": 1,
- "decoded": {
- "name": "transfer",
- "inputs": {
- "dst": "0x28c6c06298d514db089934071355e5743bf21d60",
- "rawAmount": "676511072800000000000"
- }
- }
- },
- "status": "new",
- "type": "transaction",
- "id": "e922999aff6625e1e26e6eca478b2c6ece33a5b8cf3a3c8bde96c00da8d2acc0"
- }
- ]
-}
-```
-
-
-
-## Headers
-Each webhook request includes:
-- `x-webhook-id` - ID of the webhook configuration to know which one triggered the send
-- `x-webhook-signature` - hash of the payload signed with the webhook's secret. Used to validate the payload
-
-## Signature Verification (highly recommended)
-
-To verify that the request is from thirdweb webhooks it is highly recommended to verify the payload.
-Each webhook has a `webhook_secret` which is used to sign the raw payload and is then attached to the headers.
-
-To verify the webhook:
-```typescript
-const generateSignature = (
- rawBody: string,
- secret: string,
-): string => {
- return crypto
- .createHmac("sha256", secret)
- .update(rawBody)
- .digest("hex");
-};
-
-const isValidSignature = (
- rawBody: string,
- signature: string,
- secret: string,
-): boolean => {
- const expectedSignature = generateSignature(
- body,
- secret,
- );
- return crypto.timingSafeEqual(
- Buffer.from(expectedSignature),
- Buffer.from(signature),
- );
-};
-
-// extract the signature from request headers
-const signature = req.headers['x-webhook-signature'];
-// get the raw body of the request
-const rawBody = req.rawBody;
-
-const isValid = isValidSignature(rawBody, signature, secret);
-```
-
-**You need to use the raw request body when verifying webhooks, as the cryptographic signature is sensitive to even the slightest changes. You should watch out for frameworks that parse the request as JSON and then stringify it because this too will break the signature verification.**
-
-## Payload Age
-
-You can optionally also verify the age of the payload.
-After you have verified the signature, you can be sure the timestamp in the payload is correct and apply any time limit you wish.
-
-```typescript
-export const isExpired = (
- timestamp: string,
- expirationInSeconds: number,
-): boolean => {
- const currentTime = Math.floor(Date.now() / 1000);
- return currentTime - parseInt(timestamp) > expirationInSeconds;
-};
-```
-
-## Reorged Data
-If a blockchain reorganization occurs:
-- You'll receive an event with `status: "reverted"` instead of `status: "new"`
-- You should handle this by reverting any actions taken for the original event
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx
deleted file mode 100644
index 453de34ef07..00000000000
--- a/apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaContextParameter,
- nebulaSecretKeyHeaderParameter,
-} from "../common";
-
-const response200Example = `\
-{
- "message": "string",
- "actions": [
- {
- "session_id": "string",
- "request_id": "string",
- "type": "init",
- "source": "string",
- "data": "string"
- }
- ],
- "session_id": "string",
- "request_id": "string"
-}`;
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/chat/page.mdx b/apps/portal/src/app/nebula/api-reference/chat/page.mdx
deleted file mode 100644
index c808d4a072e..00000000000
--- a/apps/portal/src/app/nebula/api-reference/chat/page.mdx
+++ /dev/null
@@ -1,117 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-
-# Chat Actions
-
-Chat actions represent blockchain transactions or operations that Nebula has prepared in response to your request. The response includes both a detailed explanation in the `message` field and the actual transaction data in the `actions` array.
-
-
-
-**Example Response with Chat Action:**
-```json
-{
- "message": "The transaction to transfer 0.0001 ETH to the address resolved from the ENS name `vitalik.eth` (which is `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`) is set up successfully. The simulation indicates that the transaction is likely to succeed.\n\nPlease proceed by signing and confirming the transaction.",
- "actions": [
- {
- "session_id": "437a0df7-d512-4ef4-95b5-6168ccbbe097",
- "request_id": "c2b51ed6-da79-49ac-b411-206a42059509",
- "type": "sign_transaction",
- "source": "executor",
- "data": "{\"chainId\": 11155111, \"to\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\", \"data\": \"0x\", \"value\": \"0x5af3107a4000\"}"
- }
- ],
- "session_id": "437a0df7-d512-4ef4-95b5-6168ccbbe097",
- "request_id": "c2b51ed6-da79-49ac-b411-206a42059509"
-}
-```
-
-**Action Properties:**
-- `session_id`: Unique identifier for the current session
-- `request_id`: Unique identifier for the specific request
-- `type`: The type of action (e.g., "sign_transaction")
-- `source`: Origin of the action (e.g., "executor")
-- `data`: Transaction parameters including:
- - `chainId`: Network identifier (e.g., 11155111 for Sepolia)
- - `to`: Recipient's address
- - `data`: Transaction data (if any)
- - `value`: Amount to send in wei
-
-When handling actions:
-1. Parse the `message` field for human-readable transaction details
-2. Extract the transaction data from the `actions` array
-3. Present transaction details to the user for review
-4. Use a local wallet to sign the transaction
-5. Broadcast the signed transaction to the network
-
-**Example Implementation with thirdweb SDK:**
-```javascript
-import {
- createThirdwebClient,
- prepareTransaction,
- sendTransaction,
- privateKeyToAccount
-} from "thirdweb";
-
-// Example function to handle the API response
-async function handleNebulaResponse(response) {
- // Initialize thirdweb client
- const client = createThirdwebClient({
- secretKey: process.env.THIRDWEB_SECRET_KEY
- });
-
- // Initialize account
- const account = privateKeyToAccount({
- client,
- privateKey: process.env.EOA_PRIVATE_KEY
- });
-
- // Check if we have any actions
- if (response.actions && response.actions.length > 0) {
- const action = response.actions[0];
-
- // Parse the transaction data from the action
- const txData = JSON.parse(action.data);
-
- try {
- // Prepare transaction with client
- const transaction = prepareTransaction({
- to: txData.to,
- data: txData.data,
- value: BigInt(txData.value),
- chain: txData.chainId,
- client
- });
-
- // Send transaction with account
- const result = await sendTransaction({
- transaction,
- account
- });
-
- return result;
- } catch (error) {
- console.error("Error processing transaction:", error);
- throw error;
- }
- }
-}
-
-// Example usage
-const response = await fetch('https://nebula-api.thirdweb.com/chat', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'x-secret-key': 'YOUR_THIRDWEB_SECRET_KEY'
- },
- body: JSON.stringify({
- message: "send 0.0001 ETH on sepolia to vitalik.eth",
- execute_config: {
- mode: "client",
- signer_wallet_address: "0xc3F2b2a12Eba0f5989cD75B2964E31D56603a2cE"
- }
- })
-});
-
-const data = await response.json();
-const result = await handleNebulaResponse(data);
-```
diff --git a/apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx
deleted file mode 100644
index 616629ed9b9..00000000000
--- a/apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaFullSessionResponse,
- nebulaSecretKeyHeaderParameter,
- nebulaSessionIdPathParameter,
-} from "../common";
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/clear-session/page.mdx b/apps/portal/src/app/nebula/api-reference/clear-session/page.mdx
deleted file mode 100644
index 6f9e4fec7b8..00000000000
--- a/apps/portal/src/app/nebula/api-reference/clear-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Clear Session
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/common.ts b/apps/portal/src/app/nebula/api-reference/common.ts
deleted file mode 100644
index f0d5f953cff..00000000000
--- a/apps/portal/src/app/nebula/api-reference/common.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import type { APIParameter } from "../../../components/Document/APIEndpointMeta/ApiEndpoint";
-
-export const nebulaFullSessionResponse = `\
-{
- "result": {
- "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
- "title": "string",
- "context": {
- "chain_ids": ["1", "137"],
- "wallet_address": "0x..."
- },
- "history": [
- {}
- ],
- "account_id": "string",
- "model_name": "string",
- "is_public": true,
- "memory": [
- {}
- ],
- "action": [
- {}
- ],
- "archive_at": "2025-01-08T17:22:45.016Z",
- "deleted_at": "2025-01-08T17:22:45.016Z",
- "created_at": "2025-01-08T17:22:45.016Z",
- "updated_at": "2025-01-08T17:22:45.016Z"
- }
-}`;
-
-export const nebulaAPI401Response = `\
-{
- "error": {
- "message": "401: Authentication failed"
- }
-}`;
-
-export const nebulaAPI422Response = `\
-{
- "detail": [
- {
- "loc": [
- "string",
- 0
- ],
- "msg": "string",
- "type": "string"
- }
- ]
-}`;
-
-export const nebulaSecretKeyHeaderParameter: APIParameter = {
- description: "Your thirdweb secret key for authentication.",
- example: "YOUR_THIRDWEB_SECRET_KEY",
- name: "x-secret-key",
- required: true,
- type: "string",
-};
-
-export const nebulaSessionIdPathParameter: APIParameter = {
- description: "The unique ID of the session",
- example: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
- name: "session_id",
- required: true,
- type: "string",
-};
-const nebulaContextFilterType = `\
-{
- chainIds: string[] | null;
- walletAddress: string | null;
-}`;
-
-export const nebulaContextParameter: APIParameter = {
- description: "Provide additional context information along with the message",
- name: "context",
- required: false,
- type: nebulaContextFilterType,
-};
diff --git a/apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx
deleted file mode 100644
index 7312d7c0ceb..00000000000
--- a/apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaContextParameter,
- nebulaFullSessionResponse,
- nebulaSecretKeyHeaderParameter,
-} from "../common";
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/create-session/page.mdx b/apps/portal/src/app/nebula/api-reference/create-session/page.mdx
deleted file mode 100644
index ef8dae5cb16..00000000000
--- a/apps/portal/src/app/nebula/api-reference/create-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Create Session
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx
deleted file mode 100644
index d9f57e5037d..00000000000
--- a/apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaSecretKeyHeaderParameter,
- nebulaSessionIdPathParameter,
-} from "../common";
-
-const response200Example = `\
-{
- "result": {
- "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
- "deleted_at": "2025-01-08T19:27:37.296Z"
- }
-}`;
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/delete-session/page.mdx b/apps/portal/src/app/nebula/api-reference/delete-session/page.mdx
deleted file mode 100644
index 0e3883e59d5..00000000000
--- a/apps/portal/src/app/nebula/api-reference/delete-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Delete Session
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx
deleted file mode 100644
index b6a038c16f1..00000000000
--- a/apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaContextParameter,
- nebulaSecretKeyHeaderParameter,
-} from "../common";
-
-const response200Example = `\
-{
- "message": "string",
- "actions": [
- {
- "session_id": "string",
- "request_id": "string",
- "type": "init",
- "source": "string",
- "data": "string"
- }
- ],
- "session_id": "string",
- "request_id": "string"
-}`;
-
-export function EndpointMetadata() {
- return (
-
- Executes a specified action.
It is similar to /chat but it
- only handles transaction requests. It is designed to be used without
- history context.
- >
- ),
- method: "POST",
- origin: "https://nebula-api.thirdweb.com",
- path: "/execute",
- referenceUrl: "/reference#tag/ai/post/ai/chat",
- request: {
- queryParameters: [],
- bodyParameters: [
- {
- description: "The message to be processed.",
- example: "Hello",
- name: "message",
- required: true,
- type: "string",
- },
- {
- description: "Whether to stream the response or not",
- example: false,
- name: "stream",
- required: false,
- type: "boolean",
- },
- {
- description:
- "The session ID to associate with the message. If not provided, a new session will be created.",
- example: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
- name: "session_id",
- required: false,
- type: "string",
- },
- nebulaContextParameter,
- ],
- headers: [nebulaSecretKeyHeaderParameter],
- pathParameters: [],
- },
- responseExamples: {
- 200: response200Example,
- 401: nebulaAPI401Response,
- 422: nebulaAPI422Response,
- },
- title: "Execute Action",
- }}
- />
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/execute/page.mdx b/apps/portal/src/app/nebula/api-reference/execute/page.mdx
deleted file mode 100644
index 7840ffe8c4a..00000000000
--- a/apps/portal/src/app/nebula/api-reference/execute/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Execute Action
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx
deleted file mode 100644
index 54ee6ccf5a5..00000000000
--- a/apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaFullSessionResponse,
- nebulaSecretKeyHeaderParameter,
- nebulaSessionIdPathParameter,
-} from "../common";
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/get-session/page.mdx b/apps/portal/src/app/nebula/api-reference/get-session/page.mdx
deleted file mode 100644
index 3118c8ecf43..00000000000
--- a/apps/portal/src/app/nebula/api-reference/get-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Get Session
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx
deleted file mode 100644
index 02e17211c3d..00000000000
--- a/apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaSecretKeyHeaderParameter,
-} from "../common";
-
-const response200Example = `\
-{
- "result": [
- {
- "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
- "title": "string",
- "created_at": "2025-01-08T10:52:40.293Z",
- "updated_at": "2025-01-08T10:52:40.293Z"
- }
- ]
-}`;
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/list-session/page.mdx b/apps/portal/src/app/nebula/api-reference/list-session/page.mdx
deleted file mode 100644
index c49f63aa9a4..00000000000
--- a/apps/portal/src/app/nebula/api-reference/list-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# List Sessions
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/api-reference/page.mdx b/apps/portal/src/app/nebula/api-reference/page.mdx
deleted file mode 100644
index 9ffb69d50c0..00000000000
--- a/apps/portal/src/app/nebula/api-reference/page.mdx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- image: {
- title: "API Reference",
- icon: "nebula",
- },
- title: "thirdweb Nebula API Reference",
- description:
- "Explore the thirdweb Nebula API reference to unlock the most powerful AI to interact with the blockchain and start building AI powered web3 apps.",
-});
-
-# Nebula API Reference
-
-Nebula provides a conversational interface to interact with blockchain data and services, and access to thirdweb tools.
-
-
-## Base URL
-
-All API requests should be made to:
-
-```bash
-https://nebula-api.thirdweb.com
-```
-
-## Authentication
-
-All API endpoints require authentication using the thirdweb secret key. [Learn how to obtain a secret key.](/nebula/get-started).
-
-Include this key in your request headers:
-
-```bash
-x-secret-key: YOUR_THIRDWEB_SECRET_KEY
-```
-
-Example curl with authentication:
-```bash
-curl -X POST https://nebula-api.thirdweb.com/chat \
- -H "Content-Type: application/json" \
- -H "x-secret-key: YOUR_THIRDWEB_SECRET_KEY" \
- -d '{
- "message": "send 0.0001 ETH on sepolia to vitalik.eth",
- "user_id": "default-user",
- "stream": false,
- }'
-```
-
-
-
-
-
-
diff --git a/apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx b/apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx
deleted file mode 100644
index abf5442333f..00000000000
--- a/apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { ApiEndpoint } from "@/components/Document/APIEndpointMeta/ApiEndpoint";
-import {
- nebulaAPI401Response,
- nebulaAPI422Response,
- nebulaContextParameter,
- nebulaFullSessionResponse,
- nebulaSecretKeyHeaderParameter,
- nebulaSessionIdPathParameter,
-} from "../common";
-
-export function EndpointMetadata() {
- return (
-
- );
-}
diff --git a/apps/portal/src/app/nebula/api-reference/update-session/page.mdx b/apps/portal/src/app/nebula/api-reference/update-session/page.mdx
deleted file mode 100644
index bd3f8a49d4f..00000000000
--- a/apps/portal/src/app/nebula/api-reference/update-session/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { EndpointMetadata } from './EndpointMetadata';
-
-# Update Session
-
-
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/assets/context-filters.png b/apps/portal/src/app/nebula/assets/context-filters.png
deleted file mode 100644
index 05f57b28cea..00000000000
Binary files a/apps/portal/src/app/nebula/assets/context-filters.png and /dev/null differ
diff --git a/apps/portal/src/app/nebula/assets/keys.png b/apps/portal/src/app/nebula/assets/keys.png
deleted file mode 100644
index d372453b1d0..00000000000
Binary files a/apps/portal/src/app/nebula/assets/keys.png and /dev/null differ
diff --git a/apps/portal/src/app/nebula/assets/nebula-diagram.png b/apps/portal/src/app/nebula/assets/nebula-diagram.png
deleted file mode 100644
index 3ee94cf6bc9..00000000000
Binary files a/apps/portal/src/app/nebula/assets/nebula-diagram.png and /dev/null differ
diff --git a/apps/portal/src/app/nebula/assets/new-project.png b/apps/portal/src/app/nebula/assets/new-project.png
deleted file mode 100644
index 8cbc736a17a..00000000000
Binary files a/apps/portal/src/app/nebula/assets/new-project.png and /dev/null differ
diff --git a/apps/portal/src/app/nebula/assets/streamed-response.png b/apps/portal/src/app/nebula/assets/streamed-response.png
deleted file mode 100644
index a745cd36537..00000000000
Binary files a/apps/portal/src/app/nebula/assets/streamed-response.png and /dev/null differ
diff --git a/apps/portal/src/app/nebula/faqs/page.mdx b/apps/portal/src/app/nebula/faqs/page.mdx
deleted file mode 100644
index e97c6339591..00000000000
--- a/apps/portal/src/app/nebula/faqs/page.mdx
+++ /dev/null
@@ -1,65 +0,0 @@
-import { Details } from "@doc";
-
-# Nebula FAQs
-
-
-During Alpha, we are primarily testing the t0 model while conducting limited trials of the upcoming t1 model.
-The t0 model utilizes a mixture-of-agents architecture. We are targeting an early Q2 launch for t1, and will
-provide additional details around launch.
-
-
-
-Nebula supports reading and writing capabilities on any EVM-compatible chain. [View the chainlist](https://thirdweb.com/chainlist) for all supported chains.
-
-
-
-Yes, you may ask Nebula questions in any spoken language.
-
-
-
-1. Define the Role Clearly: Specify the character’s role and behavior in your prompt.
-
- Example, “You are an assistant embedded in a blockchain application, designed to provide insights and execute transactions without introducing yourself.”
-
-2. Avoid phrases that suggest personality traits or self-awareness: Use Contextual Instructions and add specific instructions to avoid unnecessary introductions.
-
- Example, “Respond directly to queries without stating your identity or greeting users.”
-
-3. Set Output Expectations: Guide the format of responses.
-
- Example, “Provide concise answers or actions based on the user’s input without additional commentary.”
-
-4. Preload Context: Use Nebula’s context filters to scope responses within a specific domain (e.g., blockchain data or transactions) and avoid generic replies.
-
-5. Session Handling: Utilize Nebula’s session handling feature to maintain relevant context throughout interactions, ensuring responses align with the established character behavior.
-
-
-
-We recommend using [context filters](/nebula/key-concepts/context-filters) to improve relevant responses. You may also modify hyperparameters such as temperature, top-p,
-and more using the OpenAI API. Learn more about our [OpenAI API integration](/nebula/plugins/openai).
-
-
-
-Nebula supports the read and write context of any verified contract or any contract on the thirdweb dashboard.
-For deploying through Nebula, supported contracts include [Token - ERC20](https://thirdweb.com/thirdweb.eth/TokenERC20),
-[NFT Collection - ERC721](https://thirdweb.com/thirdweb.eth/TokenERC721), [Edition - ERC1155](https://thirdweb.com/thirdweb.eth/TokenERC1155),
-and [Split](https://thirdweb.com/thirdweb.eth/Split) contracts.
-
-If you have a published contract you would like to enable for deployment through Nebula, please [contact us](https://thirdweb.com/contact-us).
-
-
-
-Nebula retains memory within the confines of a session. [Learn more about sessions](/nebula/key-concepts/sessions).
-
-
-
-The context size or window is 128k tokens or approximately 96,000 words which may vary depending on the specific language and text characteristics.
-
-
-
-Nebula is not currently open source. We are exploring open sourcing Nebula in the future.
-
-
-
-Depending on the use case, Nebula can be used in a stateless manner by not reusing the same session. Nebula learns from each session, so having more contextual requests will be beneficial and are recommended.
-
diff --git a/apps/portal/src/app/nebula/get-started/page.mdx b/apps/portal/src/app/nebula/get-started/page.mdx
deleted file mode 100644
index 955143d4363..00000000000
--- a/apps/portal/src/app/nebula/get-started/page.mdx
+++ /dev/null
@@ -1,184 +0,0 @@
-import { Step, Steps, DocImage, Callout, createMetadata } from "@doc";
-import NewProject from "../assets/new-project.png";
-import KeysSetup from "../assets/keys.png";
-
-export const metadata = createMetadata({
- image: {
- title: "Get Started",
- icon: "nebula",
- },
- title: "Get started with thirdweb Nebula: Set up Guide",
- description:
- "How to start building web3 capable apps with thirdweb Nebula, the most powerful AI to interact with the blockchain.",
-});
-
-
-# Get Started
-
-Learn how to get set up and started with the Nebula API to successfully prepare and enable a connected user to sign a transfer .
-
-## Prerequisites
-
-Before you begin, ensure you have the following:
-
-- A thirdweb account
-- A blockchain wallet for executing transactions
-- Node.js and npm or yarn installed on your system
-
-## Obtain Client ID & Secret Key
-
-
-
-
-
-Navigate to the [projects dashboard](https://thirdweb.com/) and create a new project.
-
-
-
-
-
-
-
-Setup your project and obtain your client ID and secret key. Please note your secret key somewhere safe as it is not recoverable.
-
-
-Client Id is used for client side usage and is restricted by the domain restrictions you set on your API key, it is a public identifier which can be used on the frontend safely.
-
-Secret key is used for server side or script usage and is not restricted by the domain restrictions. Never expose your secret key in client side code.
-
-
-
-
-
-
-
-
-## Setup API (TypeScript SDK)
-
-
-
-
-
-Install the TypeScript SDK
-
-```bash
-npm install thirdweb
-```
-
-
-
-
-Setup environmental variables.
-
-
- Ensure you keep your secret key safe and do not expose it in your codebase. We recommend using a
- secret key manager such as [AWS Secret Manager](https://aws.amazon.com/secrets-manager/) or [Google Secret Manager](https://cloud.google.com/secret-manager).
-
-
-```jsx
-THIRDWEB_SECRET_KEY=your_thirdweb_secret_key
-```
-
-
-
-
-Import required libraries from thirdweb.
-
-```jsx
-import {
- createThirdwebClient,
- prepareTransaction,
- sendTransaction,
- privateKeyToAccount,
-} from "thirdweb";
-```
-
-
-
-This function processes the API's response and executes blockchain transactions.
-
-```jsx
-import { generateAccount } from "thirdweb/wallets";
-
-async function handleNebulaResponse(response) {
- const client = createThirdwebClient({
- secretKey: process.env.THIRDWEB_SECRET_KEY,
- });
-
- // You can use any wallet- see https://portal.thirdweb.com/wallets/external-wallets
- const account = await generateAccount({ client });
-
- if (response.actions && response.actions.length > 0) {
- const action = response.actions[0];
- const txData = JSON.parse(action.data);
-
- try {
- const transaction = prepareTransaction({
- to: txData.to,
- data: txData.data,
- value: BigInt(txData.value),
- chain: txData.chainId,
- client,
- });
-
- const result = await sendTransaction({
- transaction,
- account,
- });
-
- console.log("Transaction Successful:", result);
- return result;
- } catch (error) {
- console.error("Error executing transaction:", error);
- throw error;
- }
- }
-}
-```
-
-
-
-
-Send a request to the Nebula API to interpret your natural language command and retrieve the transaction details.
-
-```jsx
-const response = await fetch("https://nebula-api.thirdweb.com/chat", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- "x-secret-key": process.env.THIRDWEB_SECRET_KEY,
- },
- body: JSON.stringify({
- message: "send 0.001 ETH on Sepolia to vitalik.eth",
- execute_config: {
- mode: "client",
- signer_wallet_address: "0xYourWalletAddress",
- },
- }),
-});
-
-const data = await response.json();
-await handleNebulaResponse(data);
-```
-
-
-
-
-The response from the API will contain the transaction details.
-
-```jsx
-Transaction Successful: {
- transactionHash: "0x123abc...",
- blockNumber: 1234567,
- ...
-}
-```
-
-
-Congratulations! You have successfully set up the Nebula API and executed a transaction using the thirdweb SDK.
-
-
-### Additional Resources
-
-- [Nebula API Documentation](https://portal.thirdweb.com/nebula/api-reference)
-- [thirdweb SDK Documentation](https://portal.thirdweb.com/typescript/v5)
diff --git a/apps/portal/src/app/nebula/key-concepts/chat-execute/page.mdx b/apps/portal/src/app/nebula/key-concepts/chat-execute/page.mdx
deleted file mode 100644
index 29f6750fd0b..00000000000
--- a/apps/portal/src/app/nebula/key-concepts/chat-execute/page.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-# Chat & Execute endpoints
-
-The `/chat` endpoint is used for **natural language interactions** with the AI. It allows users to ask questions, get explanations, or retrieve blockchain-related insights, and execute transactions.
-
-The `/execute` endpoint is used for **triggering actual blockchain transactions** through AI-generated execution logic. This endpoint **performs actions** on-chain and is designed to be used without historical context.
diff --git a/apps/portal/src/app/nebula/key-concepts/context-filters/page.mdx b/apps/portal/src/app/nebula/key-concepts/context-filters/page.mdx
deleted file mode 100644
index 8a1f8adec1f..00000000000
--- a/apps/portal/src/app/nebula/key-concepts/context-filters/page.mdx
+++ /dev/null
@@ -1,24 +0,0 @@
-# Context Filters
-
-Context filters help control what blockchain data the AI uses to generate responses.
-
-You can specify:
-
-- Chain IDs – Choose which blockchain networks to pull data from.
-- Wallet Address – Focus on a specific wallet’s transactions, balances, and interactions.
-
-Benefits:
-
-- **More relevant answers:** AI focuses only on the data you care about.
-- **Enable Scope**: Keep results relevant to networks and wallets specified.
-
-Example,
-
-```jsx
-{
- "context": {
- "chain_ids": ["1"], // Ethereum network
- "wallet_address": "0x123...abc" // Specific wallet to analyze
- }
-}
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/key-concepts/execute-configuration/page.mdx b/apps/portal/src/app/nebula/key-concepts/execute-configuration/page.mdx
deleted file mode 100644
index 1ad3106f765..00000000000
--- a/apps/portal/src/app/nebula/key-concepts/execute-configuration/page.mdx
+++ /dev/null
@@ -1,19 +0,0 @@
-# Execute Configuration
-
-Configure transaction execution behavior using the execute config:
-
-```json
-{
- "execute_config": {
- "mode": "client",
- "signer_wallet_address": "0x..."
- }
-}
-```
-
-Parameters:
-
-- `mode`: Execution mode (currently supports "client")
-- `signer_wallet_address`: Wallet address for transaction signing
-
-When mode is "client", Nebula returns an unsigned transaction for local wallet signing.
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/key-concepts/response-handling/page.mdx b/apps/portal/src/app/nebula/key-concepts/response-handling/page.mdx
deleted file mode 100644
index 383a5019270..00000000000
--- a/apps/portal/src/app/nebula/key-concepts/response-handling/page.mdx
+++ /dev/null
@@ -1,134 +0,0 @@
-import { DocImage } from '@doc';
-import StreamedResponse from "../../assets/streamed-response.png";
-
-# Response Handling
-
-## Streamed vs non-streamed responses
-
-- **Streaming Responses**: This method streams data in real-time, providing immediate feedback as the response is generated. Set the `stream` parameter to `true` in your request, the API delivers responses via Server-Sent Events (SSE).
-- **Non-Streaming Responses**: When the `stream` parameter is set to `false`, the API returns the complete response in a single JSON payload after processing is complete.
-
-
-
-For `stream:true`, you'll need to handle the following event types:
-
-- `init`: Initializes the stream and provides session information
-- `presence`: Provides backend status updates about worker processing
-- `action`: Contains blockchain transaction or action data
-- `delta`: Contains chunks of the response message text
-- `error`: Contains error information if something goes wrong
-
-
-**Example SSE Stream:**
-
-```jsx
-event: init
-data: {
- "session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
- "request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
- "type": "init",
- "source": "user",
- "data": ""
-}
-
-event: presence
-data: {
- "session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
- "request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
- "type": "presence",
- "source": "executor",
- "data": "Performing function execution: ExecuteNativeTransferClientSigning"
-}
-
-event: action
-data: {
- "session_id": "f4b45429-9570-4ee8-8c8f-8b267429915a",
- "request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
- "type": "sign_transaction",
- "source": "executor",
- "data": "{\"chainId\": 11155111, \"to\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\", \"data\": \"0x\", \"value\": \"0x5af3107a4000\"}"
-}
-
-event: delta
-data: {"v": "To send 0.0001 ETH on the Sepolia network"}
-
-event: delta
-data: {"v": " to the address associated with"}
-```
-**JavaScript Example for handling streams:**
-
-```jsx
-const eventSource = new EventSource("/chat", {
- headers: {
- "x-secret-key": "YOUR_THIRDWEB_SECRET_KEY",
- },
-});
-
-let messageText = "";
-
-eventSource.addEventListener("init", (event) => {
- const data = JSON.parse(event.data);
- console.log("Stream initialized:", data);
-});
-
-eventSource.addEventListener("presence", (event) => {
- const data = JSON.parse(event.data);
- console.log("Backend status:", data.data);
-});
-
-eventSource.addEventListener("action", (event) => {
- const data = JSON.parse(event.data);
- console.log("Received action:", data);
- if (data.type === "sign_transaction") {
- // Handle transaction signing
- handleTransaction(data);
- }
-});
-
-eventSource.addEventListener("delta", (event) => {
- const data = JSON.parse(event.data);
- messageText += data.v;
- console.log("Current message:", messageText);
-});
-
-eventSource.addEventListener("error", (event) => {
- const error = JSON.parse(event.data);
- console.error("Error:", error);
- eventSource.close();
-});
-```
-## Response Format
-
-By default, responses are returned as JSON Objects. You may optionally specify the desired response format using the `response_format` parameter.
-
-- **JSON Object**: To receive the response as a JSON object, set `response_format` to `{ "type": "json_object" }`.
-- **JSON Schema**: For responses adhering to a specific JSON schema, set `response_format` to `{ "type": "json_schema", "json_schema": { ... } }`, where you define the desired schema structure.
-
-Example with `json_schema` format,
-
-```jsx
-curl -X POST https://nebula-api.thirdweb.com/chat \
--H "Content-Type: application/json" \
--H "x-secret-key: ...." \
--d '{
- "message": "what is the balance of eimanabdel.eth on contract 0xddC761FEb956Caf62dfa1c8b42e9f33Df424715A on sepolia",
- "stream": false,
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "type": "object",
- "properties": {
- "ens_name": {
- "type": "string",
- "description": "The ENS name being queried"
- },
- "balance": {
- "type": "integer",
- "description": "The balance of the address on the specified contract"
- }
- },
- "required": ["ens_name", "balance"]
- }
- }
-}'
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/key-concepts/sessions/page.mdx b/apps/portal/src/app/nebula/key-concepts/sessions/page.mdx
deleted file mode 100644
index 0423b988301..00000000000
--- a/apps/portal/src/app/nebula/key-concepts/sessions/page.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
-
-# Sessions
-
-Sessions are a way to maintain context across multiple interactions with a user. Since LLMs are stateless by default, sessions help simulate continuity.
-
-- Sessions are created automatically when calling `/chat` without a `session_id` or can be created explicitly by calling the `/session` endpoint.
-- Sessions can be managed through the following endpoints:
- - [Create Session](/nebula/api-reference/create-session)
- - [Get Session](/nebula/api-reference/get-session)
- - [Clear Session](/nebula/api-reference/clear-session)
- - [Update Session](/nebula/api-reference/update-session)
- - [Delete Session](/nebula/api-reference/delete-session)
- - [List Sessions](/nebula/api-reference/list-sessions)
-
-- Sessions persist your conversation history, custom configurations for blockchain data, and thirdweb tools interactions.
diff --git a/apps/portal/src/app/nebula/layout.tsx b/apps/portal/src/app/nebula/layout.tsx
deleted file mode 100644
index bdc827a9ce4..00000000000
--- a/apps/portal/src/app/nebula/layout.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createMetadata } from "@doc";
-import { DocLayout } from "@/components/Layouts/DocLayout";
-import { sidebar } from "./sidebar";
-
-export default async function Layout(props: { children: React.ReactNode }) {
- return (
-
- {props.children}
-
- );
-}
-
-export const metadata = createMetadata({
- description:
- "thirdweb Nebula Docs : explore the Nebula API Reference and unlock the most powerful AI to interact with the blockchain yet.",
- image: {
- icon: "nebula",
- title: "Nebula Docs",
- },
- title: "thirdweb Nebula Documentation",
-});
diff --git a/apps/portal/src/app/nebula/mcp-server/get-started/page.mdx b/apps/portal/src/app/nebula/mcp-server/get-started/page.mdx
deleted file mode 100644
index 198afeb9a38..00000000000
--- a/apps/portal/src/app/nebula/mcp-server/get-started/page.mdx
+++ /dev/null
@@ -1,93 +0,0 @@
-import { OpenSourceCard, Callout } from "@doc";
-
-# Get Started
-
-Learn how to get started with the thirdweb MCP server.
-
-### Prerequisites
-
-- Python 3.10 or higher
-- uv
-
-### Run with uvx
-```bash
-THIRDWEB_SECRET_KEY=... \
- uvx thirdweb-mcp
-```
-
-### Install and run with pipx
-
-```bash
-pipx install thirdweb-mcp
-
-THIRDWEB_SECRET_KEY=... \
- thirdweb-mcp
-```
-
-### Install from source
-
-```bash
-git clone https://github.com/thirdweb-dev/ai.git thirdweb-ai
-cd thirdweb-ai/python/thirdweb-mcp
-uv sync
-```
-
-## Configuration
-
-The thirdweb MCP server requires configuration based on which services you want to enable:
-
-1. **thirdweb Secret Key**: Required for Nebula and Insight services. Obtain from the [thirdweb dashboard](https://thirdweb.com/dashboard).
-2. **Chain IDs**: Blockchain network IDs to connect to (e.g., 1 for Ethereum mainnet, 137 for Polygon).
-3. **Engine Configuration**: If using the Engine service, you'll need the Engine URL and authentication JWT.
-
-You can provide these through command-line options or environment variables.
-
-## Usage
-
-### Command-line options
-
-```bash
-# Basic usage with default settings (stdio transport with Nebula and Insight)
-THIRDWEB_SECRET_KEY=... thirdweb-mcp
-
-# Using SSE transport on a custom port
-THIRDWEB_SECRET_KEY=... thirdweb-mcp --transport sse --port 8080
-
-# Enabling all services with specific chain IDs
-THIRDWEB_SECRET_KEY=... thirdweb-mcp --chain-id 1 --chain-id 137 \
- --engine-url YOUR_ENGINE_URL \
- --engine-auth-jwt YOUR_ENGINE_JWT \
- --engine-backend-wallet-address YOUR_ENGINE_BACKEND_WALLET_ADDRESS
-```
-
-### Environment variables
-
-You can also configure the MCP server using environment variables:
-
-- `THIRDWEB_SECRET_KEY`: Your thirdweb API secret key
-- `THIRDWEB_ENGINE_URL`: URL endpoint for thirdweb Engine service
-- `THIRDWEB_ENGINE_AUTH_JWT`: Authentication JWT token for Engine
-- `THIRDWEB_ENGINE_BACKEND_WALLET_ADDRESS`: Wallet address for Engine backend
-
-## Available Services
-
-### Nebula
-
-Autonomous onchain execution and analysis:
-- Analyze smart contract code
-- Contract interactions and deployments
-- Autonomous onchain tasks execution
-
-### Insight
-
-Offers blockchain data analysis capabilities:
-- Query on-chain data across multiple networks
-- Analyze transactions, blocks, and smart contract events
-- Monitor wallet activities and token movements
-
-### Engine
-
-Integrates with thirdweb's backend infrastructure:
-- Deploy smart contracts
-- Interact with deployed contracts
-- Manage wallet connections and transactions
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/mcp-server/integrations/claude-desktop/page.mdx b/apps/portal/src/app/nebula/mcp-server/integrations/claude-desktop/page.mdx
deleted file mode 100644
index 580a3745ec2..00000000000
--- a/apps/portal/src/app/nebula/mcp-server/integrations/claude-desktop/page.mdx
+++ /dev/null
@@ -1,31 +0,0 @@
-# Claude Desktop
-
-Learn how to add the MCP server to Claude Desktop:
-
-1. Install the MCP: `pipx install thirdweb-mcp`
-
-2. Create or edit the Claude Desktop configuration file at:
- - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- - Linux: `~/.config/Claude/claude_desktop_config.json`
-
-3. Add the following configuration:
-
- ```json
- {
- "mcpServers": {
- "thirdweb-mcp": {
- "command": "thirdweb-mcp",
- "args": [], // add `--chain-id` optionally
- "env": {
- "THIRDWEB_SECRET_KEY": "your thirdweb secret key from dashboard",
- "THIRDWEB_ENGINE_URL": "(OPTIONAL) your engine url",
- "THIRDWEB_ENGINE_AUTH_JWT": "(OPTIONAL) your engine auth jwt",
- "THIRDWEB_ENGINE_BACKEND_WALLET_ADDRESS": "(OPTIONAL) your engine backend wallet address",
- },
- }
- }
- }
- ```
-
-4. Restart Claude Desktop for the changes to take effect.
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/mcp-server/integrations/mcp-clients/page.mdx b/apps/portal/src/app/nebula/mcp-server/integrations/mcp-clients/page.mdx
deleted file mode 100644
index 682b378ed7a..00000000000
--- a/apps/portal/src/app/nebula/mcp-server/integrations/mcp-clients/page.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
-
-### MCP Clients
-
-Learn how to integrate the thirdweb MCP server with various clients.
-
-This server can be integrated with any client that supports the Model Context Protocol:
-
-1. Run the MCP server with the appropriate configuration
-2. Connect your MCP client to the server using the selected transport (stdio or SSE)
-3. Access thirdweb services through the exposed MCP tools
-
-
-#### References
-
-[thirdweb-mcp references](https://github.com/thirdweb-dev/ai/tree/main/python/thirdweb-mcp)
diff --git a/apps/portal/src/app/nebula/page.mdx b/apps/portal/src/app/nebula/page.mdx
deleted file mode 100644
index 490248446ca..00000000000
--- a/apps/portal/src/app/nebula/page.mdx
+++ /dev/null
@@ -1,100 +0,0 @@
-import { WalletIcon, FileIcon, MessageCircleIcon, BracesIcon, BotIcon, BlocksIcon } from "lucide-react";
-import { DocImage, createMetadata, FeatureCard, GithubTemplateCard, Stack, Grid, ArticleCard, ArticleIconCard } from "@doc";
-import NebulaDiagram from "./assets/nebula-diagram.png";
-import SupportedChains from "../_images/supported-chains.png";
-import { ExternalLink } from "lucide-react";
-
-export const metadata = createMetadata({
- image: {
- title: "Nebula Documentation",
- icon: "nebula",
- },
- title: "thirdweb Nebula Documentation",
- description:
- "thirdweb Nebula Docs : explore the Nebula API Reference and unlock the most powerful AI to interact with the blockchain & build AI powered web3 apps.",
-});
-
-# Nebula
-
-Nebula is a natural language model with improved blockchain reasoning, autonomous transaction capabilities, and real-time access to the blockchain. [Learn more about Nebula.](https://blog.thirdweb.com/introducing-nebula-a-powerful-blockchain-model-to-read-write-and-reason-onchain/)
-
-Nebula is currently live in Beta.
-
-
-
-
-
-## Nebula API
-
-
-
-## Features
-
-
- }
- />
-
- }
- />
-
- }
- />
-
- }
- />
-
-
-## Video Tutorials
-
-
-
-
-
-
-
-
-
-## Templates
-
-
-
-
-
-
-
-
-
-## Supported Chains
-Nebula is supported on every EVM compatible chain. To view the full list, visit [thirdweb chainlist](https://thirdweb.com/chainlist?service=nebula).
-
-
-
-
-
-
diff --git a/apps/portal/src/app/nebula/plugins/eliza/page.mdx b/apps/portal/src/app/nebula/plugins/eliza/page.mdx
deleted file mode 100644
index b883d6cf63e..00000000000
--- a/apps/portal/src/app/nebula/plugins/eliza/page.mdx
+++ /dev/null
@@ -1,106 +0,0 @@
-import { Callout, OpenSourceCard, Step, Steps, DocImage, createMetadata } from '@doc'
-import NewProject from "../../assets/new-project.png";
-import KeysSetup from "../../assets/keys.png";
-
-export const metadata = createMetadata({
- image: {
- title: "Eliza x Nebula",
- icon: "nebula",
- },
- title: "Integrate ElizaOS x thirdweb Nebula",
- description:
- "Learn about how you can unlock advanced AI capabilities for your app with thirdweb Nebula and Eliza Integration.",
-});
-
-# Eliza
-
-Eliza is a simple, fast, and lightweight AI agent framework to build flexible, scalable, and secure conversational agents.
-
-With the thirdweb plugin, you can easily integrate Nebula into an AI agent built with Eliza to provide increasingly accurate read, write, and reasoning capabilities to blockchain-related prompts:
-
-
-
-
-## Prerequisites
-
-- Create a thirdweb account
-- Node.js 23+ and pnpm 9+ installed
-
-## Obtain Client ID & Secret Key
-
-
-
-
-
-Navigate to the [projects dashboard](https://thirdweb.com/) and create a new project.
-
-
-
-
-
-
-
-Setup your project and obtain your client ID and secret key. Please note your secret key somewhere safe as it is not recoverable.
-
-
-Client Id is used for client side usage and is restricted by the domain restrictions you set on your API key, it is a public identifier which can be used on the frontend safely.
-
-Secret key is used for server side or script usage and is not restricted by the domain restrictions. Never expose your secret key in client side code.
-
-
-
-
-
-
-
-
-## Setup Eliza Starter
-
-If you have not created a project with Eliza, it is recommended to start with the Eliza Starter repository:
-
-
-
-
-The Nebula plugin is only available on version 0.1.8 of Eliza and above and is available by default.
-
-
-Clone the starter repository
-
-```bash
-git clone https://github.com/elizaos/eliza-starter.git
-```
-
-
-
-Create a .env file and add your secret key and any other environmental variables:
-
-```bash
-THIRDWEB_SECRET_KEY=your_secret_key
-```
-
-
-Client Id is used for client side usage and is restricted by the domain restrictions you set on your API key, it is a public identifier which can be used on the frontend safely.
-
-Secret key is used for server side or script usage and is not restricted by the domain restrictions. Never expose your secret key in client side code.
-
-
-
-
-```bash
-pnpm i
-```
-
-
-
-```bash
-pnpm start
-```
-
-
-
-
-### Additional Resources
-
-- [Eliza Documentation](https://elizaos.github.io/eliza/)
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/plugins/openai/page.mdx b/apps/portal/src/app/nebula/plugins/openai/page.mdx
deleted file mode 100644
index 86c087952cd..00000000000
--- a/apps/portal/src/app/nebula/plugins/openai/page.mdx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- image: {
- title: "OpenAI x Nebula",
- icon: "nebula",
- },
- title: "Integrate OpenAI x thirdweb Nebula",
- description:
- "Learn about how you can unlock advanced AI capabilities for your app with thirdweb Nebula and OpenAI integration.",
-});
-
-# OpenAI
-
-### Chat Completions API
-
-Compatible with OpenAI’s Chat Completion API to process chat history and generate context-aware responses.
-
-```python
-from openai import OpenAI
-
-client = OpenAI(
- base_url="https://nebula-api.thirdweb.com",
- api_key="{{THIRDWEB_SECRET_KEY}}",
-)
-chat_completion = client.chat.completions.create(
- model="t0",
- messages=[{"role": "user", "content": "Hello Nebula!"}],
- stream=False,
- extra_body={ "context": { "wallet_address": "0x..." }}
-)
-
-print(chat_completion)
-```
-
-### Models API
-
-Compatible with OpenAI’s Models API to list out models used.
-
-```python
-from openai import OpenAI
-
-# https://nebula-api.thirdweb.com/models
-
-client = OpenAI(
- base_url="https://nebula-api.thirdweb.com/",
- api_key="",
-)
-
-models = client.models.list()
-print(models)
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/plugins/page.mdx b/apps/portal/src/app/nebula/plugins/page.mdx
deleted file mode 100644
index e2b30ec2dfc..00000000000
--- a/apps/portal/src/app/nebula/plugins/page.mdx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { createMetadata } from "@doc";
-
-export const metadata = createMetadata({
- image: {
- title: "Plugins & Integrations",
- icon: "nebula",
- },
- title: "thirdweb Nebula Compatible AI Plugins",
- description:
- "Learn about AI plugins supported by thirdweb Nebula, such as OpenAI & Eliza.",
-});
-
-import { Callout } from '@doc'
-
-# Plugins
-
-- [OpenAI](/nebula/plugins/openai)
-- [Eliza](/nebula/plugins/eliza)
-
-We are actively adding more integrations, for any specific requests please [contact us](https://thirdweb.com/contact).
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/prompt-guide/page.mdx b/apps/portal/src/app/nebula/prompt-guide/page.mdx
deleted file mode 100644
index c93e4a6a47d..00000000000
--- a/apps/portal/src/app/nebula/prompt-guide/page.mdx
+++ /dev/null
@@ -1,28 +0,0 @@
-import {createMetadata} from "@doc";
-
-export const metadata = createMetadata({
- image: {
- title: "Prompt Guide",
- icon: "nebula",
- },
- title: "thirdweb Nebula Prompt Guide",
- description:
- "A comprehensive prompt guide to help you unlock the most powerful AI to interact with the blockchain & build AI powered web3 apps.",
-});
-
-# Prompt Guide
-
-Maximize the potential of Nebula. Whether you’re new to blockchain development or an experienced user, this document will help you craft prompts that fully leverage Nebula’s blockchain specific features.
-
-### Supported Actions
-
-| **Action** | **Description** | **Examples** |
-|-----------------------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Bridge & Swap** | Bridge and swap native currencies | • "Swap 1 USDC to 1 USDT on the Ethereum Mainnet"
• "Bridge 0.5 ETH from Ethereum Mainnet to Polygon"
|
-| **Transfer** | Send native and ERC-20 currencies | • "Send 0.1 ETH to vitalik.eth"
• "Transfer 1 USDC to saminacodes.eth on Base"
|
-| **Deploy** | Deploy published contracts | • "Deploy a Token ERC20 Contract with name "Hello World" and description "My Hello Contract" on Ethereum."
• "Deploy a Split contract with two recipients."
• "Deploy an ERC1155 Contract named 'Hello World' with description 'Hello badges on Ethereum'"
|
-| **Understand** | Retrieve information about smart contracts. | • "What ERC standards are implemented by contract address 0x59325733eb952a92e069C87F0A6168b29E80627f on Ethereum?"
• "What functions can I use to mint more of my contract's NFTs?"
• "What is the total supply of NFTs on 0x8a90CAb2b38dba80c64b7734e58Ee1dB38B8992e?" |
-| **Interact** | Query wallet balances, addresses, and token holdings. | • "How much ETH is in my wallet?"
• "What is the wallet address of vitalik.eth?"
• "Does my wallet hold USDC on Base?" |
-| **Explore** | Access blockchain-specific data. | • "What is the last block on zkSync?"
• "What is the current gas price on Avalanche C-Chain?"
• "Can you show me transaction details for 0xdfc450bb39e44bd37c22e0bfd0e5212edbea571e4e534d87b5cbbf06f10b9e04 on Optimism?" |
-| **Research** | Obtain details about tokens, their addresses, and current prices. | • "What is the address of USDC on Ethereum?"
• "Is there a UNI token on Arbitrum?"
• "What is the current price of ARB?" |
-| **Build** | Implement features using Web3 SDKs and tools. | • "How can I add a connect wallet button to my web app? I want to support users connecting with both email/social wallets and MetaMask and use smart wallets."
• "Can you show me how to claim an NFT from an ERC721 using TypeScript?"
• "I have an ERC1155 contract from thirdweb. Can you show me how to generate and mint with a signature?" |
diff --git a/apps/portal/src/app/nebula/sidebar.tsx b/apps/portal/src/app/nebula/sidebar.tsx
deleted file mode 100644
index 149566ffd1d..00000000000
--- a/apps/portal/src/app/nebula/sidebar.tsx
+++ /dev/null
@@ -1,215 +0,0 @@
-import {
- BlocksIcon,
- BracesIcon,
- CodeIcon,
- ExternalLinkIcon,
- KeyIcon,
- MessageCircleQuestionIcon,
- PencilRulerIcon,
- RocketIcon,
- WorkflowIcon,
- WrenchIcon,
-} from "lucide-react";
-import type { SideBar } from "@/components/Layouts/DocLayout";
-import { NebulaSideIcon, TypeScriptIcon, UnityIcon } from "@/icons";
-
-export const sidebar: SideBar = {
- links: [
- {
- href: "/nebula",
- icon: ,
- name: "Overview",
- },
- {
- href: "/nebula/prompt-guide",
- icon: ,
- name: "Prompt Guide",
- },
- {
- href: "https://nebula.thirdweb.com",
- icon: ,
- name: "Playground",
- },
- {
- separator: true,
- },
- {
- isCollapsible: false,
- links: [
- {
- href: "/nebula/get-started",
- icon: ,
- name: "Get Started",
- },
- {
- icon: ,
- links: [
- {
- href: "/nebula/key-concepts/chat-execute",
- name: "Chat & Execute",
- },
- {
- href: "/nebula/key-concepts/context-filters",
- name: "Context Filters",
- },
- {
- href: "/nebula/key-concepts/execute-configuration",
- name: "Execute Config",
- },
- {
- href: "/nebula/key-concepts/response-handling",
- name: "Response Handling",
- },
- {
- href: "/nebula/key-concepts/sessions",
- name: "Sessions",
- },
- ],
- name: "Key Concepts",
- },
- {
- href: "/nebula/api-reference",
- icon: ,
- links: [
- {
- expanded: true,
- links: [
- {
- href: "/nebula/api-reference/chat",
- name: "Send Message",
- },
- {
- href: "/nebula/api-reference/execute",
- name: "Execute Action",
- },
- ],
- name: "Chat",
- },
- {
- expanded: true,
- links: [
- {
- href: "/nebula/api-reference/list-session",
- name: "List Sessions",
- },
- {
- href: "/nebula/api-reference/get-session",
- name: "Get Session",
- },
- {
- href: "/nebula/api-reference/create-session",
- name: "Create Session",
- },
- {
- href: "/nebula/api-reference/update-session",
- name: "Update Session",
- },
- {
- href: "/nebula/api-reference/clear-session",
- name: "Clear Session",
- },
- {
- href: "/nebula/api-reference/delete-session",
- name: "Delete Session",
- },
- ],
- name: "Session",
- },
- ],
- name: "API Reference",
- },
- {
- icon: ,
- links: [
- {
- href: "/references/typescript/v5/chat",
- icon: ,
- name: "Typescript",
- },
- {
- href: "/dotnet/nebula/quickstart",
- icon: ,
- name: "Unity",
- },
- ],
- name: "SDK Reference",
- },
- {
- href: "/nebula/plugins",
- icon: ,
- links: [
- {
- href: "/nebula/plugins/openai",
- name: "OpenAI",
- },
- {
- href: "/nebula/plugins/eliza",
- name: "Eliza",
- },
- ],
- name: "Plugins & Integrations",
- },
- ],
- name: "Nebula (API)",
- },
- {
- isCollapsible: false,
- links: [
- {
- href: "/nebula/mcp-server/get-started",
- icon: ,
- name: "Get Started",
- },
- {
- icon: ,
- links: [
- {
- href: "/nebula/mcp-server/integrations/claude-desktop",
- name: "Claude Desktop",
- },
- {
- href: "/nebula/mcp-server/integrations/mcp-clients",
- name: "MCP Clients",
- },
- ],
- name: "Integrations",
- },
- ],
- name: "MCP Server",
- },
- {
- isCollapsible: false,
- links: [
- {
- icon: ,
- links: [
- {
- href: "/nebula/tools/python-sdk/installation",
- name: "Installation",
- },
- {
- href: "https://github.com/thirdweb-dev/ai/tree/main/python/examples",
- name: "Examples",
- },
- ],
- name: "Python SDK",
- },
- ],
- name: "Tools",
- },
- {
- separator: true,
- },
- {
- href: "/nebula/troubleshoot",
- icon: ,
- name: "Troubleshoot",
- },
- {
- href: "/nebula/faqs",
- icon: ,
- name: "FAQs",
- },
- ],
- name: "AI",
-};
diff --git a/apps/portal/src/app/nebula/tools/page.mdx b/apps/portal/src/app/nebula/tools/page.mdx
deleted file mode 100644
index 4026317a86c..00000000000
--- a/apps/portal/src/app/nebula/tools/page.mdx
+++ /dev/null
@@ -1,2 +0,0 @@
-# Installation
-
diff --git a/apps/portal/src/app/nebula/tools/python-sdk/installation/page.mdx b/apps/portal/src/app/nebula/tools/python-sdk/installation/page.mdx
deleted file mode 100644
index c4448a8e40c..00000000000
--- a/apps/portal/src/app/nebula/tools/python-sdk/installation/page.mdx
+++ /dev/null
@@ -1,50 +0,0 @@
-# Python SDK
-
-#### Installation
-
-```bash
-# Install core package with all framework adapters
-pip install "thirdweb-ai[all]"
-
-# Or install with specific framework adapters
-pip install "thirdweb-ai[openai]" # For OpenAI Agents
-pip install "thirdweb-ai[langchain]" # For LangChain
-pip install "thirdweb-ai[agentkit]" # For Coinbase Agentkit
-pip install "thirdweb-ai[goat]" # For GOAT SDK
-# ... many more framework supported
-```
-
-See the list of [supported framework and installation guides](python/thirdweb-ai#install-with-framework-specific-adapters)
-
-#### Basic Usage
-
-```python
-from thirdweb_ai import Engine, Insight, Nebula, Tool
-
-# Initialize services
-insight = Insight(secret_key=...)
-nebula = Nebula(secret_key=...)
-engine = Engine(...)
-
-# Example: Create tools for AI agents
-tools = [
- *insight.get_tools(),
- *nebula.get_tools(),
- *engine.get_tools(),
- # Or pick an individual tool from the services
-]
-
-# Example: Framework integration (LangChain)
-from thirdweb_ai.adapters.langchain import get_langchain_tools
-langchain_tools = get_langchain_tools(tools)
-agent = create_tool_calling_agent(tools=langchain_tools, ...)
-
-# Example: Framework integration (OpenAI Agents)
-from thirdweb_ai.adapters.openai import get_openai_tools
-openai_tools = get_openai_tools(tools)
-agent = Agent(name="thirdweb Assistant", tools=tools)
-
-# see python/examples for other framework integration
-```
-
-More [information](python/thirdweb-ai)
\ No newline at end of file
diff --git a/apps/portal/src/app/nebula/troubleshoot/page.mdx b/apps/portal/src/app/nebula/troubleshoot/page.mdx
deleted file mode 100644
index d90e588cd40..00000000000
--- a/apps/portal/src/app/nebula/troubleshoot/page.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-# Nebula Troubleshoot Guide
-
-For any issues you encounter while using Nebula, please [visit our support site](https://thirdweb.com/support).
\ No newline at end of file
diff --git a/apps/portal/src/app/page.tsx b/apps/portal/src/app/page.tsx
index 7f3bcda131e..b66c56bd345 100644
--- a/apps/portal/src/app/page.tsx
+++ b/apps/portal/src/app/page.tsx
@@ -1,15 +1,13 @@
import {
+ ArchiveIcon,
ArrowUpRightIcon,
- BotIcon,
+ BrainIcon,
CoinsIcon,
- MessageCircleIcon,
- WebhookIcon,
ZapIcon,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
import { Heading } from "@/components/Document";
-import { PaymentsIcon } from "@/icons/products/PaymentsIcon";
import { ChatButton } from "../components/AI/chat-button";
import { Button } from "../components/ui/button";
import {
@@ -21,19 +19,20 @@ import {
UnrealEngineIcon,
} from "../icons";
import { ConnectIcon } from "../icons/products/ConnectIcon";
-import { EngineIcon } from "../icons/products/EngineIcon";
-import { InsightIcon } from "../icons/products/InsightIcon";
import DocsHeroDark from "./_images/docs-hero-dark.png";
import DocsHeroLight from "./_images/docs-hero-light.png";
export default function Page() {
return (
-
+
);
@@ -76,28 +75,38 @@ function Hero() {
);
}
-function AISection() {
+function ArchiveSection() {
return (
@@ -106,63 +115,33 @@ function AISection() {
function ReferenceSection() {
return (
- <>
-
-
-
- >
+
);
}
@@ -172,46 +151,40 @@ function LearningResourcesSection() {
diff --git a/apps/portal/src/app/payments/sidebar.tsx b/apps/portal/src/app/payments/sidebar.tsx
index 2e4869cf48d..2abe51a01cb 100644
--- a/apps/portal/src/app/payments/sidebar.tsx
+++ b/apps/portal/src/app/payments/sidebar.tsx
@@ -65,9 +65,9 @@ export const sidebar: SideBar = {
isCollapsible: false,
links: [
{
- href: `https://payments.thirdweb.com/reference`,
+ href: `/reference`,
icon: ,
- name: "REST API",
+ name: "HTTP API",
},
{
href: "/references/typescript/v5",
diff --git a/apps/portal/src/app/tokens/faq/page.mdx b/apps/portal/src/app/tokens/faq/page.mdx
index a8299efd341..8297a23f531 100644
--- a/apps/portal/src/app/tokens/faq/page.mdx
+++ b/apps/portal/src/app/tokens/faq/page.mdx
@@ -19,4 +19,23 @@ Tokens has:
- Ability to airdrop tokens directly through the token creation flow
- Ability to create liquidity pools for your token (coming soon)
- An included listing page to share your token to users for purchasing
+
+
+
+Yes, please see the [security](/tokens/security) section for a link to the audit reports.
+
+
+
+ERC-721 tokens represent unique, one-of-a-kind assets where each token has its own ID and metadata (like an NFT artwork). ERC-1155 tokens are more flexible, allowing both unique (non-fungible) and identical (fungible) assets to exist under one smart contract. This is ideal for gaming items or collections with multiple editions.
+
+
+
+You can call the `renounceOwnership` function on your asset contract (e.g., via a block explorer).
+
+- _Native token value to enter:_ `0`
+- _Note:_ Renouncing ownership is irreversible and means you will no longer be able to update the contract or its metadata.
+
+
+
+After renouncing ownership, you lose all admin privileges, including the ability to update token metadata or manage contract settings.
\ No newline at end of file
diff --git a/apps/portal/src/app/tokens/liquidity-options/page.mdx b/apps/portal/src/app/tokens/liquidity-options/page.mdx
new file mode 100644
index 00000000000..ca9969f9fb5
--- /dev/null
+++ b/apps/portal/src/app/tokens/liquidity-options/page.mdx
@@ -0,0 +1,25 @@
+
+# Token Liquidity Options
+
+When creating an ERC-20 token with thirdweb, you have a few options for adding liquidity or pricing strategies to your token.
+Liquidity is essential for enabling trading on decentralized exchanges (DEXs) and ensuring that users can buy and sell your token easily.
+
+## Liquidity Options
+
+### Bonding Curve
+
+A bonding curve lets your token’s price automatically adjust based on supply. As more tokens get bought (supply goes down), the price goes up — and when tokens are sold (supply goes up), the price goes down.
+It’s great for tokens that want a built-in price mechanism without relying on traditional liquidity pools. Think of it as a self-balancing vending machine for your token.
+
+### Dynamic Bonding Curve (Coming Soon)
+
+This works like a regular bonding curve but gives you extra control over how the curve behaves. You can tweak parameters like slope, limits, and responsiveness to market activity.
+This option is perfect if you want your token to adapt to demand cycles, grow with your community, or react to specific economic conditions without manual intervention.
+
+### Fixed Price (Coming Soon)
+
+A fixed price means your token sells at one set amount until you change it. No fancy math, no curve — just a stable price.
+This is ideal for presales, early community distributions, or situations where you don’t want price volatility yet. Once you’re ready, you can later introduce more advanced pricing or liquidity mechanisms.
+
+
+
diff --git a/apps/portal/src/app/tokens/list-tokens/page.mdx b/apps/portal/src/app/tokens/list-tokens/page.mdx
deleted file mode 100644
index e63f82a910f..00000000000
--- a/apps/portal/src/app/tokens/list-tokens/page.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-# List Tokens
-
-Ability to list tokens is coming soon. If you are interested in this feature, please [reach out in our community Telegram](https://t.me/officialthirdweb) so we can notify you on release.
\ No newline at end of file
diff --git a/apps/portal/src/app/tokens/security/page.mdx b/apps/portal/src/app/tokens/security/page.mdx
new file mode 100644
index 00000000000..730ed6d3d38
--- /dev/null
+++ b/apps/portal/src/app/tokens/security/page.mdx
@@ -0,0 +1,5 @@
+# Security
+
+thirdweb has partnered with leading security firms to conduct audits of our smart contract codebase.
+
+All contracts including ERC-20, ERC-721, and ERC-1155 deployed through the Token dashboard or programmatically are audited. [View the full audit reports](https://github.com/thirdweb-dev/contracts/blob/main/audit-reports/audit-4.pdf)
\ No newline at end of file
diff --git a/apps/portal/src/app/tokens/sidebar.tsx b/apps/portal/src/app/tokens/sidebar.tsx
index 15df10750b1..d62645ba26c 100644
--- a/apps/portal/src/app/tokens/sidebar.tsx
+++ b/apps/portal/src/app/tokens/sidebar.tsx
@@ -1,14 +1,7 @@
-import { ZapIcon } from "lucide-react";
+import { ExternalLinkIcon, ZapIcon } from "lucide-react";
import type { SideBar } from "@/components/Layouts/DocLayout";
const slug = "/tokens";
-const prebuiltSlug = `${slug}/explore/pre-built-contracts`;
-const designDocs = `${slug}/design-docs`;
-
-// TODO: Deprecate links that start with the following slugs
-const buildSlug = `${slug}/build`;
-const extensionsSlug = `${slug}/build/extensions`;
-const baseContractsSlug = `${slug}/build/base-contracts`;
export const sidebar: SideBar = {
links: [
@@ -17,6 +10,11 @@ export const sidebar: SideBar = {
name: "Get Started",
icon: ,
},
+ {
+ href: "https://playground.thirdweb.com",
+ name: "Playground",
+ icon: ,
+ },
{ separator: true },
{
isCollapsible: false,
@@ -39,491 +37,22 @@ export const sidebar: SideBar = {
],
name: "Deploy Tokens",
},
- {
- href: `${slug}/list-tokens`,
- name: "List Tokens",
- },
],
name: "Guides",
},
-
- {
- isCollapsible: false,
- links: [
- {
- links: [
- {
- href: `${prebuiltSlug}/token`,
- name: "Token",
- },
- {
- href: `${prebuiltSlug}/token-drop`,
- name: "Token Drop",
- },
- {
- href: `${prebuiltSlug}/stake-erc20`,
- name: "Stake ERC-20",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc20`,
- name: "Airdrop ERC-20",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc20-claimable`,
- name: "Airdrop ERC-20 (Claimable)",
- },
- ],
- name: "ERC-20",
- },
- {
- links: [
- {
- href: `${prebuiltSlug}/nft-collection`,
- name: "NFT Collection",
- },
- {
- href: `${prebuiltSlug}/nft-drop`,
- name: "NFT Drop",
- },
- {
- href: `${prebuiltSlug}/loyalty-card`,
- name: "Loyalty Card",
- },
- {
- href: `${prebuiltSlug}/open-edition`,
- name: "Open Edition",
- },
- {
- href: `${prebuiltSlug}/stake-erc721`,
- name: "Stake ERC-721",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc721`,
- name: "Airdrop ERC-721",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc721-claimable`,
- name: "Airdrop ERC-721 (Claimable)",
- },
- ],
- name: "ERC-721",
- },
- {
- links: [
- {
- href: `${prebuiltSlug}/edition`,
- name: "Edition",
- },
- {
- href: `${prebuiltSlug}/edition-drop`,
- name: "Edition Drop",
- },
- {
- href: `${prebuiltSlug}/stake-erc1155`,
- name: "Stake ERC-1155",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc1155`,
- name: "Airdrop ERC-1155",
- },
- {
- href: `${prebuiltSlug}/airdrop-erc1155-claimable`,
- name: "Airdrop ERC-1155 (Claimable)",
- },
- ],
- name: "ERC-1155",
- },
- {
- links: [
- {
- href: `${prebuiltSlug}/marketplace`,
- name: "Marketplace",
- },
- {
- href: `${prebuiltSlug}/multiwrap`,
- name: "Multiwrap",
- },
- {
- href: `${prebuiltSlug}/split`,
- name: "Split",
- },
- {
- href: `${prebuiltSlug}/vote`,
- name: "Vote",
- },
- ],
- name: "MISC.",
- },
- ],
- name: "Pre-built Contracts",
- },
-
{ separator: true },
- // build
+ // resources
{
isCollapsible: false,
links: [
{
- href: `${buildSlug}/get-started`,
- name: "Get Started",
+ href: `${slug}/liquidity-options`,
+ name: "Liquidity Options",
},
- // base contracts
{
- href: `${baseContractsSlug}`,
- links: [
- {
- links: [
- {
- href: `${baseContractsSlug}/erc-20/base`,
- name: "Base",
- },
- {
- href: `${baseContractsSlug}/erc-20/drop`,
- name: "Drop",
- },
- {
- href: `${baseContractsSlug}/erc-20/drop-vote`,
- name: "Drop Vote",
- },
- {
- href: `${baseContractsSlug}/erc-20/signature-mint`,
- name: "Signature Mint",
- },
- {
- href: `${baseContractsSlug}/erc-20/signature-mint-vote`,
- name: "Signature Mint Vote",
- },
- {
- href: `${baseContractsSlug}/erc-20/vote`,
- name: "Vote",
- },
- ],
- name: "ERC-20",
- },
- {
- links: [
- {
- href: `${baseContractsSlug}/erc-721/base`,
- name: "Base",
- },
- {
- href: `${baseContractsSlug}/erc-721/delayed-reveal`,
- name: "Delayed Reveal",
- },
- {
- href: `${baseContractsSlug}/erc-721/drop`,
- name: "Drop",
- },
- {
- href: `${baseContractsSlug}/erc-721/lazy-mint`,
- name: "Lazy Mint",
- },
- {
- href: `${baseContractsSlug}/erc-721/signature-mint`,
- name: "Signature Mint",
- },
- ],
- name: "ERC-721",
- },
- {
- links: [
- {
- href: `${baseContractsSlug}/erc-1155/base`,
- name: "Base",
- },
- {
- href: `${baseContractsSlug}/erc-1155/delayed-reveal`,
- name: "Delayed Reveal",
- },
- {
- href: `${baseContractsSlug}/erc-1155/drop`,
- name: "Drop",
- },
- {
- href: `${baseContractsSlug}/erc-1155/lazy-mint`,
- name: "Lazy Mint",
- },
- {
- href: `${baseContractsSlug}/erc-1155/signature-mint`,
- name: "Signature Mint",
- },
- ],
- name: "ERC-1155",
- },
- {
- href: `${baseContractsSlug}/erc-4337`,
- links: [
- {
- href: `${baseContractsSlug}/erc-4337/account`,
- name: "Account",
- },
- {
- href: `${baseContractsSlug}/erc-4337/account-factory`,
- name: "Account Factory",
- },
- {
- href: `${baseContractsSlug}/erc-4337/managed-account`,
- name: "Managed Account",
- },
- {
- href: `${baseContractsSlug}/erc-4337/managed-account-factory`,
- name: "Managed Account Factory",
- },
- ],
- name: "ERC-4337",
- },
- ],
- name: "Base Contracts",
+ href: `${slug}/security`,
+ name: "Security",
},
- // extensions
- {
- href: `${extensionsSlug}`,
- links: [
- {
- links: [
- {
- href: `${extensionsSlug}/general/BatchMintMetadata`,
- name: "BatchMintMetadata",
- },
- {
- href: `${extensionsSlug}/general/ContractMetadata`,
- name: "ContractMetadata",
- },
- {
- href: `${extensionsSlug}/general/DelayedReveal`,
- name: "DelayedReveal",
- },
- {
- href: `${extensionsSlug}/general/Drop`,
- name: "Drop",
- },
- {
- href: `${extensionsSlug}/general/DropSinglePhase`,
- name: "DropSinglePhase",
- },
- {
- href: `${extensionsSlug}/general/LazyMint`,
- name: "LazyMint",
- },
- {
- href: `${extensionsSlug}/general/Multicall`,
- name: "Multicall",
- },
- {
- href: `${extensionsSlug}/general/Ownable`,
- name: "Ownable",
- },
- {
- href: `${extensionsSlug}/general/Permissions`,
- name: "Permissions",
- },
- {
- href: `${extensionsSlug}/general/PermissionsEnumerable`,
- name: "PermissionsEnumerable",
- },
- {
- href: `${extensionsSlug}/general/PlatformFee`,
- name: "PlatformFee",
- },
- {
- href: `${extensionsSlug}/general/PrimarySale`,
- name: "PrimarySale",
- },
- {
- href: `${extensionsSlug}/general/Royalty`,
- name: "Royalty",
- },
- ],
- name: "General",
- },
- {
- links: [
- {
- href: `${extensionsSlug}/erc-20/ERC20`,
- name: "ERC20",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20BatchMintable`,
- name: "ERC20BatchMintable",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20Burnable`,
- name: "ERC20Burnable",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20ClaimConditions`,
- name: "ERC20ClaimConditions",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20Mintable`,
- name: "ERC20Mintable",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20Permit`,
- name: "ERC20Permit",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20SignatureMint`,
- name: "ERC20SignatureMint",
- },
- {
- href: `${extensionsSlug}/erc-20/ERC20Staking`,
- name: "ERC20Staking",
- },
- ],
- name: "ERC-20",
- },
- {
- links: [
- {
- href: `${extensionsSlug}/erc-721/ERC721`,
- name: "ERC721",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721BatchMintable`,
- name: "ERC721BatchMintable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Burnable`,
- name: "ERC721Burnable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721ClaimConditions`,
- name: "ERC721ClaimConditions",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721ClaimCustom`,
- name: "ERC721ClaimCustom",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721ClaimPhases`,
- name: "ERC721ClaimPhases",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Claimable`,
- name: "ERC721Claimable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Enumerable`,
- name: "ERC721Enumerable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Mintable`,
- name: "ERC721Mintable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Revealable`,
- name: "ERC721Revealable",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721SignatureMint`,
- name: "ERC721SignatureMint",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Staking`,
- name: "ERC721Staking",
- },
- {
- href: `${extensionsSlug}/erc-721/ERC721Supply`,
- name: "ERC721Supply",
- },
- ],
- name: "ERC-721",
- },
- {
- links: [
- {
- href: `${extensionsSlug}/erc-1155/ERC1155`,
- name: "ERC1155",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155BatchMintable`,
- name: "ERC1155BatchMintable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Burnable`,
- name: "ERC1155Burnable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155ClaimConditions`,
- name: "ERC1155ClaimConditions",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155ClaimCustom`,
- name: "ERC1155ClaimCustom",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155ClaimPhases`,
- name: "ERC1155ClaimPhases",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Claimable`,
- name: "ERC1155Claimable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Drop`,
- name: "ERC1155Drop",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155DropSinglePhase`,
- name: "ERC1155DropSinglePhase",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Enumerable`,
- name: "ERC1155Enumerable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Mintable`,
- name: "ERC1155Mintable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Revealable`,
- name: "ERC1155Revealable",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155SignatureMint`,
- name: "ERC1155SignatureMint",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Staking`,
- name: "ERC1155Staking",
- },
- {
- href: `${extensionsSlug}/erc-1155/ERC1155Supply`,
- name: "ERC1155Supply",
- },
- ],
- name: "ERC-1155",
- },
- {
- links: [
- {
- href: `${extensionsSlug}/erc-4337/SmartWallet`,
- name: "SmartWallet",
- },
- {
- href: `${extensionsSlug}/erc-4337/SmartWalletFactory`,
- name: "SmartWalletFactory",
- },
- ],
- name: "ERC-4337",
- },
- ],
- name: "Extensions",
- },
- // stylus
- {
- href: `${buildSlug}/stylus`,
- name: "Arbitrum Stylus",
- },
- ],
- name: "Build your own",
- },
- { separator: true },
- // resources
- {
- isCollapsible: false,
- links: [
{
href: `${slug}/faq`,
name: "FAQ",
@@ -531,37 +60,6 @@ export const sidebar: SideBar = {
],
name: "Resources",
},
- {
- isCollapsible: true,
- links: [
- {
- links: [
- {
- href: `${designDocs}/drop`,
- name: "Drop",
- },
- {
- href: `${designDocs}/marketplace`,
- name: "Marketplace",
- },
- {
- href: `${designDocs}/multiwrap`,
- name: "Multiwrap",
- },
- {
- href: `${designDocs}/pack`,
- name: "Pack",
- },
- {
- href: `${designDocs}/signature-mint`,
- name: "Signature Mint",
- },
- ],
- name: "Design Docs",
- },
- ],
- name: "Archive",
- },
],
name: "Tokens",
};
diff --git a/apps/portal/src/app/vault/faqs/page.mdx b/apps/portal/src/app/vault/faqs/page.mdx
deleted file mode 100644
index ac6e487b4f8..00000000000
--- a/apps/portal/src/app/vault/faqs/page.mdx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { Details } from "@doc";
-
-# Vault FAQs
-
-
-***thirdweb vault is entirely non-custodial.***
-
-This means that if you lose your keys and your recovery code, *you have no means of recovering any of your EOAs, any funds stored in them, or any smart accounts or other contracts your EOAs might own.*
-
-thirdweb *cannot* help you in such a scenario.
-
-While storing all keys with yourself is the most secure way to use thirdweb vault, the lack of recovery options might be inconvenient or scary. As a compromise, when used with Engine Cloud, thirdweb allows you to store a backup of your rotation code with us. This way if you ever lose your admin key, we can let you rotate it as long as you can access the project this vault was initialised for.
-
-***is this still non-custodial?***
-
-yes.
-
-thirdweb cannot access any of your wallets or created entities with your rotation code alone.
-
-a “rotation-code” only allows the “service account rotate” operation, which will invalidate your admin key and all existing access tokens.
-
-There is no way for thirdweb to “silently” access your vault without your knowledge with only the recovery code.
-
-Rotating your engine’s vault account through a thirdweb-stored rotation code requires a signature from your wallet. You will also be able to see rotation history, the thirdweb account which initiated this rotation, and their wallet signature.
-
-
-
-You need either:
-- The admin key (which can perform any action, including creating Vault EOAs, aka server wallets).
-- Or an access token that has explicit permissions to create Vault EOAs.
-
-For Engine Cloud by default, we generate an access token for you during onboarding. This token can create Vault EOAs.
-
-However, if you want to restrict access to creating Vault EOAs, you can create a custom access token with the required scopes.
-
-
-
-The admin key is temporarily stored in dashboard when performing actions that require it, such as creating or managing server wallets:
-
-- It is only stored locally in memory for the duration of your session.
-- It is only sent over the network when end-to-end encrypted communication with Vault is happening.
-- It is not persisted or stored after your session ends.
-
-Please note, you should never share your admin key with third parties.
-
-
-
-Vault is not yet open source, but we plan to release it soon.
-
-
diff --git a/apps/portal/src/app/vault/get-started/page.mdx b/apps/portal/src/app/vault/get-started/page.mdx
deleted file mode 100644
index b3bbfb2489f..00000000000
--- a/apps/portal/src/app/vault/get-started/page.mdx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Callout } from "@doc";
-import { createMetadata } from "@/components/Document";
-
-# Get Started with Vault
-
-
-Vault is currently powering server wallets for the transactions API and will expand into more products.
-
-
-
-## Manage Vault
-
-To manage your Vault, navigate to **Project > Vault** in your project dashboard.
-
-Here you can create and manage access tokens and rotate your admin key.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/key-concepts/access-control/page.mdx b/apps/portal/src/app/vault/key-concepts/access-control/page.mdx
deleted file mode 100644
index 41d38a1eb3a..00000000000
--- a/apps/portal/src/app/vault/key-concepts/access-control/page.mdx
+++ /dev/null
@@ -1,111 +0,0 @@
-
-
-# Metadata-Based Access Control
-
-thirdweb Vault uses metadata patterns to map organizational structures directly into access control policies, eliminating the need to duplicate organizational hierarchies within the key management system.
-
-## Entity Tagging
-
-Each EOA can be tagged with arbitrary metadata key-value pairs representing organizational attributes:
-
-```json
-{
- "team": "trading",
- "region": "apac",
- "purpose": "treasury",
- "riskLevel": "high"
-}
-```
-
-## Pattern Matching with Rules
-
-Access tokens can be scoped using metadata rules that define precise access patterns:
-
-```json
-{
- "metadataPatterns": [
- {
- "key": "team",
- "rule": {
- "pattern": "^trading$"
- }
- },
- {
- "key": "riskLevel",
- "rule": {
- "op": "lessThan",
- "value": 3
- }
- }
- ]
-}
-```
-
-## Practical Implementation Examples
-
-### Departmental Segregation
-
-An organization can create EOAs tagged with departmental metadata and issue access tokens that respect organizational boundaries:
-
-```json
-// Policy component for trading department
-{
- "type": "eoa:signTransaction",
- "allowlist": [],
- "metadataPatterns": [
- {
- "key": "department",
- "rule": {
- "pattern": "^trading$"
- }
- },
- {
- "key": "region",
- "rule": {
- "pattern": "apac"
- }
- }
- ],
- "payloadPatterns": {
- "chainId": [
- {
- "pattern": "^(1|137)$"
- }
- ],
- "value": [
- {
- "op": "lessThan",
- "value": "1000000000000000000"
- }
- ]
- }
-}
-```
-
-### Multi-Team Collaboration
-
-For entities requiring shared access across teams:
-
-```json
-// EOA metadata
-{
- "teams": "finance,trading,compliance",
- "purpose": "treasury"
-}
-
-// Policy for finance team access
-{
- "type": "eoa:signMessage",
- "allowlist": [],
- "metadataPatterns": [
- {
- "key": "teams",
- "rule": {
- "pattern": "finance"
- }
- }
- ],
- "chainId": 1,
- "messagePattern": "^Confirm treasury operation:"
-}
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/key-concepts/access-tokens/page.mdx b/apps/portal/src/app/vault/key-concepts/access-tokens/page.mdx
deleted file mode 100644
index 14fdd8b85cd..00000000000
--- a/apps/portal/src/app/vault/key-concepts/access-tokens/page.mdx
+++ /dev/null
@@ -1,42 +0,0 @@
-
-# Access Tokens
-Access tokens are a core security mechanism in thirdweb Vault that enable secure, controlled delegation of wallet operations. Created by either user accounts or service accounts, access tokens allow precise, policy-based access to account-owned entities like EOAs.
-
-### Purpose and Benefits
-
-Access tokens serve several critical functions:
-
-- **Delegation without sharing keys**: Grant specific capabilities to services, applications, or team members without exposing your admin key
-- **Fine-grained permission control**: Limit exactly what operations can be performed and under what conditions
-- **Instant revocation**: Immediately terminate access when needed
-- **Auditable access paths**: Track and monitor who has what level of access to your entities
-
-### Policy-Based Control
-
-Each access token is configured with a set of policies that define:
-
-1. **Which operations** can be performed (e.g., signing transactions, reading wallet information)
-2. **Which entities** can be accessed (using allowlists or metadata patterns)
-3. **What constraints** apply to each operation (e.g., transaction value limits, allowed chains)
-
-An access token can only perform operations explicitly permitted by its policy. For example, you might create an access token that can only:
-
-- Sign transactions on Ethereum mainnet
-- With a maximum value of 1 ETH
-- To a specific set of contract addresses
-- Using only wallets tagged with a particular purpose
-
-### Practical Applications
-
-Access tokens enable critical workflows for blockchain applications:
-
-- **Application integrations**: Let your application sign transactions without holding private keys
-- **Team collaboration**: Grant different team members appropriate access levels to shared wallets
-- **Automated processes**: Enable secure automated signing for scheduled operations
-- **Temporary access**: Create time-limited tokens for specific projects or partnerships
-
-### Using Metadata for Flexible Control
-
-A particularly powerful feature of access tokens is their ability to use metadata patterns for entity access control. Rather than maintaining explicit allowlists, you can tag your EOAs with descriptive metadata and then create access tokens that match specific patterns.
-
-This metadata-based approach provides tremendous flexibility in how you organize and control access to your wallet infrastructure, which is detailed further in the sections below
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/key-concepts/accounts/page.mdx b/apps/portal/src/app/vault/key-concepts/accounts/page.mdx
deleted file mode 100644
index 026c9f2e25d..00000000000
--- a/apps/portal/src/app/vault/key-concepts/accounts/page.mdx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { Callout } from "@doc";
-
-# Accounts
-
-Vault will support 2 accounts types
-
-1. User Account (*coming soon*):
-2. Service Account
-
-## User Account
-
-User accounts can be authenticated by:
-
-1. passkey
-2. SIWE
-3. OTP (email/SMS)
-4. oauth (google etc)
-
-These are meant to be owned and operated by end-users and are ideal for integrating with consumer facing applications that want to provide a web2 like blockchain experience, while still being fully non-custodial.
-
-## Service Accounts
-
-Service accounts in thirdweb Vault provide a hierarchical security model for organizational key management, combining administrative control with precise delegation capabilities. These are ideal for applications where you have programmatic access control needs for wallets, but still want to keep the system non-custodial.
-
-
-thirdweb uses vault service accounts to power engine
-
-
-### Service Account Credentials
-
-A service account has two primary credentials:
-
-1. **Admin Key**: Grants access to every operation on every entity owned by the account
-2. **Rotation Code**: Used to invalidate current credentials and generate new ones during security events
-
-Service Accounts can used in combination with access-tokens to build non-custodial programmable access control for your enterprise applications.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/key-concepts/entities/page.mdx b/apps/portal/src/app/vault/key-concepts/entities/page.mdx
deleted file mode 100644
index 9db01dda458..00000000000
--- a/apps/portal/src/app/vault/key-concepts/entities/page.mdx
+++ /dev/null
@@ -1,21 +0,0 @@
-# Entities
-
-Entities are the resources secured by vault. Entities are owned by a vault account.
-Vault currently secures the EOA entity.
-
-## EOA
-
-An EOA (Externally Owned Account) is an EVM account controlled by a private key held by a user. It's a fundamental part of the EVM ecosystem, used for managing funds, initiating transactions, and interacting with smart contracts.
-The private key to the EOA is always stored encrypted, and only decrypted within vault.
-
-Vault supports the following EOA related operations (API reference):
-
-```typescript
-eoa:list
-eoa:create
-eoa:signMessage
-eoa:signTypedData
-eoa:signTransaction
-eoa:signStructuredMessage
-eoa:signAuthorization
-```
diff --git a/apps/portal/src/app/vault/key-concepts/key-management/page.mdx b/apps/portal/src/app/vault/key-concepts/key-management/page.mdx
deleted file mode 100644
index 1cf8d080107..00000000000
--- a/apps/portal/src/app/vault/key-concepts/key-management/page.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Callout } from "@doc";
-
-# Understanding Vault Keys
-
-## Vault Admin Key
-
-This is an admin key that grants access to every operation on every server wallet. It is also used to create access tokens.
-
-Keep the admin key securely and distribute it only between trusted team members (who you would consider admins, and need to perform administrative functions). Do not send this key to external services, only send it directly to vault (via E2E encryption), or use it in the thirdweb dashboard where it's always securely stored in your browser memory and only used to communicate with the vault through e2e encryption. Your admin keys are never revealed to anyone other than vault itself, and you.
-
-## Access Tokens
-
-Access Tokens are created using the admin key. Access tokens support flexible policies that allow you to restrict what it can do. It can be scoped by:
-
-1. operation type (eg signMessage or createEoa)
-2. operation payload (only allow specific types of transactions to be signed like restricting by chainId, toAddress, or max value)
-3. entity, ie, which EOAs can this access token perform operations with. Access to entities like EOAs can be scoped in 2 ways:
- 1. **allowlist**: if you have a short list (1/2) EOAs that an access token should be able to access, you can use the allowlist
- 2. metadata: if you have lots of entities and complex requirements for different users to access different groups of entities, you can scope by metadata. Metadata allows you to represent implicit grouping of resources and user. As an example:
- 1. you can create multple EOAs with metadata `team: "trading-floor"`
- 2. If you then create an access token with
- `metadataPatterns: { key: "team", pattern: "^trading-floor$"}` ,
- this access token will only be able to access EOAs with that specific metadata parameter set.
- 3. This allows you to create different access tokens for different sets of EOAs, where each set is grouped together with a metadata pattern. Groups can overlap. If you want multiple groups of users with your org to have access to the same EOA, you can instead use metadata: `{ teams: "trading-floor, compliance" }`
- And now use:
- for trading floor:
- `metadataPatterns: { key: "teams", pattern: "trading-floor"}`
- for compliance:
- `metadataPatterns: { key: "team", pattern: "compliance"}`
-
- This is just an example of how flexible vault’s policies can be. Patterns can be regex operators or numeric comparisons. Metadata supports arbitrary key-value as well, so you can also create other metadata fields like `purpose` or `teamId` (if you want to map it to an internal team identifier)
-4. An access token can be revoked instantly with your admin key.
-5. You can share access tokens with all members of your team. There are multiple ways you should be sharing these, depending on your team and organisation structure:
- 1. If you have distinct teams within your org that don't have overlapping needs to access EOAs, you can create team specific access tokens. Every member of a team within your org will get the same access token. If a member leaves and you want to remove their access, you can revoke the existing team access tokens, create a new access token with the same policies, and share the new token with remaining team members.
- 2. if you have a small org, where members have large overlapping needs, you can create a single access token (scoped as minimally as possible) and share it with everyone. If a member leaves, you can revoke the existing token, create a new one, and share it with your members again.
- 3. for the most granular permissioning, you can create a distinct access token for every member of your team with policies restricted to exactly what they need. This way the token can also be revoked individually without any side-effects to the other tokens.
-
-
-Access tokens are for using with external services or for non-adminstrative team members. Adminstrative team members might want the ability to create new access tokens, so sharing the admin key with them is more appropriate.
-
-
-## Rotation code
-
-The rotation code can be used to "rotate" your account. Rotating your account will:
-
-1. invalidate your old admin key, returning you a new key
-2. invalidate the rotation code used, returning a new rotation code
-3. invalidate all existing access tokens that were previously created.
-
-The rotation code should only be stored with the "organisation owner".
-
-It can be used in disaster scenarios when you suspect you might have leaked a key.
-
-It can also be used when an "administrative" team member who had access to your admin key leaves your org, and you want to revoke their access.
-
-After the rotation code is used, all exsting access tokens need to be recreated and shared with your team, and the newly received admin key must be shared with your "team admins".
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/layout.tsx b/apps/portal/src/app/vault/layout.tsx
deleted file mode 100644
index 031d8bc919b..00000000000
--- a/apps/portal/src/app/vault/layout.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createMetadata } from "@doc";
-import { DocLayout } from "@/components/Layouts/DocLayout";
-import { sidebar } from "./sidebar";
-
-export default async function Layout(props: { children: React.ReactNode }) {
- return (
-
- {props.children}
-
- );
-}
-
-export const metadata = createMetadata({
- description:
- "Vault is a non-custodial key management service secured with TEE architecture (AWS Nitro Enclaves), designed for blockchain applications.",
- title: "Vault",
- image: {
- icon: "vault",
- title: "thirdweb Vault",
- },
-});
diff --git a/apps/portal/src/app/vault/page.mdx b/apps/portal/src/app/vault/page.mdx
deleted file mode 100644
index 2aa5bc4998c..00000000000
--- a/apps/portal/src/app/vault/page.mdx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { createMetadata } from "@/components/Document";
-import { DocImage, FeatureCard, OpenSourceCard, Callout } from "@doc";
-import { ArrowLeftRightIcon, UserLockIcon, UsersIcon, WalletIcon } from "lucide-react";
-
-
-export const metadata = createMetadata({
- title: "thirdweb Vault",
- description: "A secure key management service for storing, managing, and protecting cryptographic keys and secrets.",
- image: {
- icon: "vault",
- title: "thirdweb Vault",
- },
-});
-
-# Vault
-
-Vault is a non-custodial key management service secured with TEE architecture (AWS Nitro Enclaves), designed for blockchain applications.
-
-## Features
-
-
- }
- />
-
- }
- />
-
- }
- />
-
- }
- />
-
-
-
-With vault, you can build applications where:
-
-- Your users never need to manage private keys
-- Your backend services can request signatures without having access to private keys
-- Your users can create controlled access for team members, services, or automation
-- Security is enforced cryptographically, not through promises
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/api-reference/page.mdx b/apps/portal/src/app/vault/sdk/api-reference/page.mdx
deleted file mode 100644
index 64bd6f3336c..00000000000
--- a/apps/portal/src/app/vault/sdk/api-reference/page.mdx
+++ /dev/null
@@ -1,130 +0,0 @@
-# API Reference
-
-This section lists every exported function from **@thirdweb-dev/vault-sdk** grouped by broad capability. All functions are fully typed – hover in your editor for exact type information.
-
----
-
-## 1. Client utilities
-
-| Function | Description |
-| --- | --- |
-| `createVaultClient({ secretKey })` | Uses your project secret key to establish a connection to your Vault instance and returns a `VaultClient`. Create **one** client per Vault instance and reuse it. |
-| `ping({ client, request })` | Health-check endpoint mainly used in examples and tests. Returns the current server time. |
-
-```ts
-const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });
-await ping({ client, request: { message: "pong?" } });
-```
-
----
-
-## 2. Service Accounts
-
-| Function | When to use |
-| --- | --- |
-| `createServiceAccount({ request })` | Bootstrap a brand-new Vault. Returns the **admin key** and **rotation code**. _Run once during provisioning_. |
-| `getServiceAccount({ request })` | Retrieve metadata for the current service account. Requires **admin key** or a token with `serviceAccount:read` policy. |
-| `rotateServiceAccount({ request })` | Rotate (invalidate) the admin key **and** all existing access tokens in a single atomic operation. Authenticate with the **rotation code**. |
-
-Example – rotate an account after a key leak:
-
-```ts
-await rotateServiceAccount({
- client,
- request: {
- auth: { rotationCode: process.env.VAULT_ROTATION_CODE! },
- },
-});
-```
-
----
-
-## 3. EOAs (Wallets)
-
-| Function | Purpose |
-| --- | --- |
-| `createEoa` | Create a new EOA (wallet) inside the Vault. Optionally attach arbitrary `metadata` for later querying. |
-| `listEoas` | Pagination-aware listing with optional metadata filters. |
-| `signTransaction` | Ask the Vault to sign an EVM transaction (legacy, 2930, 1559, 4844 or 7702). |
-| `signMessage` | Sign a plain string / hex message. |
-| `signTypedData` | Sign EIP-712 typed data with full generic type safety. |
-| `signAuthorization` | Sign an [`Authorization`](#authorization) struct used by some L2s / account-abstraction schemes. |
-| `signStructuredMessage` | Sign EIP-4337 user-operations (v0.6 & v0.7). |
-
-```ts
-// sign a 1559 tx
-import { parseTransaction, signTransaction } from "@thirdweb-dev/vault-sdk";
-
-const tx = parseTransaction({
- to: "0x...",
- value: 0n,
- chainId: 1,
- maxFeePerGas: 30n * 10n ** 9n,
- maxPriorityFeePerGas: 1n * 10n ** 9n,
- gasLimit: 21_000,
-});
-
-await signTransaction({
- client,
- request: {
- auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
- options: { from: "0xEoaAddress", transaction: tx },
- },
-});
-```
-
-> **Note**: `parseTransaction` is a convenience helper that normalises user-supplied objects – you can also build the canonical tx object yourself.
-
----
-
-## 4. Access Tokens
-
-| Function | Purpose |
-| --- | --- |
-| `createAccessToken` | Mint a **base token** scoped by policies & metadata. Requires **admin key**. |
-| `createSignedAccessToken` | Pure-client helper that turns a *base* token into a short-lived, signed JWT (prefixed with `vt_sat_`). No server round-trip required. |
-| `listAccessTokens` | List existing tokens with pagination and optional metadata filters. |
-| `revokeAccessToken` | Immediately invalidate a token (or all derived signed tokens) by `id`. |
-
-```ts
-// Derive a time-boxed signed token for a serverless function
-const sat = await createSignedAccessToken({
- vaultClient: client,
- baseAccessToken: process.env.VAULT_BASE_TOKEN!,
- additionalPolicies: [
- { type: "eoa:signMessage", chainId: 1, messagePattern: "^0x.*" },
- ],
- expiryTimestamp: Math.floor(Date.now() / 1000) + 60 * 5, // 5 min
-});
-```
-
----
-
-## 5. Utilities
-
-| Function | Notes |
-| --- | --- |
-| `parseTransaction` | Normalises user input into a canonical `EthereumTypedTransaction` (supports Legacy, 2930, 1559, 4844, 7702). Throws `ParseTransactionError` on invalid input. |
-| `ParseTransactionError` | Custom error class thrown by the above helper. |
-
-```ts
-try {
- parseTransaction({ gas: 100_000 });
-} catch (err) {
- if (err instanceof ParseTransactionError) {
- console.error(err.message);
- }
-}
-```
-
----
-
-### Types
-
-All request & response shapes are exported as TypeScript types so you can easily model higher-level abstractions:
-
-```ts
-import type { CreateEoaPayload, SignMessagePayload, PolicyComponent } from "@thirdweb-dev/vault-sdk";
-```
-
-Refer to the generated `.d.ts` files for the complete list.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx b/apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx
deleted file mode 100644
index 414c63a18be..00000000000
--- a/apps/portal/src/app/vault/sdk/guides/access-tokens/page.mdx
+++ /dev/null
@@ -1,105 +0,0 @@
-# Guide – Managing Access Tokens
-
-Access tokens let you delegate finely-scoped permissions to services, cron jobs or external partners without sharing the admin key.
-
-This guide covers:
-
-1. Creating a **base** access token (server-side)
-2. Deriving short-lived **signed** tokens client-side
-3. Listing and revoking tokens
-
----
-
-## 1. Create a base token
-
-Base tokens are created **once** and stored securely (e.g. in your secrets manager). They cannot be scoped by expiry – instead you define *policies* that control which operations are allowed.
-
-```ts
-import { createVaultClient, createAccessToken } from "@thirdweb-dev/vault-sdk";
-
-const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });
-
-const res = await createAccessToken({
- client,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: {
- policies: [
- {
- type: "eoa:signMessage",
- allowlist: ["0xEoaAddress"],
- messagePattern: "^0x.*", // only allow hex messages
- },
- ],
- expiresAt: new Date("2030-01-01").toISOString(),
- metadata: { env: "prod", owner: "backend" },
- },
- },
-});
-
-console.log("base token", res.data.accessToken);
-```
-
----
-
-## 2. Create a signed access token (JWT)
-
-A **signed access token (SAT)** is a JWT created entirely on the client side. You derive it from a base token, embed additional policies and set a short expiry.
-
-```ts
-import { createSignedAccessToken } from "@thirdweb-dev/vault-sdk";
-
-
-const sat = await createSignedAccessToken({
- vaultClient: client,
- baseAccessToken: process.env.BASE_ACCESS_TOKEN,
-
- additionalPolicies: [
- { type: "eoa:signMessage", chainId: 1 },
- ],
- expiryTimestamp: Math.floor(Date.now() / 1000) + 300, // 5 minutes
-});
-
-// Prefix: vt_sat_
-console.log(sat);
-```
-
-Send SATs to un-trusted environments (browser, serverless) – they only work until the expiry timestamp and can be revoked centrally by revoking their base token.
-
----
-
-## 3. List & revoke
-
-```ts
-import { listAccessTokens, revokeAccessToken } from "@thirdweb-dev/vault-sdk";
-
-// List the first 10 tokens created by "backend"
-const list = await listAccessTokens({
- client,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: { page: 1, pageSize: 10 },
- },
-});
-
-const tokenId = list.data.items[0].id;
-
-// Revoke it
-await revokeAccessToken({
- client,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: { id: tokenId },
- },
-});
-```
-
-Once revoked, **all signed tokens derived** from the base are automatically invalidated.
-
----
-
-### Best practices
-
-1. **Never ship base tokens to browsers** – always derive SATs.
-2. **Keep expiries short** (minutes) for web-apps and serverless functions.
-3. **Scope by metadata** to share the same policies across many EOAs.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/guides/creating-eoas/page.mdx b/apps/portal/src/app/vault/sdk/guides/creating-eoas/page.mdx
deleted file mode 100644
index 1a51f153ee3..00000000000
--- a/apps/portal/src/app/vault/sdk/guides/creating-eoas/page.mdx
+++ /dev/null
@@ -1,75 +0,0 @@
-# Guide – Creating & Managing EOAs
-
-This guide walks you through creating your first Externally Owned Account (EOA) inside the Vault and querying it later.
-
-## Prerequisites
-
-- A running Vault instance.
-- The **admin key** or a token with the `eoa:create` / `eoa:read` policies.
-- The Vault SDK installed (see Installation).
-
----
-
-## 1. Create a new EOA
-
-```ts
-import { createVaultClient, createEoa } from "@thirdweb-dev/vault-sdk";
-
-const client = await createVaultClient({
- secretKey: "PROJECT_SECRET_KEY",
-});
-
-const res = await createEoa({
- client,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: {
- metadata: {
- team: "treasury",
- purpose: "eth-cold-storage",
- },
- },
- },
-});
-
-if (!res.success) throw new Error(res.error.message);
-
-console.log("EOA address", res.data.address);
-```
-
-### Metadata
-
-`metadata` accepts arbitrary key-value pairs that can later be used for filtering (`listEoas`) or for access-token policies.
-
----
-
-## 2. Listing EOAs
-
-```ts
-import { listEoas } from "@thirdweb-dev/vault-sdk";
-
-const list = await listEoas({
- client,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: {
- page: 1,
- pageSize: 20,
- },
- },
-});
-
-for (const eoa of list.data.items) {
- console.log(eoa.address, "metadata:", eoa.metadata);
-}
-```
-
-You can build richer UIs by using the pagination data (`page`, `pageSize`, `totalRecords`).
-
----
-
-## 3. Best practices
-
-1. **Group wallets via metadata** – e.g. `{ env: "prod" }`, `{ team: "ops" }`.
-2. **Use access tokens for app-specific actions** – never ship the admin key to client-side code.
-3. **Rotate when you onboard/offboard admins** – see the rotation guide.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/guides/signing/page.mdx b/apps/portal/src/app/vault/sdk/guides/signing/page.mdx
deleted file mode 100644
index 1f59fbb0c80..00000000000
--- a/apps/portal/src/app/vault/sdk/guides/signing/page.mdx
+++ /dev/null
@@ -1,126 +0,0 @@
-# Guide – Signing Transactions & Messages
-
-In this guide we will request signatures from the Vault for common payload types:
-
-1. Plain text / hex messages
-2. EIP-712 typed data
-3. EVM transactions (legacy & EIP-1559)
-
-## Prerequisites
-
-- An EOA created in the Vault
-- An **access token** with the corresponding `eoa:sign*` policies (or the admin key for testing)
-
----
-
-## 1. Sign a plain message
-
-```ts
-import { createVaultClient, signMessage } from "@thirdweb-dev/vault-sdk";
-
-const client = await createVaultClient({ secretKey: "PROJECT_SECRET_KEY" });
-
-const res = await signMessage({
- client,
- request: {
- auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
- options: {
- from: "0xEoaAddress", // address of the signer wallet
- message: "gm",
- chainId: 1,
- },
- },
-});
-
-console.log(res.data.signature);
-```
-
----
-
-## 2. Sign EIP-712 typed data
-
-The helper is fully generic – you get compile-time checks that the `message` matches your `types`.
-
-```ts
-import { signTypedData } from "@thirdweb-dev/vault-sdk";
-import type { TypedData } from "abitype";
-
-interface Types extends TypedData {
- Person: [
- { name: "name"; type: "string" },
- { name: "wallet"; type: "address" },
- ];
-}
-
-await signTypedData({
- client,
- request: {
- auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
- options: {
- from: "0xEoaAddress",
- typedData: {
- domain: { name: "Example", version: "1", chainId: 1 },
- types: {
- EIP712Domain: [
- { name: "name", type: "string" },
- { name: "version", type: "string" },
- { name: "chainId", type: "uint256" },
- ],
- Person: [
- { name: "name", type: "string" },
- { name: "wallet", type: "address" },
- ],
- },
- primaryType: "Person",
- message: {
- name: "Alice",
- wallet: "0xEoaAddress",
- },
- },
- },
- },
-});
-```
-
----
-
-## 3. Sign an EIP-1559 transaction
-
-```ts
-import { parseTransaction, signTransaction } from "@thirdweb-dev/vault-sdk";
-
-const tx1559 = parseTransaction({
- type: "0x02",
- chainId: 1,
- to: "0xRecipient",
- value: 0n,
- gasLimit: 21_000,
- maxFeePerGas: 30n * 10n ** 9n,
- maxPriorityFeePerGas: 1n * 10n ** 9n,
-});
-
-await signTransaction({
- client,
- request: {
- auth: { accessToken: process.env.VAULT_SIG_TOKEN! },
- options: { from: "0xEoaAddress", transaction: tx1559 },
- },
-});
-```
-
----
-
-### Error handling
-
-All SDK functions return an object with `{ success, data, error }`. Prefer pattern matching over exceptions:
-
-```ts
-const res = await signMessage(/* … */);
-
-if (!res.success) {
- console.error(res.error);
- return;
-}
-
-console.log("signature", res.data.signature);
-```
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/installation/page.mdx b/apps/portal/src/app/vault/sdk/installation/page.mdx
deleted file mode 100644
index 35a2f04b36a..00000000000
--- a/apps/portal/src/app/vault/sdk/installation/page.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
-# Installation & Setup
-
-The Vault SDK targets modern **ESM** runtimes (Node >= 18 and all evergreen browsers).
-
-## Add the package
-
-```bash
-# with pnpm (recommended)
-pnpm add @thirdweb-dev/vault-sdk
-
-# or npm
-npm install @thirdweb-dev/vault-sdk
-
-# or Yarn
-yarn add @thirdweb-dev/vault-sdk
-```
-
-## Peer dependencies
-
-The SDK has no required peer-dependencies, but it expects the **`fetch`** Web API to be globally available (Node 18 provides it by default).
-
-If you run on an older Node version, install a fetch polyfill:
-
-```bash
-npm install undici --save
-```
-
-```ts
-// polyfill global fetch (Node < 18)
-import { fetch, Headers, Request, Response } from "undici";
-// @ts-ignore
-globalThis.fetch = fetch;
-```
-
-## Initialise a client instance
-
-All requests go through a `VaultClient` that holds your Vault's base URL and the enclave public key:
-
-```ts
-import { createVaultClient } from "@thirdweb-dev/vault-sdk";
-
-const vault = await createVaultClient({
- // Get this from your thirdweb dashboard
- secretKey: "PROJECT_SECRET_KEY",
-});
-```
-
-`createVaultClient` uses your secret key to establish a connection to the thirdweb vault instance. You can also specify a baseUrl that points to your own vault instance. Cache the resulting `vault` object and reuse it for all subsequent operations.
-
-> **Tip**: If you run multiple Vault instances (dev, staging, prod) create one `VaultClient` per instance.
-
----
-
-Next: explore the **API Reference** or jump straight into the guides.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sdk/page.mdx b/apps/portal/src/app/vault/sdk/page.mdx
deleted file mode 100644
index 0df2409e793..00000000000
--- a/apps/portal/src/app/vault/sdk/page.mdx
+++ /dev/null
@@ -1,70 +0,0 @@
-# Vault SDK
-
-The **@thirdweb-dev/vault-sdk** gives you a type-safe JavaScript/TypeScript client for interacting with a Vault instance from any Node.js or browser environment.
-
-It is built on top of the Vault HTTP API and handles:
-
-- End-to-end encryption to the TEEs (Nitro Enclaves) that protect your keys.
-- Type-safe request/response objects (generated from the Rust server types).
-- Convenience helpers for signing messages, transactions and typed data.
-- Utility helpers for JSON-Web-Token (JWT) based _signed access tokens_.
-
-Use the SDK whenever you need programmatic, non-interactive access to the Vault—CLI tooling, server-side scripts, CI/CD pipelines or browser-based dashboards.
-
----
-
-## What you can do
-
-1. **Create and manage service accounts** – bootstrap a new Vault, rotate admin keys.
-2. **Create EOAs (wallets)** – generate new non-custodial accounts inside the Vault.
-3. **Sign payloads** – transactions, messages, typed-data, EIP-4337 user-ops, …
-4. **Mint access tokens** – granular, policy-based bearer tokens for internal or 3rd-party services.
-5. **Parse raw transactions** – normalise heterogeneous user input into canonical EVM tx objects.
-
-See the Installation guide for how to add the package and the API Reference for every function available.
-
----
-
-## Quick example
-
-```ts
-import {
- createVaultClient,
- createEoa,
- signMessage,
-} from "@thirdweb-dev/vault-sdk";
-
-// 1. Connect to your Vault instance
-const vault = await createVaultClient({
- secretKey: "PROJECT_SECRET_KEY" /* Your thirdweb project secret key */,
-});
-
-// 2. Create a new wallet inside the Vault
-const { success, data: eoa } = await createEoa({
- client: vault,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: {
- metadata: { purpose: "treasury" },
- },
- },
-});
-
-if (!success) throw new Error("Failed to create EOA");
-
-// 3. Sign a message with that wallet
-await signMessage({
- client: vault,
- request: {
- auth: { adminKey: process.env.VAULT_ADMIN_KEY! },
- options: {
- from: eoa!.address,
- message: "Hello from Vault ✨",
- },
- },
-});
-```
-
----
-
-Continue with the **Installation** section to get started.
diff --git a/apps/portal/src/app/vault/security/page.mdx b/apps/portal/src/app/vault/security/page.mdx
deleted file mode 100644
index c3acf1df00c..00000000000
--- a/apps/portal/src/app/vault/security/page.mdx
+++ /dev/null
@@ -1,94 +0,0 @@
-# Security
-
-## Non Custodiality
-
-Vault guarantees non-custodiality through cryptography. All private and sensitive data is stored encrypted, and can only be decrypted within the secure enclave. The code running within the secure enclave is open-source, audited, and attested.
-
-## Attestation
-
-At any time, you can request an attestation document from Vault. This attestation document is signed by AWS (independently verifiable).
-
-The attestation document allows you to [verify](https://aws.amazon.com/blogs/compute/validating-attestation-documents-produced-by-aws-nitro-enclaves/) that the code being run inside the secure enclave has not been tampered, and is the same as the open source code that you can access.
-
-The code running inside a nitro enclave is an Enclave Image File (EIF). The EIF has unique PCR values which will change upon tampering.
-
-In the context of AWS Nitro Enclaves, an Enclave Image File (EIF) measurement, specifically the Platform Configuration Register (PCR) values, are **cryptographic hashes that uniquely identify the enclave's image and its contents**. PCRs are used to verify that the enclave has been loaded and is running in a known, trusted state, ensuring its integrity and preventing unauthorized modification
-
-The master key of the Vault can only be accessed by this exact code running inside the enclave. To verify this, you can query Vault to check the current AWS policy on the master key, and confirm that only nitro-enclaves with this specific PCR measurement have access to these resources.
-
-## Verify, Don’t Trust
-
-You can compile your own EIF from the Vault source-code, and retrieve PCR values. This allows you to compare the PCR values you received from Vault *against* the PCR measurements you generated yourself, proving that a hosted Vault service is running untampered code.
-
-## Chain of ~~Trust~~ Verification
-
-Armed with proof that the Vault service is running untampered code, you can audit the code to ensure Vault behaves as expected.
-
-For example: how can you verify that Vault is not lying about who can access it’s keys?
-
-You can look at the Vault code to confirm that it does indeed query the correct AWS APIs to fetch the current policies on it’s keys, and then returns it without modifications.
-
-If you know the code is correct, and if you know that the service is running untampered code, then you can confirm that the correct data is being returned to you.
-
-But how can you confirm that data from the Vault hasn’t been tampered by other non-enclave components your response might be coming through? To solve this, Vault uses an end to end encrypted communication protocol with perfect forward secrecy.
-
-This same approach can be used to verify that all entities are always stored encrypted, and access is only granted to authorized requests. To further prevent data leakage, Vault uses HMAC hashes instead of raw identifiers to associate entities with each other in the encrypted database. This means Vault can not-only guarantee non-custodial access to entities, but also preserves privacy between entities and their owners. E2E encryption also means that all your operations and responses remain private and untampered.
-
-# End to End Encryption
-
-Every sensitive request to Vault is made to the `/v1/enclave/post` endpoint with a payload that looks like this:
-
-```json
-
- {
- "ephemeralPublicKey": "05d7deb3ef80f929ee6d1afdbf63d43e68ae9d1a045577cf6a2cbc29baaa5c5f",
- "nonce": "716d11684ed4a973ff401e9bc84db48608c1f78abdba59a2",
- "ciphertext": "ed0665497121ca59ef610f976f0a3beaa494c17b65ca127e72f286fa3464fde3f14e305d9fded6090bd5fd7fd2fd57d93d399619fe950d71790daec1b753d5b221d914e6e29c6734e6a38c7d237a91fea289f4812eeefae88281cc9cae8e7421ca1d81a5ac4181d889a9a082fbaf7cd5c650a2c8ccf61981d9fc3535a76733e0b00dbad4a2492c399b8a49c00f89d11283fe408754e470f5ec3579fac2aedc4c042eb75dd6804cf0fa331d5da039cfad6e36f5d00e7c6e78b5e0956a36af01761c31b0d85d90b3d15e0808a544c3f15ba1d3ae108efd36add25791ee6d27d58d9bf7c87903bbd5c54ed52c3b501eb9c67ff374308d95b7acabd7e02375fd0aab6668008583740f1883ed0c00731f732ecd4d46498939f223b1eba1c0c536cea12cf85370c17ef30fce992c129938e1f049c64c2cadafd1efc93692445c47923f6bb9ffbb8226fbf7f5bfa5a14060a2085c1df145294397a7035761c20fdac820a57ed4bdd591941a9d9804c3c92c1e5e0f60857a68516b330816c57e133b4dfcf492cdc1f9ab3d9097babd997552adbb90c871e82fbab041555f0ab4ae3fb93adf4a3ba2182d76787d58568275849595564eb10e601f7ede972f2c6d8429112f90ce4aa09177ca2811d7025100cd3621edcc8b091d2e943afdc44f91d2f60abb3daae1"
- }
-```
-
-The communication protocol ensures that requests can only be decrypted by the Vault-enclave, and responses can only be decrypted by you. The protocol also provides perfect forward secrecy, meaning even if cryptographic keys for a previous request is exposed, future requests still remain non-compromised.
-
-## Protocol
-
-Vault uses the xChaCha20Poly1305 cryptographic cipher, combined with the x25519dalek for zero round trip key-exchange.
-
-### Step 1
-
-The client queries the Vault’s xChaCha20Poly1305 public-key from the `GET api/v1/enclave` endpoint.
-
-### Step 2
-
-The client generates a random 32 byte ephemeral secret key (and stores it to decrypt the response too)
-
-### Step 3
-
-The client derives a shared secret using xChaCha20Poly1305:
-
-```json
-shared_secret = diffie_hellman(client_ephemeral_secret_key, vault_public_key)
-```
-
-### Step 4
-
-The client derives an encryption key from the `shared_secret` using HKDF
-
-### Step 5
-
-The client generates a random 24 byte nonce
-
-The client generates the `ciphertext` using xChaCha20Poly1305 with the random nonce, and the derives encryption key
-
-### Sending the Payload
-
-The generated ciphertext, nonce, and the public key to the ephemeral secret are all hex encoded and sent as the payload
-
-## Decrypting the Response
-
-The response also arrives in the same payload format. We just perform the steps in reverse now.
-
-1. Use `x25519dalek` `diffie_hellman` to derive a `shared_secret` from the:
- 1. private key we used for sending the request
- 2. the public key returned in the response
-2. HKDF the `shared_secret` to get the `encryption_key`
-3. Use the `nonce` in the response (which Vault randomly generates) + the `shared_secret` with xChaCha20Poly1305 to decrypt your payload.
\ No newline at end of file
diff --git a/apps/portal/src/app/vault/sidebar.tsx b/apps/portal/src/app/vault/sidebar.tsx
deleted file mode 100644
index 2108de684e6..00000000000
--- a/apps/portal/src/app/vault/sidebar.tsx
+++ /dev/null
@@ -1,102 +0,0 @@
-import {
- Code2Icon,
- KeyIcon,
- MessageCircleQuestionIcon,
- RocketIcon,
- ShieldQuestionIcon,
- VaultIcon,
- WrenchIcon,
-} from "lucide-react";
-import type { SideBar } from "@/components/Layouts/DocLayout";
-
-export const sidebar: SideBar = {
- links: [
- {
- href: "/vault",
- icon: ,
- name: "Overview",
- },
- {
- href: "/vault/get-started",
- icon: ,
- name: "Get Started",
- },
- {
- icon: ,
- links: [
- {
- href: "/vault/key-concepts/key-management",
- name: "Key Management",
- },
- {
- href: "/vault/key-concepts/entities",
- name: "Entities",
- },
- {
- href: "/vault/key-concepts/accounts",
- name: "Accounts",
- },
- {
- href: "/vault/key-concepts/access-tokens",
- name: "Access Tokens",
- },
- {
- href: "/vault/key-concepts/access-control",
- name: "Access Control",
- },
- ],
- name: "Key Concepts",
- },
- {
- icon: ,
- links: [
- {
- href: "/vault/sdk",
- name: "Overview",
- },
- {
- href: "/vault/sdk/installation",
- name: "Installation",
- },
- {
- href: "/vault/sdk/api-reference",
- name: "API Reference",
- },
- {
- links: [
- {
- href: "/vault/sdk/guides/creating-eoas",
- name: "Creating & Managing EOAs",
- },
- {
- href: "/vault/sdk/guides/signing",
- name: "Signing Transactions & Messages",
- },
- {
- href: "/vault/sdk/guides/access-tokens",
- name: "Managing Access Tokens",
- },
- ],
- name: "Guides",
- },
- ],
- name: "TypeScript SDK",
- },
- {
- href: "/vault/security",
- icon: ,
- name: "Security",
- },
- {
- href: "/vault/troubleshoot",
- icon: ,
- name: "Troubleshoot",
- },
- {
- href: "/vault/faqs",
- icon: ,
- name: "FAQs",
- },
- ],
- name: "Vault",
-};
diff --git a/apps/portal/src/app/vault/troubleshoot/page.mdx b/apps/portal/src/app/vault/troubleshoot/page.mdx
deleted file mode 100644
index acd5a392073..00000000000
--- a/apps/portal/src/app/vault/troubleshoot/page.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-# Vault Troubleshoot Guide
-
-More information coming soon.
\ No newline at end of file
diff --git a/apps/portal/src/app/wallets/ecosystem/reown/page.mdx b/apps/portal/src/app/wallets/ecosystem/reown/page.mdx
new file mode 100644
index 00000000000..c1dbb5697ce
--- /dev/null
+++ b/apps/portal/src/app/wallets/ecosystem/reown/page.mdx
@@ -0,0 +1,48 @@
+import { DocImage, Steps, Step } from "@doc";
+import WalletconnectCreate from "../assets/walletconnect-create.png";
+import WalletconnectUrl from "../assets/walletconnect-url.png";
+import WalletconnectWallet from "../assets/walletconnect-wallet.png";
+import WalletconnectGuide from "../assets/walletconnect-guide.png";
+
+# How to Register Your thirdweb Ecosystem Wallet with WalletConnect (now Reown)
+
+**Note:** WalletConnect Inc. is now Reown. [Read more here](https://reown.com/blog/walletconnect-is-now-reown).
+
+Registering your Ecosystem Wallet with Reown allows it to appear in the WalletConnect Explorer for seamless integration with platforms like OpenSea and other third-party applications.
+
+
+
+Visit the [Reown Dashboard](https://reown.com/) and select **"Create Project"**
+- Enter your [Ecosystem Wallet's Explorer](https://thirdweb.com/team/~/~/ecosystem/) page URL as the **Homepage URL** and proceed.
+- Choose **Wallet** as the project type and select **"Create"**
+
+
+
+
+
+
+
+Navigate to the **WalletGuide** tab and fill out the following form:
+- **Wallet Name:** Provide your wallet's name.
+- **Wallet Category:** Select **"Web App Wallets"**
+- **Web App URL:** Use your Ecosystem Wallet's Explorer page URL.
+- **Supported Chains:** Choose Ethereum and any other chains your wallet supports.
+- **Logo:** Upload your wallet’s logo (this will appear on the WalletConnect Explorer).
+- **Testing Instructions:** Provide clear testing instructions for the Reown team. For example: *"Log in via the specified URL and select an authentication method."*
+
+
+
+
+
+Once you've completed the form, click **"Submit Review"**
+- After approval, your wallet will appear live on the WalletConnect Explorer.
+
+
+
+Visit a platform like OpenSea and use WalletConnect to log in.
+- Select your registered wallet from the list and authenticate.
+- Your wallet should now seamlessly connect, allowing you to interact with the platform.
+
+
+
+By following these steps, your branded Ecosystem Wallet will be accessible across all WalletConnect-enabled (Reown) applications.
\ No newline at end of file
diff --git a/apps/portal/src/app/wallets/ecosystem/set-up/page.mdx b/apps/portal/src/app/wallets/ecosystem/set-up/page.mdx
index 617713d1ec5..74ae3eac0fb 100644
--- a/apps/portal/src/app/wallets/ecosystem/set-up/page.mdx
+++ b/apps/portal/src/app/wallets/ecosystem/set-up/page.mdx
@@ -2,10 +2,7 @@ import { Callout, DocImage, createMetadata, Steps, Step } from "@doc";
import CreateEcosystemWallet from "./assets/ecosystem-info.png";
import EcosystemWalletPermissions from "./assets/ecosystem-wallet-permissions.png";
import AddAPartner from "./assets/add-partner.png";
-import WalletconnectCreate from "../assets/walletconnect-create.png";
-import WalletconnectUrl from "../assets/walletconnect-url.png";
-import WalletconnectWallet from "../assets/walletconnect-wallet.png";
-import WalletconnectGuide from "../assets/walletconnect-guide.png";
+
export const metadata = createMetadata({
image: {
@@ -101,45 +98,3 @@ You and your partners can integrate your ecosystem wallet either as a full login
-# How to Register Your thirdweb Ecosystem Wallet with WalletConnect (now Reown)
-
-**Note:** WalletConnect Inc. is now Reown. [Read more here](https://reown.com/blog/walletconnect-is-now-reown).
-
-Registering your Ecosystem Wallet with Reown allows it to appear in the WalletConnect Explorer for seamless integration with platforms like OpenSea and other third-party applications.
-
-
-
-Visit the [Reown Dashboard](https://reown.com/) and select **"Create Project"**
-- Enter your [Ecosystem Wallet's Explorer](https://thirdweb.com/team/~/~/ecosystem/) page URL as the **Homepage URL** and proceed.
-- Choose **Wallet** as the project type and select **"Create"**
-
-
-
-
-
-
-
-Navigate to the **WalletGuide** tab and fill out the following form:
-- **Wallet Name:** Provide your wallet's name.
-- **Wallet Category:** Select **"Web App Wallets"**
-- **Web App URL:** Use your Ecosystem Wallet's Explorer page URL.
-- **Supported Chains:** Choose Ethereum and any other chains your wallet supports.
-- **Logo:** Upload your wallet’s logo (this will appear on the WalletConnect Explorer).
-- **Testing Instructions:** Provide clear testing instructions for the Reown team. For example: *"Log in via the specified URL and select an authentication method."*
-
-
-
-
-
-Once you've completed the form, click **"Submit Review"**
-- After approval, your wallet will appear live on the WalletConnect Explorer.
-
-
-
-Visit a platform like OpenSea and use WalletConnect to log in.
-- Select your registered wallet from the list and authenticate.
-- Your wallet should now seamlessly connect, allowing you to interact with the platform.
-
-
-
-By following these steps, your branded Ecosystem Wallet will be accessible across all WalletConnect-enabled (Reown) applications.
diff --git a/apps/portal/src/app/wallets/faq/page.mdx b/apps/portal/src/app/wallets/faq/page.mdx
index 4220ecdb560..57b9031c381 100644
--- a/apps/portal/src/app/wallets/faq/page.mdx
+++ b/apps/portal/src/app/wallets/faq/page.mdx
@@ -1,4 +1,8 @@
-import { createMetadata, Details } from "@doc";
+import { createMetadata, Details, DocImage, Callout, Step, Steps } from "@doc";
+import ManageWallet from '../export-private-key/manage-wallet.png'
+import ExportKey from '../export-private-key/export-key.png'
+import ConfirmReveal from '../export-private-key/confirm-reveal.png'
+import ExportedKey from '../export-private-key/exported-key.png'
export const metadata = createMetadata({
title: "Wallets FAQs | thirdweb documentation",
@@ -17,22 +21,12 @@ export const metadata = createMetadata({
View all the supported chains for wallets on [thirdweb chainlist](https://thirdweb.com/chainlist?service=connect-sdk).
-
- No, since our SDK provides the wallet signer, you can build a unified experience with the same code to handle how all your users' wallets interact with signatures and smart contracts.
-
- However, you will need to provide a separate flow to create in-app wallets as you would with any wallet provider (WalletConnect, Coinbase Wallet, etc.).
-
-
Make sure that you are developing on a [secure origin](https://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features/), which includes localhost and any site on https://. thirdweb uses cryptography libraries that are unsupported on http://.
If you continue to run into a console error, please [contact us](https://thirdweb.com/support) with more details.
-
- For a full list of supported authenticated options, we recommending searching the [playground](https://playground.thirdweb.com/wallets/sign-in/button). Wallets also supports custom authentication if you want to integrate thirdweb into your own auth system.
-
-
Yes, you can easily use account abstraction with in-app wallets to enable sponsored (gasless) transactions. Learn more in our [sponsor gas guide](/transactions/sponsor).
@@ -41,8 +35,10 @@ export const metadata = createMetadata({
Thirdweb wallets can be used as a signer to a smart contract account (account abstraction), but it can also be used as a standalone EOA.
-
- In the event that thirdweb ceases to exist, we have committed to keeping our in-app wallet service running for a period of at least 12 months after the shutdown announcement. During this time users will be able to access their wallet and transfer their assets out, or export their private key which they can then import into a different client.
+## User Wallets
+
+
+ For a full list of supported authenticated options, we recommending searching the [playground](https://playground.thirdweb.com/wallets/sign-in/button). Wallets also supports custom authentication if you want to integrate thirdweb into your own auth system.
@@ -51,11 +47,21 @@ export const metadata = createMetadata({
Users can also link their account to a different auth method (e.g. email, phone, or social). All linked methods will be able to be used to access their accounts, providing an alternate recovery method in the case where one is lost.
+
+ No, since our SDK provides the wallet signer, you can build a unified experience with the same code to handle how all your users' wallets interact with signatures and smart contracts.
+
+ However, you will need to provide a separate flow to create in-app wallets as you would with any wallet provider (WalletConnect, Coinbase Wallet, etc.).
+
+
+## Server Wallets
+
+## Ecosystem Wallets
+
Yes, you can change your Ecosystem Wallet name and icon. However, you cannot change the Ecosystem Wallet slug.
-## Security
+## Security & Recoverability
Learn more about the architecture of how thirdweb wallets are created and stored [in the security docs.](/wallets/security).
@@ -64,3 +70,48 @@ Yes, you can change your Ecosystem Wallet name and icon. However, you cannot cha
Using enclave, your customers' assets are safe even if thirdweb or you are compromised. This is because the attacker will only be able to access the encrypted keys, and that is not enough to reconstruct the private key.
+
+
+ Learn how to export the private key for a thirdweb wallet using the Connect modal.
+
+
+ It's not possible to export a user's private key programmatically. Our system is designed to be non-custodial and only users can access their full keys.
+
+
+
+
+ Login to your wallet on the application.
+
+
+
+ Select "Manage Wallet".
+
+
+
+
+ Choose "Export Private Key" and confirm the action to reveal the private key.
+
+
+
+
+ Confirm you want to reveal your private key.
+
+ Revealing private keys can compromise your assets and security. Keep them safe and confidential at all times.
+
+
+
+
+
+ Copy the exported private key directly from the modal.
+
+
+
+
+
+ As an advanced option, to hide the export private key option from the modal, set the `hidePrivateKeyOption` to `true` when initializing the typescript or react SDK.
+
+
+
+
+ In the event that thirdweb ceases to exist, we have committed to keeping our user service running for a period of at least 12 months after the shutdown announcement. During this time users will be able to access their wallet and transfer their assets out, or export their private key which they can then import into a different client.
+
diff --git a/apps/portal/src/app/wallets/link-profiles/page.mdx b/apps/portal/src/app/wallets/link-profiles/page.mdx
index 688f6973300..8ec4e119583 100644
--- a/apps/portal/src/app/wallets/link-profiles/page.mdx
+++ b/apps/portal/src/app/wallets/link-profiles/page.mdx
@@ -1,11 +1,12 @@
-import { createMetadata, ArticleIconCard, Callout, Tabs, TabsList, TabsTrigger, TabsContent } from "@doc";
+import { createMetadata, ArticleIconCard, Callout, Tabs, TabsList, TabsTrigger, TabsContent, OpenApiEndpoint } from "@doc";
import {
ReactIcon,
TypeScriptIcon,
UnityIcon,
DotNetIcon,
ExternalLinkIcon,
- UnrealEngineIcon
+ UnrealEngineIcon,
+ EngineIcon
} from "@/icons"
export const metadata = createMetadata({
@@ -22,8 +23,12 @@ export const metadata = createMetadata({
thirdweb Wallets allow users to tie the same wallet address to multiple social identities. Developers can programmatically link additional identities at any point in their user journey.
-
+
+
+
+ HTTP
+
TypeScript
@@ -46,6 +51,22 @@ thirdweb Wallets allow users to tie the same wallet address to multiple social i
+
+
+### Link Profile
+
+Link an additional authentication method to an existing wallet.
+
+
+
+### Unlink Profile
+
+Remove a linked authentication method from a wallet.
+
+
+
+
+
**OAuth Authentication (Discord, Google, Apple, etc.)**
@@ -210,8 +231,12 @@ var linkedAccounts = await ThirdwebManager.Instance.LinkAccount(mainInAppWallet,
Once linked, you can retrieve the user profiles via either identity.
-
+
+
+
+ HTTP
+
TypeScript
@@ -226,6 +251,12 @@ Once linked, you can retrieve the user profiles via either identity.
+
+
+Retrieve linked profiles using the [Fetch Users API](/wallets/get-users#http-api).
+
+
+
```typescript
import { getProfiles } from "thirdweb/wallets";
diff --git a/apps/portal/src/app/wallets/monitor/page.mdx b/apps/portal/src/app/wallets/monitor/page.mdx
new file mode 100644
index 00000000000..aa7f49ec5b7
--- /dev/null
+++ b/apps/portal/src/app/wallets/monitor/page.mdx
@@ -0,0 +1,82 @@
+import {
+ Grid,
+ Callout,
+ OpenSourceCard,
+ ArticleIconCard,
+ createMetadata,
+ Steps,
+ Step,
+ OpenApiEndpoint,
+} from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { WalletsSmartIcon } from "@/icons";
+import { TypeScriptIcon, DotNetIcon, EngineIcon } from "@/icons";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Monitor transactions",
+ icon: "wallets",
+ },
+ title: "Monitor Transactions | thirdweb Documentation",
+ description: "Monitor and get notified about transactions in your application.",
+});
+
+# Monitor Transactions
+
+Monitor and get notified about transactions in your application, both on your project dashboard and programmatically.
+
+
+
+
+
+ HTTP
+
+
+
+ TypeScript / React
+
+
+
+
+
+ ### Get transaction status
+
+ Get the information about a transaction by its id.
+
+
+
+ ### List transactions
+
+ List all transactions for your project with filtering and pagination.
+
+
+
+
+
+
+
+ You can track the status of transactions sent via the [transactions API](https://engine.thirdweb.com/reference) using its transaction id.
+
+ ```typescript
+ import { Engine } from "thirdweb";
+
+ const executionResult = await Engine.getTransactionStatus({
+ client,
+ transactionId, // the transaction id returned from enqueueTransaction
+ });
+ ```
+
+ You can also poll for the transaction hash with this convenience function:
+
+ ```typescript
+ import { Engine } from "thirdweb";
+
+ const { transactionHash } = await Engine.waitForTransactionHash({
+ client,
+ transactionId, // the transaction id returned from enqueueTransaction
+ });
+ ```
+
+
+
+
diff --git a/apps/portal/src/app/wallets/page.mdx b/apps/portal/src/app/wallets/page.mdx
index e2de2a49d17..a9697405d15 100644
--- a/apps/portal/src/app/wallets/page.mdx
+++ b/apps/portal/src/app/wallets/page.mdx
@@ -373,7 +373,7 @@ Retrieve authenticated user's wallet details:
2. Enter your Client ID and Bundle ID from the thirdweb dashboard
3. Allowlist your game's Bundle ID on the thirdweb dashboard for security
- ### Implementing In-App Wallets
+ ### Implementing User Wallets
Enable email login in Unity:
diff --git a/apps/portal/src/app/wallets/security/page.mdx b/apps/portal/src/app/wallets/security/page.mdx
index 96194a76b46..c943c21e6cf 100644
--- a/apps/portal/src/app/wallets/security/page.mdx
+++ b/apps/portal/src/app/wallets/security/page.mdx
@@ -1,4 +1,4 @@
-import { DocImage, Callout, createMetadata } from "@doc";
+import { DocImage, Callout, createMetadata, Tabs, TabsList, TabsContent, TabsTrigger } from "@doc";
import EnclaveWalletCreation from "./assets/enclave-wallet-creation.png";
import AppScoped from "./assets/app-scoped.svg";
import EcosystemScoped from "./assets/ecosystem-scoped.svg";
@@ -15,6 +15,17 @@ export const metadata = createMetadata({
# Wallet Security & Architecture
+
+
+
+ User Wallets
+
+
+ Server Wallets
+
+
+
+
## Wallet Creation
When a user signs into an application using their email or social logins for the first time, a wallet is generated within a secure enclave on the server after verifying the user's legitimacy. The enclave provides a trusted execution environment, ensuring the wallet creation process is isolated and protected from external interference.
@@ -95,3 +106,87 @@ thirdweb complies to GDPR and CCPA compliance frameworks and deletes customer da
### Audit and Bounty Program
Halborn has audited our enclave wallet security architecture which we'll be releasing shortly, and there is an ongoing bounty program to ensure vulnerabilities are caught. [View the Letter of Attestation.](/pdfs/thirdweb_code_security_audit.pdf)
+
+
+
+
+## Non Custodiality
+Vault guarantees non-custodiality through cryptography. All private and sensitive data is stored encrypted, and can only be decrypted within the secure enclave. The code running within the secure enclave is open-source, audited, and attested.
+
+## Attestation
+At any time, you can request an attestation document from Vault. This attestation document is signed by AWS (independently verifiable).
+
+The attestation document allows you to verify that the code being run inside the secure enclave has not been tampered, and is the same as the open source code that you can access.
+
+The code running inside a nitro enclave is an Enclave Image File (EIF). The EIF has unique PCR values which will change upon tampering.
+
+In the context of AWS Nitro Enclaves, an Enclave Image File (EIF) measurement, specifically the Platform Configuration Register (PCR) values, are cryptographic hashes that uniquely identify the enclave's image and its contents. PCRs are used to verify that the enclave has been loaded and is running in a known, trusted state, ensuring its integrity and preventing unauthorized modification
+
+The master key of the Vault can only be accessed by this exact code running inside the enclave. To verify this, you can query Vault to check the current AWS policy on the master key, and confirm that only nitro-enclaves with this specific PCR measurement have access to these resources.
+
+## Verify, Don’t Trust
+You can compile your own EIF from the Vault source-code, and retrieve PCR values. This allows you to compare the PCR values you received from Vault against the PCR measurements you generated yourself, proving that a hosted Vault service is running untampered code.
+
+## Chain of Verification
+Armed with proof that the Vault service is running untampered code, you can audit the code to ensure Vault behaves as expected.
+
+For example: how can you verify that Vault is not lying about who can access it’s keys?
+
+You can look at the Vault code to confirm that it does indeed query the correct AWS APIs to fetch the current policies on it’s keys, and then returns it without modifications.
+
+If you know the code is correct, and if you know that the service is running untampered code, then you can confirm that the correct data is being returned to you.
+
+But how can you confirm that data from the Vault hasn’t been tampered by other non-enclave components your response might be coming through? To solve this, Vault uses an end to end encrypted communication protocol with perfect forward secrecy.
+
+This same approach can be used to verify that all entities are always stored encrypted, and access is only granted to authorized requests. To further prevent data leakage, Vault uses HMAC hashes instead of raw identifiers to associate entities with each other in the encrypted database. This means Vault can not-only guarantee non-custodial access to entities, but also preserves privacy between entities and their owners. E2E encryption also means that all your operations and responses remain private and untampered.
+
+## End to End Encryption
+Every sensitive request to Vault is made to the `/v1/enclave/post` endpoint with a payload that looks like this:
+
+```
+{
+ "ephemeralPublicKey": "05d7deb3ef80f929ee6d1afdbf63d43e68ae9d1a045577cf6a2cbc29baaa5c5f",
+ "nonce": "716d11684ed4a973ff401e9bc84db48608c1f78abdba59a2",
+ "ciphertext": "ed0665497121ca59ef610f976f0a3beaa494c17b65ca127e72f286fa3464fde3f14e305d9fded6090bd5fd7fd2fd57d93d399619fe950d71790daec1b753d5b221d914e6e29c6734e6a38c7d237a91fea289f4812eeefae88281cc9cae8e7421ca1d81a5ac4181d889a9a082fbaf7cd5c650a2c8ccf61981d9fc3535a76733e0b00dbad4a2492c399b8a49c00f89d11283fe408754e470f5ec3579fac2aedc4c042eb75dd6804cf0fa331d5da039cfad6e36f5d00e7c6e78b5e0956a36af01761c31b0d85d90b3d15e0808a544c3f15ba1d3ae108efd36add25791ee6d27d58d9bf7c87903bbd5c54ed52c3b501eb9c67ff374308d95b7acabd7e02375fd0aab6668008583740f1883ed0c00731f732ecd4d46498939f223b1eba1c0c536cea12cf85370c17ef30fce992c129938e1f049c64c2cadafd1efc93692445c47923f6bb9ffbb8226fbf7f5bfa5a14060a2085c1df145294397a7035761c20fdac820a57ed4bdd591941a9d9804c3c92c1e5e0f60857a68516b330816c57e133b4dfcf492cdc1f9ab3d9097babd997552adbb90c871e82fbab041555f0ab4ae3fb93adf4a3ba2182d76787d58568275849595564eb10e601f7ede972f2c6d8429112f90ce4aa09177ca2811d7025100cd3621edcc8b091d2e943afdc44f91d2f60abb3daae1"
+}
+```
+
+The communication protocol ensures that requests can only be decrypted by the Vault-enclave, and responses can only be decrypted by you. The protocol also provides perfect forward secrecy, meaning even if cryptographic keys for a previous request is exposed, future requests still remain non-compromised.
+
+### Protocol
+Vault uses the xChaCha20Poly1305 cryptographic cipher, combined with the x25519dalek for zero round trip key-exchange.
+
+**Step 1**
+The client queries the Vault’s xChaCha20Poly1305 public-key from the `GET api/v1/enclave` endpoint.
+
+**Step 2**
+The client generates a random 32 byte ephemeral secret key (and stores it to decrypt the response too)
+
+**Step 3**
+The client derives a shared secret using xChaCha20Poly1305:
+
+```shared_secret = diffie_hellman(client_ephemeral_secret_key, vault_public_key)```
+
+**Step 4**
+The client derives an encryption key from the `shared_secret` using HKDF
+
+**Step 5**
+The client generates a random 24 byte nonce
+
+The client generates the `ciphertext` using xChaCha20Poly1305 with the random nonce, and the derives encryption key
+
+**Sending the Payload**
+The generated ciphertext, nonce, and the public key to the ephemeral secret are all hex encoded and sent as the payload
+
+**Decrypting the Response**
+The response also arrives in the same payload format. We just perform the steps in reverse now.
+
+1. Use `x25519dalek` `diffie_hellman` to derive a shared_secret from the:
+- private key we used for sending the request
+- the public key returned in the response
+2. HKDF the `shared_secret` to get the `encryption_key`
+3. Use the `nonce` in the response (which Vault randomly generates) + the `shared_secret` with xChaCha20Poly1305 to decrypt your payload.
+
+
+
+
\ No newline at end of file
diff --git a/apps/portal/src/app/wallets/sidebar.tsx b/apps/portal/src/app/wallets/sidebar.tsx
index 52e6409dd35..fc056d1a6f7 100644
--- a/apps/portal/src/app/wallets/sidebar.tsx
+++ b/apps/portal/src/app/wallets/sidebar.tsx
@@ -12,69 +12,92 @@ export const sidebar: SideBar = {
name: "Get Started",
icon: ,
},
- {
- href: "https://playground.thirdweb.com/",
- icon: ,
- name: "Playground",
- },
{ separator: true },
{
isCollapsible: false,
links: [
{
href: `${walletSlug}/users`,
- name: "User Wallets",
+ name: "QuickStart",
},
{
- href: `${walletSlug}/server`,
- name: "Server Wallets",
+ href: `${walletSlug}/get-users`,
+ name: "Fetch Users",
+ },
+ {
+ href: `${walletSlug}/pregenerate-wallets`,
+ name: "Pregenerate Wallets",
+ },
+ {
+ href: `${walletSlug}/custom-auth`,
+ name: "Custom Authentication",
},
{
href: `${walletSlug}/external-wallets`,
name: "External Wallets",
},
{
- href: `${walletSlug}/ecosystem/set-up`,
- name: "Ecosystem Wallets",
+ href: `${walletSlug}/auth`,
+ name: "Sign in with Ethereum",
},
{
- href: `/transactions/sponsor`,
- name: "Sponsor Gas",
+ href: `${walletSlug}/link-profiles`,
+ name: "Link Profiles",
},
{
- href: `${walletSlug}/get-users`,
- name: "Fetch Users",
+ href: `${walletSlug}/adapters`,
+ name: "Adapters",
},
+ ],
+ name: "User Wallets",
+ },
+ {
+ isCollapsible: false,
+ name: "Ecosystem Wallets",
+ links: [
{
- href: `${walletSlug}/pregenerate-wallets`,
- name: "Pregenerate Wallets",
+ href: `${walletSlug}/ecosystem/set-up`,
+ name: "QuickStart",
},
{
- href: `${walletSlug}/custom-auth`,
- name: "Bring your own Auth",
+ href: `${walletSlug}/ecosystem/reown`,
+ name: "Add to Reown",
},
+ ],
+ },
+ { separator: true },
+ {
+ isCollapsible: false,
+ name: "Server Wallets",
+ links: [
{
- href: `${walletSlug}/auth`,
- name: "Sign in with Ethereum",
+ href: `${walletSlug}/server`,
+ name: "QuickStart",
},
{
- href: `${walletSlug}/link-profiles`,
- name: "Link Profiles",
+ href: `${walletSlug}/monitor`,
+ name: "Monitor Transactions",
+ },
+ ],
+ },
+ { separator: true },
+ {
+ isCollapsible: false,
+ name: "Gas Sponsorship",
+ links: [
+ {
+ href: `${walletSlug}/sponsor-gas`,
+ name: "QuickStart",
},
{
- href: `${walletSlug}/export-private-key`,
- name: "Export Private Keys",
+ href: `${walletSlug}/sponsorship-policies`,
+ name: "Sponsorship Policies",
},
{
href: `${walletSlug}/session-keys`,
name: "Session Keys",
},
- {
- href: `${walletSlug}/adapters`,
- name: "Usage with other libraries",
- },
],
- name: "Guides",
},
{ separator: true },
{
@@ -124,12 +147,17 @@ export const sidebar: SideBar = {
name: "Resources",
links: [
{
- href: `${walletSlug}/security`,
- name: "Security",
+ href: "https://playground.thirdweb.com/wallets",
+ name: "Playground",
+ icon: ,
},
{
- href: "/vault",
- name: "Vault",
+ href: `${walletSlug}/wallet-types`,
+ name: "Wallet Types",
+ },
+ {
+ href: `${walletSlug}/security`,
+ name: "Security",
},
{
href: `${walletSlug}/faq`,
diff --git a/apps/portal/src/app/wallets/sponsor-gas/page.mdx b/apps/portal/src/app/wallets/sponsor-gas/page.mdx
index 35d89531e3f..cb36a78b176 100644
--- a/apps/portal/src/app/wallets/sponsor-gas/page.mdx
+++ b/apps/portal/src/app/wallets/sponsor-gas/page.mdx
@@ -6,24 +6,25 @@ import {
createMetadata,
Steps,
Step,
+ OpenApiEndpoint,
} from "@doc";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { WalletsSmartIcon } from "@/icons";
-import { TypeScriptIcon, DotNetIcon } from "@/icons";
+import { TypeScriptIcon, DotNetIcon, EngineIcon } from "@/icons";
export const metadata = createMetadata({
image: {
- title: "Sponsor Gas",
+ title: "Gas Sponsorship",
icon: "wallets",
},
- title: "Sponsor Gas | thirdweb Documentation",
+ title: "Gas Sponsorship | thirdweb Documentation",
description:
"Enable gasless transactions using EIP-7702 or ERC-4337. thirdweb lets you sponsor gas fees so users can sign and send transactions with zero friction.",
});
-# Sponsor gas
+# Gas Sponsorship
-Sponsor gas fees for your users by configuring `executionMode` in the in-app wallet options.
+Sponsor gas fees for transactions using EIP-7702 or ERC-4337. Thirdweb will handle the gas fees for you.
@@ -35,10 +36,14 @@ Sponsor gas fees for your users by configuring `executionMode` in the in-app wal
## EIP-7702 (recommended)
-Sponsor gas fees for your users' in-app wallets using [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), enabling gasless transactions and improving user experience.
+Sponsor gas fees using [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), enabling gasless transactions and improving user experience.
-
+
+
+
+ HTTP
+
TypeScript / React
@@ -49,7 +54,20 @@ Sponsor gas fees for your users' in-app wallets using [EIP-7702](https://eips.et
+
+
+ EIP-7702 is the default execution mode in the [thirdweb API](/reference) for your user and server wallets.
+
+Example sponsored contract write request:
+
+
+
+
+
+
+ You can enable EIP-7702 execution for in-app wallets by passing the `executionMode` option to the `inAppWallet` function.
+
```typescript
const wallet = inAppWallet({
// enable gasless transactions for the wallet
@@ -59,9 +77,22 @@ Sponsor gas fees for your users' in-app wallets using [EIP-7702](https://eips.et
},
});
```
+
+ For server wallets, EIP-7702 execution is the default execution mode when initializing a server wallet with a signer (EOA) address.
+
+ ```typescript
+ const wallet = await Engine.serverWallet({
+ client,
+ address: "0x...", // your server wallet signer (EOA) address
+ });
+ ```
+
+
+ You can enable EIP-7702 execution for in-app wallets by passing the `executionMode` option.
+
```csharp
var smartEoa = await InAppWallet.Create(
client: thirdwebClient,
@@ -72,29 +103,66 @@ Sponsor gas fees for your users' in-app wallets using [EIP-7702](https://eips.et
+
+
That's it! All transactions executed by the user will be sponsored via the thirdweb infrastructure.
-## EIP-4337
+## ERC-4337
+
+For chains that don't support EIP-7702, you can use EIP-4337 smart contract wallets to sponsor gas fees. Note that with EIP-4337, it will create a smart contract wallet with a different address than the admin wallet (EOA) that controls it.
+
+
+
+
+
+ HTTP
+
+
+
+ TypeScript / React
+
+
+
+ .NET / Unity
+
+
+
+
+
+ERC4337 execution is not supported in the high level thirdweb API, but you can use the lower level [Engine transactions API](https://engine.thirdweb.com/reference#tag/write/post/v1/write/contract) with specific execution options:
+
+```http
+POST https://engine.thirdweb.com/v1/write/contract
+Content-Type: application/json
+x-secret-key:
+
+{
+ "executionOptions": {
+ "type": "ERC4337",
+ "signerAddress": "0x...", // the EOA that has sign permissions on the smart wallet
+ "smartAccountAddress": "0x...", // optional, the address of the smart wallet to act on behalf of
+ "chainId": "1", // your chain id
+ },
+ "params": [{
+ "contractAddress": "0x...",
+ "method": "function transfer(address to, uint256 amount)",
+ "params": ["0x...", "1000000000000000000"],
+ }],
+}
+```
+
+View all the available execution options in the [transactions API reference](https://engine.thirdweb.com/reference#tag/write/post/v1/write/contract).
+
+
-For chains that don't support EIP-7702, you can use EIP-4337 smart contract wallets to sponsor gas fees. Note that with EIP-4337, you need to create a smart contract wallet for the user with a different address than the admin wallet (EOA) that controls it.
+
-
-
-
-
- TypeScript / React
-
-
-
- .NET / Unity
-
-
+ For user wallets, you can enable ERC-4337 execution by passing the `smartAccount` option to the `inAppWallet` function.
-
```typescript
const wallet = inAppWallet({
// will create a smart contract wallet for the user
@@ -110,6 +178,9 @@ For chains that don't support EIP-7702, you can use EIP-4337 smart contract wall
+
+ You can enable ERC-4337 execution for any wallet by creating a smart wallet with the `SmartWallet.Create` function.
+
```csharp
var adminWallet = await InAppWallet.Create(
client: thirdwebClient,
diff --git a/apps/portal/src/app/wallets/sponsorship-policies/page.mdx b/apps/portal/src/app/wallets/sponsorship-policies/page.mdx
new file mode 100644
index 00000000000..7cceeec29ff
--- /dev/null
+++ b/apps/portal/src/app/wallets/sponsorship-policies/page.mdx
@@ -0,0 +1,75 @@
+import { createMetadata } from "@doc";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Gas Sponsorship Policies",
+ icon: "wallets",
+ },
+ title: "Gas Sponsorship Policies | thirdweb Documentation",
+ description:
+ "Configure sponsorship policies to control the execution of sponsored transactions on your account. Set spend limits, restrict chains, contracts, and wallets.",
+});
+
+# Gas Sponsorship Policies
+
+Sponsorship policies are a way to control the execution of sponsored transactions on your account.
+
+You can use them to:
+
+- Set global spend limits.
+- Restrict sponsorship to a particular chain.
+- Restrict sponsorship to a particular contract.
+- Allow/Disallow specific wallets
+- Setup your own server verifier.
+
+These policies can be set from your project dashboard, under project > account abstraction > settings.
+
+## Server Verifier
+
+The most flexible and powerful way to control the execution of sponsored transactions is to setup your own server verifier.
+
+In the project dashboard, under project > account abstraction > settings, setup your backend URL and any additional headers you need to pass to the verifier.
+
+On every user transaction, your backend will be called with the transaction data and the user's wallet address, your endpoint should return a boolean indicating whether the transaction should be sponsored.
+
+### Backend endpoint specification:
+
+Your backend will be called with the following request:
+
+```http
+POST https://your-backend-url/verify-transaction
+Content-Type: application/json
+Referer: "https://api.thirdweb.com",
+# additional custom headers
+
+# request body
+{
+ "clientId": string;
+ "chainId": number;
+ "userOp": {
+ sender: string;
+ targets: string[];
+ gasLimit: string;
+ gasPrice: string;
+ data?: {
+ targets: string[];
+ callDatas: string[];
+ values: string[];
+ };
+ }
+}
+```
+
+Your backend should process the request, apply your own policy logic based on the request data and return the following JSON response:
+
+```http
+HTTP/1.1 200 OK
+Content-Type: application/json
+
+{
+ "isAllowed": boolean;
+ "reason"?: string;
+}
+```
+
+The `isAllowed` field indicates whether the transaction should be sponsored or not. `reason` is an optional field that can be used to provide a reason for the decision.
diff --git a/apps/portal/src/app/wallets/wallet-types/page.mdx b/apps/portal/src/app/wallets/wallet-types/page.mdx
new file mode 100644
index 00000000000..a2eac2c1a82
--- /dev/null
+++ b/apps/portal/src/app/wallets/wallet-types/page.mdx
@@ -0,0 +1,63 @@
+import { ArticleIconCard, AuthList, Callout, DocImage, Grid, Stack, createMetadata } from "@doc";
+
+export const metadata = createMetadata({
+ title: "Wallet Types | thirdweb Documentation",
+ description:
+ "Understand the different types of wallets supported by thirdweb, including user wallets, server wallets, external wallets (EOAs), and ecosystem wallets. Learn which wallet type is best suited for your application needs.",
+ image: {
+ title: "Wallet Types",
+ icon: "wallets",
+ },
+});
+
+# Understand Different Wallet Types
+
+## User Wallets
+
+User wallets (also called _Embedded Wallets_) are automatically generated for users when they sign in through supported authentication methods like email, social login, or custom auth.
+
+They’re stored securely in a trusted environment (such as a secure enclave or MPC) and give users a seamless, traditional onboarding experience without needing to handle seed phrases.
+
+**Best for:**
+
+- Apps that want a frictionless login + wallet experience
+- Users new to crypto
+- Applications managing authentication and wallet creation together
+
+## Server Wallets
+
+**Server wallets** (also known as **developer wallets** or **backend wallets**) are controlled by the backend and used for performing programmatic actions such as minting tokens, settling payments, or automating on-chain operations.
+
+**Best for:**
+
+- Server-side scripts and backend operations
+- API payment facilitation and settlement flows
+- Secure automation of transactions
+
+## External Wallets (EOAs)
+
+External wallets are self-custodial wallets owned and managed directly by users. Examples include MetaMask, Coinbase Wallet, Phantom, and more.
+
+**Best for:**
+
+- Web3-native users comfortable managing their keys
+- Dapps requiring wallet signatures or on-chain transactions
+- Direct blockchain interaction via the browser
+
+## Ecosystem Wallet
+
+Ecosystem Wallets are embedded wallets that support brand-customization and provide a single identity across multiple applications or games.
+
+**Best for:**
+
+- Platforms or ecosystems that include multiple apps, games, or partner integrations
+- Managing access controls, permissions, and partner integrations programmatically
+
+## Summary
+
+| | **Custody** | **Security** | **Export Private Keys** | **App-Scoped** | Managed By |
+| ------------------------- | ------------- | ------------------------ | ----------------------- | -------------- | ---------- |
+| **User Wallet** | Non-custodial | Enclaves | ✅ | ✅ | User |
+| **Server Wallet** | Non-custodial | Vault (KMS) | ✅ | ❌ | Developer |
+| **External Wallet (EOA)** | Non-custodial | User Managed Private Key | ✅ | ❌ | User |
+| **Ecosystem Wallet** | Non-custodial | Enclaves | ❌ | ⚠️ | User |
\ No newline at end of file
diff --git a/apps/portal/src/app/x402/faq/page.mdx b/apps/portal/src/app/x402/faq/page.mdx
new file mode 100644
index 00000000000..1a588e2f1e7
--- /dev/null
+++ b/apps/portal/src/app/x402/faq/page.mdx
@@ -0,0 +1,30 @@
+import { createMetadata, Details } from "@doc";
+
+export const metadata = createMetadata({
+ title: "x402 FAQs | thirdweb documentation",
+ description: "Get answers to common questions about thirdweb x402, including internet native payments, API payments, and integration details.",
+ image: {
+ title: "x402 FAQs",
+ icon: "wallets",
+ },
+});
+
+# x402 FAQ
+
+## General
+
+
+Use client-side integration when end users are paying directly from their own wallets. For example, in applications or AI agents where users sign transactions themselves.
+
+Use server-side integration when your backend or service handles payments such as when sponsoring user payments, automating paid API calls, or keeping API keys and logic secure.
+
+
+
+Using thirdweb's facilitator you are able to support more tokens and chains than any other facilitator in the ecosystem.
+
+You also have a built-in faciltator wallet to easily use and manage gas funds without worrying about topping up funds.
+
+
+
+Yes, if you use the thirdweb facilitator your endpoint will auto-register to [Nexus](https://nexus.thirdweb.com) for discovery by AI agents.
+
\ No newline at end of file
diff --git a/apps/portal/src/app/x402/sidebar.tsx b/apps/portal/src/app/x402/sidebar.tsx
index 3e7f44c2a57..c17ed4ed195 100644
--- a/apps/portal/src/app/x402/sidebar.tsx
+++ b/apps/portal/src/app/x402/sidebar.tsx
@@ -45,9 +45,9 @@ export const sidebar: SideBar = {
isCollapsible: false,
links: [
{
- href: `https://payments.thirdweb.com/reference`,
+ href: `/reference`,
icon: ,
- name: "REST API",
+ name: "HTTP API",
},
{
href: "/references/typescript/v5",
@@ -72,6 +72,17 @@ export const sidebar: SideBar = {
],
name: "API References",
},
+ { separator: true },
+ {
+ isCollapsible: false,
+ links: [
+ {
+ href: `${x402Slug}/faq`,
+ name: "FAQ",
+ },
+ ],
+ name: "Resources",
+ },
],
name: "x402",
};