Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/playground-web/src/app/ai/api/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export async function promptNebula(params: {

if (data.type === "sign_transaction") {
try {
const parsedTxData = JSON.parse(data.data) as NebulaTxData;
const parsedTxData = data.data as NebulaTxData;
params.handleStream({
data: parsedTxData,
event: "action",
Expand All @@ -133,7 +133,7 @@ export async function promptNebula(params: {

if (data.type === "sign_swap") {
try {
const swapData = JSON.parse(data.data) as NebulaSwapData;
const swapData = data.data as NebulaSwapData;
params.handleStream({
data: swapData,
event: "action",
Expand Down
4 changes: 2 additions & 2 deletions apps/playground-web/src/app/ai/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export type NebulaUserMessage = {
};

export type NebulaTxData = {
chainId: number;
chain_id: number;
data: `0x${string}`;
to: string;
value?: string;
value: string;
};
2 changes: 1 addition & 1 deletion apps/playground-web/src/app/ai/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ export default function ChatPage() {
}

export const metadata = {
title: "AI Chat API - Playground",
title: "Blockchain LLM - Playground",
description: "Chat with thirdweb AI for blockchain interactions",
};
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ type ChatMessage =
};

type NebulaTxData = {
chainId: number;
chain_id: number;
data: `0x${string}`;
to: string;
value?: string;
Expand Down Expand Up @@ -703,7 +703,7 @@ function RenderMessage(props: {
transaction={() =>
prepareTransaction({
client: THIRDWEB_CLIENT,
chain: defineChain(message.data.chainId),
chain: defineChain(message.data.chain_id),
data: message.data.data,
to: message.data.to,
value: message.data.value
Expand All @@ -719,7 +719,7 @@ function RenderMessage(props: {
props.sendMessage({
content: [
{
chain_id: message.data.chainId,
chain_id: message.data.chain_id,
transaction_hash: tx.transactionHash,
type: "transaction",
},
Expand All @@ -734,7 +734,7 @@ function RenderMessage(props: {
) : (
<ConnectButton
client={THIRDWEB_CLIENT}
chain={defineChain(message.data.chainId)}
chain={defineChain(message.data.chain_id)}
/>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/playground-web/src/app/navLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ai: ShadcnSidebarLink = {
links: [
{
href: "/ai/chat",
label: "Chat API",
label: "Blockchain LLM",
},
],
};
Expand Down
2 changes: 1 addition & 1 deletion apps/portal/src/app/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const apisLinks = [
const aiLinks = [
{
href: "/ai/chat",
name: "Chat API",
name: "Blockchain LLM",
},
{
href: "/ai/mcp",
Expand Down
59 changes: 59 additions & 0 deletions apps/portal/src/app/ai/chat/execution/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {OpenApiEndpoint} from "@doc";

# Transaction Execution

thirdweb AI can either auto execute transactions or prepare them for signing.

- **Auto Execute**: The API will auto execute the transaction. Requires wallet authentication.
- **Prepare for Signing**: The API will only prepare the transaction for signing. The user will need to sign the transaction manually.

## Auto Execute

Requirements:

- The context object must be set with:
- `from` set to the wallet address to execute the transaction from
- `auto_execute_transaction` set to `true`
- (Optional) `chain_ids` set to the chain IDs to execute the transaction on
- The API must be called with either:
- your `x-secret-key` header for server wallet authentication
- OR a `Authorization` header with a valid wallet JWT for user wallet authentication

Comment on lines +14 to +21
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Confirm header names and JWT format across the codebase

Ensure you’re consistently using exactly x-secret-key and Authorization: Bearer <token> in all AI docs and examples (Playground, Portal, SDK README).


🏁 Script executed:

#!/usr/bin/env bash
# Verify consistent header naming across docs and app sources
rg -nP -C2 '(x-secret-key|Authorization:?\s*Bearer)' apps/portal apps/playground-web packages --type-not=lock --hidden

Length of output: 74588


🏁 Script executed:

#!/usr/bin/env bash

# Show first 40 lines of the execution docs to confirm how Authorization is described
sed -n '1,40p' apps/portal/src/app/ai/chat/execution/page.mdx

# Show the streaming docs to see if JWT auth is mentioned or needs to be added
sed -n '60,100p' apps/portal/src/app/ai/chat/streaming/page.mdx

Length of output: 2494


Consistent Authorization: Bearer header in AI chat docs

The AI chat execution docs still reference a generic Authorization header without the Bearer prefix, and the code examples don’t explicitly show it. Please update the following:

  • apps/portal/src/app/ai/chat/execution/page.mdx
    • Change “OR a Authorization header with a valid wallet JWT”
    to
    “OR an Authorization: Bearer <YOUR_WALLET_JWT> header with a valid wallet JWT”
    • In the <OpenApiEndpoint> example, add a headers override:
    <OpenApiEndpoint path="/ai/chat" method="POST" requestBodyOverride={…} responseExampleOverride={…}
    ->
    + components={{
    +   request: {
    +     headers: {
    +       "x-secret-key": "<YOUR_SECRET_KEY>",
    +       "Authorization": "Bearer <YOUR_WALLET_JWT>"
    +     }
    +   }
    + }}
    />
  • apps/portal/src/app/ai/chat/streaming/page.mdx
    • If the streaming endpoint supports user‐wallet authentication, add a note and example:
    - Headers:
    -   - `x-secret-key`: `<your-secret-key>`
    + Headers (server OR user auth):
    +   - `x-secret-key`: `<your-secret-key>`  
    +   OR  
    +   - `Authorization: Bearer <YOUR_WALLET_JWT>`
  • Playground and SDK README
    • Verify that all AI/chat examples use exactly
    x-secret-key for server calls
    and
    Authorization: Bearer <token> for user calls.

This will ensure all AI docs and samples are aligned.

🧰 Tools
🪛 LanguageTool

[grammar] ~16-~16: There might be a mistake here.
Context: ...m - auto_execute_transaction set to true - (Optional) chain_ids set to the chain ...

(QB_NEW_EN)


[grammar] ~17-~17: There might be a mistake here.
Context: ... chain IDs to execute the transaction on - The API must be called with either: - ...

(QB_NEW_EN)


[grammar] ~18-~18: There might be a mistake here.
Context: ...on - The API must be called with either: - your x-secret-key header for server wa...

(QB_NEW_EN)


[grammar] ~19-~19: There might be a mistake here.
Context: ... header for server wallet authentication - OR a Authorization header with a valid...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In apps/portal/src/app/ai/chat/execution/page.mdx around lines 14-21, the docs
reference a generic Authorization header and lack explicit examples; update the
sentence to read “OR an Authorization: Bearer <YOUR_WALLET_JWT> header with a
valid wallet JWT”, and modify the <OpenApiEndpoint> example to include a headers
override that demonstrates either x-secret-key or Authorization: Bearer
<YOUR_WALLET_JWT>; also update apps/portal/src/app/ai/chat/streaming/page.mdx to
note support for user-wallet authentication and replace the headers block with a
“Headers (server OR user auth):” example showing x-secret-key OR Authorization:
Bearer <YOUR_WALLET_JWT>; finally, scan Playground and SDK README examples to
ensure all AI/chat samples consistently use x-secret-key for server calls and
Authorization: Bearer <token> for user calls, correcting any mismatches.

Model behavior:

If all the requirements are met, the transaction will be executed automatically and the model will return a message with the transaction ID.

It will also include an `actions` array with a `monitor_transaction` action. This action can be used to monitor the transaction status and get the transaction receipt via the thirdweb API.

<OpenApiEndpoint path="/ai/chat" method="POST" requestBodyOverride={{
"messages": [
{
"role": "user",
"content": "Transfer 10 USDC to vitalik.eth"
}
],
"context": {
"from": "0x...",
"auto_execute_transaction": true,
"chain_ids": [8453]
}
}} responseExampleOverride={{
"message": "I've sent 10 USDC to Vitalik's wallet with transaction ID 11cd95e3-c0ee-4468-97c1-fd05dc919cdb. It should be confirmed in a few seconds.",
"session_id": "123",
"request_id": "456",
"actions": [{
"session_id": "8d1bfac4-e6c0-473b-bbb6-649f459d37e6",
"request_id": "79066871-b86f-4814-8027-5f34d99df389",
"source": "model",
"type": "monitor_transaction",
"data": {
"transaction_id": "11cd95e3-c0ee-4468-97c1-fd05dc919cdb"
}
}]
}} />

## Prepare for Signing

When the `auto_execute` parameter is set to `false` or omitted, the API will prepare the transaction for signing and return the transaction data in the `actions` array as a 'sign_transaction' action type.

<OpenApiEndpoint path="/ai/chat" method="POST" />
8 changes: 4 additions & 4 deletions apps/portal/src/app/ai/chat/page.mdx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Tabs, TabsContent, TabsList, TabsTrigger, OpenApiEndpoint } from "@doc";

# Chat API
# Blockchain LLM

The thirdweb AI chat API is a standard OpenAI-compatible chat completion API that allows you to interact with the thirdweb AI model, optimized for blockchain interactions.
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.

- Query real-time data from the blockchain
- Analyze transactions
- Fetch token balances, prices and metadata
- Prepare any contract call or transaction for signing
- Prepare swaps from/to any token pair
- Execute or prepare any contract call or transaction
- Execute or prepare swaps from/to any token pair
- Deploy contracts
- Generate images
- Search the web
Expand Down
38 changes: 24 additions & 14 deletions apps/portal/src/app/ai/chat/streaming/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,12 @@ data: {
"request_id": "9efc7f6a-8576-4d9c-8603-f6c72aa72164",
"type": "sign_transaction",
"source": "executor",
"data": "{\"chainId\": 11155111, \"to\": \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\", \"data\": \"0x\", \"value\": \"0x5af3107a4000\"}"
"data": {
"chain_id": 11155111,
"to": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"data": "0x",
"value": "0x5af3107a4000"
}
}
```

Expand Down Expand Up @@ -90,52 +95,57 @@ for await (const event of events) {
if (!event.data) {
continue;
}
const parsedEventData = JSON.parse(event.data);
switch (event.event) {
case "init": {
console.log("Init event", event.data);
console.log("Init event", parsedEventData);
// handle init event (session id and request id)
break;
}
case "presence": {
console.log("Presence event", event.data);
console.log("Presence event", parsedEventData);
// handle intermediate thinking steps
break;
}
case "delta": {
console.log("Delta event", event.data);
console.log("Delta event", parsedEventData);
// handle delta event (streamed output text response)
break;
}
case "action": {
const data = JSON.parse(event.data);

// handle transaction signing
if (data.type === "sign_transaction") {
const transactionData = JSON.parse(data.data);
if (parsedEventData.type === "sign_transaction") {
const transactionData = parsedEventData.data;
console.log("Sign transaction event", transactionData);
}

// handle swap signing
if (data.type === "sign_swap") {
const swapData = JSON.parse(data.data);
if (parsedEventData.type === "sign_swap") {
const swapData = parsedEventData.data;
console.log("Sign swap event", swapData);
}

// handle transaction monitoring
if (parsedEventData.type === "monitor_transaction") {
const transactionId = parsedEventData.data.transaction_id;
console.log("Monitor transaction event", transactionId);
}

break;
}
case "image": {
const data = JSON.parse(event.data);
const imageData = parsedEventData.data;
// handle image rendering
console.log("Image data", data);
console.log("Image data", imageData);
break;
}
case "context": {
console.log("Context event", event.data);
console.log("Context event", parsedEventData);
// handle context changes (chain ids, wallet address, etc)
break;
}
case "error": {
console.log("Error event", event.data);
console.log("Error event", parsedEventData);
// handle error event (error message)
break;
}
Expand Down
6 changes: 5 additions & 1 deletion apps/portal/src/app/ai/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { SideBar } from "@/components/Layouts/DocLayout";
export const sidebar: SideBar = {
links: [
{
name: "Chat API",
name: "Blockchain LLM",
isCollapsible: false,
links: [
{
Expand All @@ -17,6 +17,10 @@ export const sidebar: SideBar = {
href: "https://playground.thirdweb.com/ai/chat",
icon: <ExternalLinkIcon />,
},
{
name: "Transaction Execution",
href: "/ai/chat/execution",
},
Comment on lines +20 to +23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

New “Transaction Execution” doc link — verify route exists and is indexed

The link points to /ai/chat/execution. It looks like the MDX page was added in this PR; please also ensure it’s discoverable (sitemap/search index) and that the frontmatter includes title/description so it renders well in listings.

Run this quick check from repo root:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# 1) Route file presence
test -f apps/portal/src/app/ai/chat/execution/page.mdx && echo "OK: execution page exists"

# 2) Basic frontmatter or H1
rg -n --hidden -C2 -S $'^---\\n|^title:\\s*|^#\\s*' apps/portal/src/app/ai/chat/execution/page.mdx || {
  echo "WARN: frontmatter/H1 not found (ensure title/description or a top-level heading exist)"; exit 1;
}

# 3) Optional: Confirm any sitemap or sidebar ordering includes the new path (heuristic)
rg -nS "/ai/chat/execution" apps/portal || echo "NOTE: /ai/chat/execution not referenced outside sidebar"

Length of output: 618


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "----- Head of page.mdx -----"
head -n20 apps/portal/src/app/ai/chat/execution/page.mdx

echo "----- Frontmatter start lines -----"
grep -n -E '^---' apps/portal/src/app/ai/chat/execution/page.mdx || true

echo "----- Title lines -----"
grep -n -E '^\s*title:' apps/portal/src/app/ai/chat/execution/page.mdx || true

echo "----- Description lines -----"
grep -n -E '^\s*description:' apps/portal/src/app/ai/chat/execution/page.mdx || true

echo "----- H1 lines -----"
grep -n -E '^# ' apps/portal/src/app/ai/chat/execution/page.mdx || true

echo "----- References to /ai/chat/execution in apps/portal -----"
rg -n "/ai/chat/execution" apps/portal || true

Length of output: 1805


Add frontmatter and ensure indexing for “Transaction Execution” page

The new MDX page exists and includes a top-level heading, but it currently lacks frontmatter metadata and isn’t referenced in any sitemap or search‐index configuration. To ensure this doc is discoverable and renders properly in listings:

• apps/portal/src/app/ai/chat/execution/page.mdx
– Add frontmatter at the very top, for example:
diff +--- +title: "Transaction Execution" +description: "Use thirdweb AI to auto-execute or prepare transactions for signing." +---
– This will provide explicit title/description for sitemap generators and search indexers.
– Retain or move the existing # Transaction Execution H1 below the frontmatter.

• Sitemap/search index configuration
– Verify that /ai/chat/execution is included in your sitemap (e.g., via next-sitemap or other routing exports).
– Ensure your search indexing process (DocSearch, Lunr, etc.) picks up MDX files under apps/portal/src/app/ai/chat.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
name: "Transaction Execution",
href: "/ai/chat/execution",
},
file=apps/portal/src/app/ai/chat/execution/page.mdx
---
title: "Transaction Execution"
description: "Use thirdweb AI to auto-execute or prepare transactions for signing."
---
# Transaction Execution
<!-- rest of the MDX content follows -->

{
name: "Streaming Responses",
href: "/ai/chat/streaming",
Expand Down
2 changes: 1 addition & 1 deletion apps/portal/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function AISection() {
description="Integrate the most advanced blockchain model into your applications"
href="/ai/chat"
icon={MessageCircleIcon}
title="Chat API"
title="Blockchain LLM"
/>
<ArticleCardIndex
description="For agents and humans. Use the thirdweb API with natural language"
Expand Down
Loading