Skip to content
Open
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
5 changes: 5 additions & 0 deletions packages/sdk/echo-start/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ const DEFAULT_TEMPLATES = {
description:
'Full-stack Next.js application with Echo and the Vercel AI SDK',
},
'next-402-chat': {
title: 'Next.js Chat x402',
description:
'Next.js chat app with an auth switcher for Echo credits or x402 USDC',
},
'next-image': {
title: 'Next.js Image Gen',
description:
Expand Down
17 changes: 17 additions & 0 deletions templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,23 @@ npx echo-start@latest --template next-chat

---

#### Next.js Chat x402 (`next-402-chat`)

A simple chat template with a payment/auth switcher for Echo credits or USDC via x402.

```bash
npx echo-start@latest --template next-402-chat
```

**Features:**

- Simple chat UI based on the standard Next.js chat template
- Auth switcher between Echo credits and wallet-based x402
- USDC payments via x402 with wallet connection
- Echo credits flow with built-in Echo authentication

---

#### Next.js Image Generation (`next-image`)

Image generation application with Echo billing.
Expand Down
3 changes: 3 additions & 0 deletions templates/next-402-chat/.env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ECHO_APP_ID="74d9c979-e036-4e43-904f-32d214b361fc"
NEXT_PUBLIC_ECHO_APP_ID="74d9c979-e036-4e43-904f-32d214b361fc"
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="YOUR_PROJECT_ID"
41 changes: 41 additions & 0 deletions templates/next-402-chat/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
47 changes: 47 additions & 0 deletions templates/next-402-chat/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Echo Next.js Chat x402 Template

A minimal Next.js chat template with an auth switcher that lets users choose how to pay:

- Echo credits (Echo auth)
- USDC via x402 (wallet auth)

## Quick Start

```bash
npx echo-start@latest --template next-402-chat
```

Then configure env vars:

```bash
ECHO_APP_ID=your_app_id
NEXT_PUBLIC_ECHO_APP_ID=your_app_id
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_walletconnect_project_id
```

## Features

- Simple chat UI from the standard `next-chat` template
- Payment/auth switcher on the sign-in screen
- Echo credits flow via `@merit-systems/echo-next-sdk`
- USDC x402 flow via `@merit-systems/ai-x402`
- Wallet connection via RainbowKit + wagmi

## How It Works

- `credits` mode:
- User signs in with Echo
- API uses `openai(model)` from Echo SDK
- `x402` mode:
- User connects wallet
- Client uses `useChatWithPayment`
- API uses `createX402OpenAIWithoutPayment` and reads `x-payment` header

## Run Locally

```bash
pnpm install
pnpm dev
```

Open `http://localhost:3000`.
22 changes: 22 additions & 0 deletions templates/next-402-chat/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
19 changes: 19 additions & 0 deletions templates/next-402-chat/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
// import.meta.dirname is available after Node.js v20.11.0
baseDirectory: import.meta.dirname,
})

const eslintConfig = [
...compat.config({
extends: ['next'],
settings: {
next: {
rootDir: 'examples/nextjs-chatbot/',
},
},
}),
]

export default eslintConfig
10 changes: 10 additions & 0 deletions templates/next-402-chat/next.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
/* config options here */
turbopack: {
root: '.',
},
};

export default nextConfig;
73 changes: 73 additions & 0 deletions templates/next-402-chat/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "next-402-chat-template",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --turbopack",
"start": "next start",
"lint": "biome check --write",
"postinstall": "npm dedupe || true"
},
"dependencies": {
"@ai-sdk/react": "2.0.17",
"@merit-systems/ai-x402": "latest",
"@merit-systems/echo-next-sdk": "latest",
"@merit-systems/echo-react-sdk": "latest",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-hover-card": "^1.1.15",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-tooltip": "^1.2.8",
"@radix-ui/react-use-controllable-state": "^1.2.2",
"@rainbow-me/rainbowkit": "^2.2.8",
"@tanstack/react-query": "^5.90.2",
"ai": "5.0.19",
"@ai-sdk/openai": "2.0.16",
"autonumeric": "^4.10.9",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.6.0",
"lucide-react": "^0.542.0",
"next": "15.5.9",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-syntax-highlighter": "^15.6.6",
"shiki": "^3.12.2",
"streamdown": "^1.2.0",
"tailwind-merge": "^3.3.1",
"use-stick-to-bottom": "^1.1.1",
"viem": "2.x",
"wagmi": "^2.17.5",
"x402": "^0.7.1",
"zod": "^4.1.5"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@next/eslint-plugin-next": "^15.5.3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/react-syntax-highlighter": "^15.5.13",
"tailwindcss": "^4",
"tw-animate-css": "^1.3.8",
"typescript": "^5"
},
"overrides": {
"ai": "5.0.19",
"@ai-sdk/react": "2.0.17",
"@ai-sdk/openai": "2.0.16",
"@merit-systems/echo-react-sdk": {
"ai": "5.0.19",
"@ai-sdk/react": "2.0.17"
},
"@merit-systems/echo-next-sdk": {
"ai": "5.0.19",
"@ai-sdk/openai": "2.0.16"
}
}
}
5 changes: 5 additions & 0 deletions templates/next-402-chat/postcss.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};

export default config;
1 change: 1 addition & 0 deletions templates/next-402-chat/public/file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions templates/next-402-chat/public/globe.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions templates/next-402-chat/public/logo/dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading