Skip to content

Commit c46f3b8

Browse files
authored
Merge pull request #680 from Merit-Systems/master
[Release] cli template + api key mode dash + user fallback
2 parents 74b9667 + ed7d93d commit c46f3b8

49 files changed

Lines changed: 3025 additions & 17 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CONTRIBUTING.md‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,17 @@ echo/
188188
- **Echo TS SDK** (`packages/sdk/ts`): Foundation for all framework-specific SDKs
189189
- **Echo React SDK** (`packages/sdk/react`): React hooks and components
190190
- **Echo Next SDK** (`packages/sdk/next`): Next.js App Router integration
191+
- **Echo CLI** (`templates/echo-cli`): Command-line AI agent with authentication options
192+
193+
### Authentication Methods in Echo
194+
195+
Echo supports multiple authentication and payment methods:
196+
197+
1. **Echo API Keys**: Managed accounts with centralized billing
198+
2. **WalletConnect**: Connect mobile wallets for decentralized payments
199+
3. **Local Wallet (Self-Custody)**: Generate and manage private keys locally for full custody
200+
201+
All methods integrate with the X402 payment protocol for USDC-based AI payments.
191202

192203
## Coding Standards
193204

@@ -197,6 +208,9 @@ echo/
197208
- Prefer explicit types over `any`
198209
- Use interfaces for public APIs, types for internal structures
199210
- Enable strict mode in `tsconfig.json`
211+
- Import from correct module paths:
212+
- `privateKeyToAccount` from `viem/accounts`, not `viem`
213+
- Use relative paths or absolute imports with `@` alias
200214

201215
### Imports
202216

@@ -308,21 +322,30 @@ The scope indicates which package is affected:
308322
- `react-sdk`: React SDK
309323
- `next-sdk`: Next.js SDK
310324
- `ts-sdk`: TypeScript SDK
325+
- `cli`: Echo CLI template
311326
- `templates`: Starter templates
312327
- `docs`: Documentation
313328

329+
When working on the Echo CLI or templates, use `cli` or `templates` scope.
330+
314331
### Examples
315332

316333
```bash
317334
feat(react-sdk): add support for streaming responses
318335

336+
feat(cli): add local wallet self-custody authentication
337+
319338
fix(server): correct token counting for Claude models
320339

321340
docs(templates): add environment setup guide for next-chat
322341

342+
docs(cli): update readme with local wallet instructions
343+
323344
refactor(control): simplify balance calculation logic
324345

325346
test(ts-sdk): add integration tests for provider initialization
347+
348+
test(cli): add tests for wallet generation and signing
326349
```
327350

328351
## Pull Request Process

‎README.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,14 @@ Available templates:
111111

112112
- **[next](./templates/next)** - Next.js application with Echo
113113
- **[react](./templates/react)** - Vite React application with Echo
114-
- **[nextjsChatbot](./templates/nextjs-chatbot)** - Next.js with Echo and Vercel AI SDK
115-
- **[assistantUi](./templates/assistant-ui)** - Next.js with Echo and Assistant UI
114+
- **[next-chat](./templates/next-chat)** - Next.js chatbot with Echo and Vercel AI SDK
115+
- **[assistant-ui](./templates/assistant-ui)** - Next.js with Echo and Assistant UI
116+
- **[echo-cli](./templates/echo-cli)** - CLI tool for AI chat with Echo (API keys + crypto wallets)
116117

117118
Or run `npx echo-start my-app` to choose interactively.
118119

120+
**Note:** The CLI template (`echo-cli`) requires manual installation from the repository as it's a command-line tool rather than a web application. See the [templates README](./templates/README.md) for details.
121+
119122
# Development
120123

121124
Fill out `packages/app/control/.env` and `packages/app/server/.env`. Then...

