/** * ROB Domains — Vercel AI SDK Integration Example * * Demonstrates using the ROB Domains Agent API with the Vercel AI SDK * using the `tool` helper and `generateText` / `streamText`. * Covers Search, Mint, Set Primary, and Update Profile. * * Requires: npm install ai @ai-sdk/openai zod */ import { generateText, tool } from 'ai'; import { openai } from '@ai-sdk/openai'; import { z } from 'zod'; const BASE_URL = 'https://robdn.com'; // ─── Tool Helpers ───────────────────────────────────────────────────────────── async function get(path: string) { const res = await fetch(`${BASE_URL}${path}`); return res.json(); } async function post(path: string, body: unknown) { const res = await fetch(`${BASE_URL}${path}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); return res.json(); } // ─── Tools ─────────────────────────────────────────────────────────────────── const robDomainsTools = { searchDomain: tool({ description: 'Search for a .rob domain. Returns availability, owner, tokenId, and profile.', parameters: z.object({ domain: z.string().describe('Domain label without ".rob" suffix'), }), execute: async ({ domain }) => get(`/agent/search/${domain}`), }), getProfile: tool({ description: 'Get the full on-chain profile for a .rob domain.', parameters: z.object({ domain: z.string().describe('Domain label (e.g. "alice")'), }), execute: async ({ domain }) => get(`/agent/profile/${domain}`), }), reverseResolve: tool({ description: 'Reverse-resolve an Ethereum wallet to its primary .rob domain.', parameters: z.object({ wallet: z.string().describe('Ethereum wallet address (0x-prefixed)'), }), execute: async ({ wallet }) => get(`/agent/reverse/${wallet}`), }), getPrimaryDomain: tool({ description: 'Get the primary .rob domain for an Ethereum wallet.', parameters: z.object({ wallet: z.string().describe('Ethereum wallet address'), }), execute: async ({ wallet }) => get(`/agent/primary/${wallet}`), }), buildMintTransaction: tool({ description: 'Generate an unsigned mint transaction payload for a .rob domain. User must sign and broadcast.', parameters: z.object({ domain: z.string().describe('Domain label to mint'), }), execute: async ({ domain }) => post('/agent/tx/mint', { domain }), }), buildSetPrimaryTransaction: tool({ description: 'Generate an unsigned set-primary transaction payload for a .rob domain token.', parameters: z.object({ tokenId: z.string().describe('On-chain token ID'), wallet: z.string().describe('Wallet address that owns the token'), }), execute: async ({ tokenId, wallet }) => post('/agent/tx/set-primary', { tokenId, wallet }), }), buildUpdateProfileTransaction: tool({ description: 'Generate unsigned update-profile transaction payload(s) for a .rob domain.', parameters: z.object({ tokenId: z.string().describe('Token ID of the domain'), bio: z.string().max(500).optional(), profilePicture: z.string().optional(), coverImage: z.string().optional(), background: z.string().optional(), socialLinks: z .array( z.object({ platform: z.string(), url: z.string(), }) ) .optional(), customLinks: z .array( z.object({ title: z.string(), url: z.string(), }) ) .optional(), }), execute: async (input) => post('/agent/tx/update-profile', input), }), registerDomainWorkflow: tool({ description: 'Get a complete multi-step execution plan for registering a .rob domain.', parameters: z.object({ domain: z.string().describe('Domain label to register'), wallet: z.string().describe('Wallet address of the future owner'), setPrimary: z.boolean().optional().default(false), profile: z .object({ bio: z.string().optional(), profilePicture: z.string().optional(), coverImage: z.string().optional(), background: z.string().optional(), socialLinks: z .array(z.object({ platform: z.string(), url: z.string() })) .optional(), customLinks: z .array(z.object({ title: z.string(), url: z.string() })) .optional(), }) .optional(), }), execute: async (input) => post('/agent/workflow/register-domain', input), }), }; // ─── Agent ──────────────────────────────────────────────────────────────────── async function robDomainsAgent(userMessage: string): Promise { const { text } = await generateText({ model: openai('gpt-4o'), system: 'You are a helpful assistant for ROB Domains (.rob), a Web3 domain name system on Robinhood Chain. Help users search domains, manage profiles, and generate unsigned transaction payloads. Always note that the API never executes transactions — the user signs and broadcasts.', prompt: userMessage, tools: robDomainsTools, maxSteps: 5, }); return text; } // ─── Demo ───────────────────────────────────────────────────────────────────── async function main() { console.log('─── Search ───'); console.log(await robDomainsAgent('Is "alice" available on ROB Domains?')); console.log('\n─── Mint ───'); console.log( await robDomainsAgent('Build a mint transaction for "alice.rob".') ); console.log('\n─── Update Profile ───'); console.log( await robDomainsAgent( 'Build an update-profile transaction for token #42. Set bio to "Web3 builder" and add Twitter https://twitter.com/alice.' ) ); console.log('\n─── Full Registration ───'); console.log( await robDomainsAgent( 'Register "alice.rob" for wallet 0xAbCd1234567890AbCd1234567890AbCd12345678, set as primary, bio "Web3 builder".' ) ); } main().catch(console.error);