AT

aaronjmars/tweazy

Developer tools
47 stars 15 forks Quality 69 Trend 27MIT

The best way to monetize AI applications & MCP, using x402, CDP Smart Wallets & Paymaster

Overview

The best way to read tweets onchain. A pay-per-use AI app - users pay 0.01 USDC per MCP query via x402, with CDP Smart Wallets, passkeys, and gas sponsorship on Base. 1. (Smart Wallet with passkeys or non-custodial wallets) 2. through a chat interface 3. automatically via x402 4. after successful payment 5. generated by AI Perfect for developers wanting to build with Web3 payments (x402) - 🔐 : Smart Wallets with Passkeys (CDP) or non-custodial wallets - 💳 : HTTP 402 Payment Required implementation for API access - 🔑 : Biometric login with Smart Wallets (most secure, no seed phrases) - ⛽ : Transaction fee sponsorship via paymaster for Smart Wallets - 🤖 : Generative UI with React component registry - 🔗 : Model Context Protocol for extensible AI functionality - 🌐 : Supports both Base testnet (default) and Base mainnet - 🛡️ : Clean architecture with proper error handling - 🎨 : AI can generate and render React components on demand - Node.

README

Star us ->        

The best way to read tweets onchain. A pay-per-use AI chat app - users pay 0.01 USDC on Base for every query, with Coinbase Smart Wallets (passkeys) or any browser wallet, and MCP servers for tools and data.

See it in action

What it does

Tweazy is a Next.js template for a pay-per-use AI app:

  1. Connect a wallet - a Coinbase Smart Wallet with passkeys, or any injected browser wallet (MetaMask, Rabby, Coinbase Wallet, …).
  2. Ask a question in the chat.
  3. Pay 0.01 USDC on Base. Every query opens a payment step first; the message is only sent after the USDC transfer goes through.
  4. Get the answer, rendered with generative UI (charts and data cards) by Tambo AI.
  5. Add your own MCP servers at /mcp-config (for example a Twitter/X data server) so the AI can call their tools.

Use it as a starting point for monetized AI apps with onchain payments.

Features

  • Two wallet options: Coinbase Smart Wallet (passkeys, no seed phrase) or any injected wallet via wagmi.
  • Per-query USDC payments on Base, set in src/lib/config.ts (0.01 USDC by default).
  • Tambo AI generative UI with a React component registry (src/lib/tambo.ts).
  • MCP support: user-configured MCP servers (HTTP or SSE), stored in the browser.
  • Base Sepolia by default, Base mainnet with one env var.

Quick start

Prerequisites

  • Node.js 24+ (see .nvmrc) and npm
  • A Tambo AI API key
  • A wallet address to receive payments

Setup

git clone https://github.com/aaronjmars/tweazy
cd tweazy
npm install
cp example.env.local .env.local   # then fill in the values below
npm run dev

Open http://localhost:3000.

Scripts

npm run dev            # dev server
npm run build          # production build
npm run start          # serve the production build
npm run lint           # eslint
npm run format:check   # biome (npm run format to fix)
npm run init           # npx tambo init

Configuration

Secrets go in .env.local. Everything else (RPC URLs, USDC contracts, chain IDs, price) lives in src/lib/config.ts.