‎packages/app/control/docs/getting-started/templates.mdx‎

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,4 +416,84 @@ Next.js application demonstrating Echo as an Auth.js provider for authentication
416416
</Tab>
417417
</Tabs>
418418
</Step>
419-
</Steps>
419+
</Steps>
420+
421+
## Echo CLI (Echodex)
422+
423+
A command-line interface for AI chat powered by Echo with support for both API key and crypto wallet payments via the X402 protocol.
424+
425+
[View on GitHub](https://github.com/Merit-Systems/echo/tree/master/templates/echo-cli)
426+
427+
<Callout type="info">
428+
**Note:** Unlike web-based templates, the CLI tool requires manual installation from the repository as it's not available through `echo-start`.
429+
</Callout>
430+
431+
### Features
432+
433+
- **Dual Authentication**: Echo API keys or WalletConnect for flexible payment options
434+
- **Multi-Model Support**: GPT-4o, GPT-5, GPT-5 Mini, GPT-5 Nano
435+
- **X402 Protocol**: Pay-per-use with crypto wallets
436+
- **Conversation Management**: Resume and export chat history
437+
- **Secure Storage**: OS keychain integration
438+
- **Real-time Usage Tracking**: View balance and costs
439+
440+
<Steps>
441+
<Step>
442+
### Create an Echo App
443+
Go to [echo.merit.systems/new](https://echo.merit.systems/new) to get an `app_id`.
444+
</Step>
445+
446+
<Step>
447+
### Clone and Install
448+
The CLI template is available in the Echo repository:
449+
450+
```sh lineNumbers
451+
git clone https://github.com/Merit-Systems/echo.git
452+
cd echo/templates/echo-cli
453+
pnpm install
454+
pnpm build
455+
```
456+
</Step>
457+
458+
<Step>
459+
### Authenticate
460+
Start by logging in to Echo:
461+
462+
```sh lineNumbers
463+
echodex login
464+
```
465+
466+
Choose between:
467+
- **Echo API Key**: Opens your browser to create an API key
468+
- **WalletConnect**: Displays a QR code for mobile wallet authentication
469+
</Step>
470+
471+
<Step>
472+
### Start Chatting
473+
Once authenticated, start a chat session:
474+
475+
```sh lineNumbers
476+
echodex
477+
```
478+
479+
Or use other commands:
480+
```sh lineNumbers
481+
echodex model # Select AI model
482+
echodex resume # Resume last conversation
483+
echodex history # View conversation history
484+
echodex export # Export as JSON
485+
echodex profile # View profile and balance
486+
```
487+
</Step>
488+
</Steps>
489+
490+
### Global Installation (Optional)
491+
492+
To use `echodex` globally on your system:
493+
494+
```sh lineNumbers
495+
cd echo/templates/echo-cli
496+
pnpm link --global
497+
```
498+
499+
For more details, see the [CLI template README](https://github.com/Merit-Systems/echo/tree/master/templates/echo-cli#readme).

‎packages/app/control/docs/index.mdx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ We provide a variety of ready-to-use templates to help you get started quickly w
129129
- **Auth.js (NextAuth)** — Next.js app with Echo as an Auth.js provider
130130
- **React Chat** — Chat interface for React apps
131131
- **React Image** — Image generation for React apps
132+
- **CLI** — Command-line tool for AI chat with Echo (API keys + crypto wallets)
132133

133134
All templates are available through `echo-start` or in the [GitHub repository](https://github.com/Merit-Systems/echo/tree/master/templates). Visit our [templates documentation](/docs/getting-started/templates) for detailed setup instructions.
134135

‎packages/app/control/src/app/(app)/app/[id]/(overview)/_components/setup/connection/index.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ export const Connection: React.FC<Props> = ({ appId }) => {
5050
refetchInterval: shouldRefetch ? 2500 : undefined,
5151
}
5252
);
53-
const [numApiKeys] = api.user.apiKeys.count.useSuspenseQuery({ appId });
53+
const [numApiKeys] = api.user.apiKeys.count.useSuspenseQuery(
54+
{ appId },
55+
{
56+
refetchInterval: shouldRefetch ? 2500 : undefined,
57+
}
58+
);
5459

5560
const isConnected = useMemo(() => {
5661
return numTokens > 0 || numApiKeys > 0;

‎packages/app/control/src/app/(app)/app/[id]/_hooks/use-app-setup.ts‎

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,10 @@ export const useAppConnectionSetup = (appId: string) => {
2525
refetchInterval: shouldRefetchConnection ? 2500 : undefined,
2626
}
2727
);
28-
const [transactionsCount] = api.apps.app.transactions.count.useSuspenseQuery(
29-
{
30-
appId,
31-
},
32-
{
33-
refetchInterval: shouldRefetchTransactions ? 2500 : undefined,
34-
}
35-
);
3628

3729
const isConnected = useMemo(() => {
38-
return numTokens > 0 || numApiKeys > 0 || transactionsCount > 0;
39-
}, [numTokens, numApiKeys, transactionsCount]);
30+
return numTokens > 0 || numApiKeys > 0;
31+
}, [numTokens, numApiKeys]);
4032

4133
useEffect(() => {
4234
setShouldRefetchConnection(!isConnected);

‎packages/app/control/src/app/(app)/app/[id]/transactions/_components/transactions.tsx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ interface Transaction {
2626
user?: {
2727
id: string | null;
2828
name: string | null;
29+
email: string | null;
2930
image: string | null;
3031
};
3132
date: Date;
@@ -111,7 +112,10 @@ const TransactionRow = ({ transaction }: { transaction: Transaction }) => {
111112
<div className="flex flex-col items-start">
112113
<p className="text-sm leading-tight">
113114
<span className="font-medium">
114-
{transaction.user?.name ?? 'x402 Users'}
115+
{transaction.user?.name ??
116+
(transaction.user?.email
117+
? `${transaction.user.id}`
118+
: 'Unknown User')}
115119
</span>{' '}
116120
made {transaction.callCount} requests
117121
</p>

‎packages/app/control/src/app/(app)/app/[id]/users/_components/users.tsx‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const UsersTable: React.FC<Props> = ({ appId }) => {
5656
...rows.map(row =>
5757
[
5858
`"${row.name ?? ''}"`,
59-
`"${row.email || ''}"`,
59+
`"${row.email ?? ''}"`,
6060
row.usage.totalTransactions,
6161
row.usage.rawCost,
6262
row.usage.markupProfit,
@@ -187,7 +187,9 @@ const UserRow = ({ user, showEmail }: { user: User; showEmail: boolean }) => {
187187
<TableCell className="pl-4">
188188
<div className="flex flex-row items-center gap-2">
189189
<UserAvatar src={user.image} className="size-6" />
190-
<p className="text-sm font-medium">{user.name}</p>
190+
<p className="text-sm font-medium">
191+
{user.name ?? (user.email ? `${user.id}` : 'Unknown User')}
192+
</p>
191193
</div>
192194
</TableCell>
193195
{showEmail && (

‎packages/app/control/src/services/db/apps/transactions.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const listAppTransactions = async (
4949
select: {
5050
id: true,
5151
name: true,
52+
email: true,
5253
image: true,
5354
},
5455
},
@@ -69,6 +70,7 @@ export const listAppTransactions = async (
6970
user: {
7071
id: string | null;
7172
name: string | null;
73+
email: string | null;
7274
image: string | null;
7375
};
7476
date: Date;
@@ -93,6 +95,7 @@ export const listAppTransactions = async (
9395
id: transaction.id,
9496
user: {
9597
id: transaction.userId,
98+
email: transaction.user?.email ?? null,
9699
name:
97100
transaction.user?.name ??
98101
(transaction.userId === null ? 'x402 Users' : null),

‎templates/README.md‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,46 @@ npx echo-start@latest --template assistant-ui
6767

6868
---
6969

70+
### CLI Templates
71+
72+
#### Echo CLI (`echo-cli`)
73+
74+
A command-line interface for AI chat powered by Echo with support for both API key and crypto wallet payments.
75+
76+
**Note:** This template is different from web-based templates. Install it directly from the repository:
77+
78+
```bash
79+
git clone https://github.com/Merit-Systems/echo.git
80+
cd echo/templates/echo-cli
81+
pnpm install
82+
pnpm build
83+
```
84+
85+
**Features:**
86+
87+
- Dual authentication: Echo API keys or WalletConnect
88+
- Multi-model support (GPT-4o, GPT-5, etc.)
89+
- X402 protocol for crypto payments
90+
- Conversation history and resume
91+
- Secure OS keychain credential storage
92+
- Export conversations as JSON
93+
- Profile and usage management
94+
95+
**Usage:**
96+
97+
```bash
98+
echodex login # Authenticate
99+
echodex # Start chat
100+
echodex model # Select AI model
101+
echodex resume # Resume conversation
102+
echodex history # View history
103+
echodex export # Export as JSON
104+
echodex profile # View profile
105+
echodex logout # Sign out
106+
```
107+
108+
---
109+
70110
### Feature-Specific Templates
71111

72112
#### Next.js Chat (`next-chat`)

0 commit comments

Comments
 (0)