Var Required Notes
NEXT_PUBLIC_TAMBO_API_KEY yes Tambo AI API key.
NEXT_PUBLIC_PAYMENT_RECIPIENT yes Wallet address that receives the 0.01 USDC payments.
NEXT_PUBLIC_NETWORK_MODE no testnet (default, Base Sepolia) or mainnet (Base).
CDP_API_KEY_NAME, CDP_API_KEY_PRIVATE_KEY, CDP_WALLET_SECRET no Coinbase CDP credentials for the /api/cdp/* routes. Without them, create-wallet, balance and fund-wallet return mock data.
TWEAZY_ALLOW_MOCK_PAYMENT no Set to 1 to let /api/cdp/transfer return a mock success when CDP is not configured. Local development only - never on a deployment that serves paid queries.

Networks

Mode Network Chain ID USDC contract
testnet (default) Base Sepolia 84532 0x036CbD53842c5426634e7929541eC2318f3dCF7e
mainnet Base 8453 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

RPC URLs, contracts and chain IDs switch automatically with NEXT_PUBLIC_NETWORK_MODE. If the connected wallet is on the wrong chain, the app asks it to switch.

How it works

sequenceDiagram
    participant User
    participant App
    participant Base
    participant AI as Tambo AI + MCP

    User->>App: Ask question
    App->>User: Payment modal (0.01 USDC)
    User->>Base: USDC transfer to the recipient
    Base-->>App: Transaction confirmed
    App->>AI: Send the query
    AI-->>App: Response + generative UI
    App->>User: Display answer
  • The payment gate lives in src/components/EnhancedMessageInput.tsx: every query opens PaymentModal before it is sent.
  • src/lib/payment.ts sends the USDC transfer with the right wallet: wagmi writeContract for injected wallets, the Coinbase Wallet SDK provider for Smart Wallets (src/lib/smart-wallet.ts).
  • src/components/WalletProvider.tsx holds the two-wallet context.

Project structure

src/
├── app/
│   ├── api/cdp/           # CDP wallet routes (create-wallet, balance, fund-wallet, transfer)
│   ├── mcp-config/        # MCP server configuration page
│   ├── layout.tsx
│   └── page.tsx           # Chat app (Tambo + MCP providers)
├── components/
│   ├── ui/                # Chat thread, messages, graph, data cards
│   ├── WalletProvider.tsx # Two-wallet context
│   ├── WalletSelector.tsx
│   ├── PaymentModal.tsx   # Payment confirmation UI
│   └── EnhancedMessageInput.tsx # Chat input with the payment gate
├── hooks/usePayment.ts
└── lib/
    ├── config.ts          # Network + app config
    ├── payment.ts         # USDC transfers for both wallet types
    ├── smart-wallet.ts    # Coinbase Smart Wallet (passkeys)
    ├── cdp-wallet.ts      # Client for the /api/cdp routes
    ├── mcp-utils.ts       # MCP server list (localStorage)
    └── tambo.ts           # Tambo component registry

API routes

  • POST /api/cdp/create-wallet - create a CDP wallet (mock address when CDP is not configured)
  • POST /api/cdp/balance - USDC balance (mock balance when CDP is not configured)
  • POST /api/cdp/fund-wallet - fund a wallet from the CDP faucet (Base Sepolia only; mock when CDP is not configured)
  • POST /api/cdp/transfer - not implemented yet: returns 501 when CDP is configured, 503 when it is not (or a mock success with TWEAZY_ALLOW_MOCK_PAYMENT=1)

Security notes

  • Defaults to testnet - Base Sepolia test tokens have no real value. Check NEXT_PUBLIC_NETWORK_MODE before you deploy.
  • Mainnet moves real USDC.
  • Secrets stay in env vars; non-secrets in src/lib/config.ts.
  • Smart Wallets use passkeys; injected wallets keep user-controlled keys.

See SECURITY.md to report a vulnerability.

Troubleshooting

  • “Payment recipient not configured” - set NEXT_PUBLIC_PAYMENT_RECIPIENT in .env.local to a valid address.
  • “Tambo API key not found” - get a key at tambo.co/dashboard and set NEXT_PUBLIC_TAMBO_API_KEY.
  • “Insufficient balance” - on testnet, get Base Sepolia ETH from a faucet for gas and testnet USDC (0x036CbD53842c5426634e7929541eC2318f3dCF7e) for payments.
  • Wrong network - switch the wallet to Base Sepolia (84532) or Base (8453), matching NEXT_PUBLIC_NETWORK_MODE.

Contributing

Fork, branch, and open a PR. Before you push, run npm run lint, npm run format:check and npm run build. Use conventional commits (feat: ..., fix: ...). See CONTRIBUTING.md.

Resources

License

MIT, see LICENSE.


Built by Aaron Elijah Mars, founder of Aeon and MiroShark - @aaronjmars

View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →