@clawcard/cli 2.1.8 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -14
- package/package.json +1 -1
- package/skill/SKILL.md +165 -32
- package/src/agent-api.js +58 -0
- package/src/commands/agent.js +383 -0
- package/src/index.js +104 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @clawcard/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The complete identity for autonomous AI agents.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
One command gives your agent email, phone, virtual cards, a USDC crypto wallet, on-chain identity, and access to every paid API on the internet. Works with Claude Code, Cursor, Gemini CLI, and any MCP-compatible agent.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -26,28 +26,81 @@ clawcard keys create
|
|
|
26
26
|
clawcard setup
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
`clawcard setup` uses [skills.sh](https://skills.sh) to install the ClawCard skill for your agent.
|
|
29
|
+
`clawcard setup` uses [skills.sh](https://skills.sh) to install the ClawCard skill for your agent.
|
|
30
|
+
|
|
31
|
+
## What Your Agent Gets
|
|
32
|
+
|
|
33
|
+
| Capability | Description |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Email | Dedicated inbox at `@mail.clawcard.sh` |
|
|
36
|
+
| Phone | SMS-enabled US phone number |
|
|
37
|
+
| Virtual Cards | Instant Visa cards with per-card spend limits |
|
|
38
|
+
| Crypto Wallet | USDC on Base — gasless transfers, x402 + MPP payments |
|
|
39
|
+
| Service Discovery | Find and pay for any API in the x402 ecosystem |
|
|
40
|
+
| On-Chain Identity | ERC-8004 NFT — verifiable, portable agent identity |
|
|
41
|
+
| Credentials | AES-256 encrypted vault for API keys and secrets |
|
|
42
|
+
| Spending Guardrails | Per-agent, per-transaction, per-day limits |
|
|
30
43
|
|
|
31
44
|
## Agent Commands
|
|
32
45
|
|
|
33
46
|
Your agent runs these commands directly. All support `--json` for machine-parseable output.
|
|
34
47
|
|
|
48
|
+
### Identity & Info
|
|
49
|
+
|
|
50
|
+
| Command | Description |
|
|
51
|
+
|---|---|
|
|
52
|
+
| `clawcard agent info --json` | Agent identity (email, phone, wallet, budget) |
|
|
53
|
+
| `clawcard agent budget --json` | Check remaining FIAT budget |
|
|
54
|
+
| `clawcard agent activity --json` | View activity log |
|
|
55
|
+
|
|
56
|
+
### Communication
|
|
57
|
+
|
|
35
58
|
| Command | Description |
|
|
36
59
|
|---|---|
|
|
37
|
-
| `clawcard agent info --json` | Agent identity (email, phone, budget) |
|
|
38
60
|
| `clawcard agent emails --json` | List inbox |
|
|
39
61
|
| `clawcard agent emails send --to --subject --body --json` | Send email |
|
|
40
62
|
| `clawcard agent sms --json` | List SMS messages |
|
|
41
63
|
| `clawcard agent sms send --to --body --json` | Send SMS |
|
|
64
|
+
|
|
65
|
+
### Virtual Cards (FIAT)
|
|
66
|
+
|
|
67
|
+
| Command | Description |
|
|
68
|
+
|---|---|
|
|
42
69
|
| `clawcard agent cards --json` | List virtual cards |
|
|
43
70
|
| `clawcard agent cards create --amount --type --memo --json` | Create card |
|
|
44
71
|
| `clawcard agent cards details <id> --json` | Get PAN, CVV, expiry |
|
|
45
72
|
| `clawcard agent cards close <id> --json` | Close card |
|
|
73
|
+
|
|
74
|
+
### Crypto Wallet (USDC on Base)
|
|
75
|
+
|
|
76
|
+
| Command | Description |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `clawcard agent wallet --json` | View wallet (or create one) |
|
|
79
|
+
| `clawcard agent wallet balance --json` | Balance + spending power |
|
|
80
|
+
| `clawcard agent wallet fund --amount <dollars> --json` | Fund wallet from FIAT balance |
|
|
81
|
+
| `clawcard agent wallet send --to <0x> --amount <usdc> --json` | Send USDC |
|
|
82
|
+
| `clawcard agent wallet send --url <url> --json` | Pay an x402 API |
|
|
83
|
+
| `clawcard agent wallet send --url <url> --protocol mpp --json` | Pay an MPP API |
|
|
84
|
+
| `clawcard agent wallet transactions --json` | Transaction history |
|
|
85
|
+
| `clawcard agent wallet freeze --json` | Freeze wallet |
|
|
86
|
+
| `clawcard agent wallet unfreeze --json` | Unfreeze wallet |
|
|
87
|
+
| `clawcard agent wallet close --json` | Close wallet permanently |
|
|
88
|
+
|
|
89
|
+
### Discovery & Identity
|
|
90
|
+
|
|
91
|
+
| Command | Description |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `clawcard agent discover --query "web search" --json` | Find x402 services |
|
|
94
|
+
| `clawcard agent identity --json` | Register/view ERC-8004 on-chain identity |
|
|
95
|
+
| `clawcard agent card --json` | View A2A agent card (discovery document) |
|
|
96
|
+
|
|
97
|
+
### Credentials
|
|
98
|
+
|
|
99
|
+
| Command | Description |
|
|
100
|
+
|---|---|
|
|
46
101
|
| `clawcard agent creds --json` | List stored credentials |
|
|
47
102
|
| `clawcard agent creds set --service --key --value --json` | Store credential |
|
|
48
103
|
| `clawcard agent creds get --service --key --json` | Retrieve credential |
|
|
49
|
-
| `clawcard agent budget --json` | Check remaining budget |
|
|
50
|
-
| `clawcard agent activity --json` | View activity log |
|
|
51
104
|
|
|
52
105
|
## User Commands
|
|
53
106
|
|
|
@@ -60,33 +113,45 @@ Your agent runs these commands directly. All support `--json` for machine-parsea
|
|
|
60
113
|
| `clawcard agent` | Show agent identity |
|
|
61
114
|
| `clawcard agent fund` | Add budget to your agent |
|
|
62
115
|
| `clawcard keys create` | Create agent key |
|
|
63
|
-
| `clawcard keys revoke` | Revoke key
|
|
116
|
+
| `clawcard keys revoke` | Revoke key |
|
|
64
117
|
| `clawcard setup` | Install ClawCard skill |
|
|
65
118
|
| `clawcard billing` | Billing dashboard |
|
|
66
119
|
| `clawcard billing topup` | Top up balance |
|
|
67
120
|
| `clawcard billing balance` | Quick balance check |
|
|
68
121
|
| `clawcard referral` | Show referral code |
|
|
122
|
+
| `clawcard settings` | Manage billing address |
|
|
69
123
|
| `clawcard help` | Show all commands |
|
|
70
124
|
|
|
71
125
|
## How It Works
|
|
72
126
|
|
|
73
|
-
1. You create an agent key
|
|
74
|
-
2. `clawcard setup` installs
|
|
75
|
-
3.
|
|
76
|
-
4.
|
|
127
|
+
1. You create an agent key — it gets email, phone, and budget
|
|
128
|
+
2. `clawcard setup` installs the skill that teaches your agent the commands
|
|
129
|
+
3. Agent creates a wallet, discovers services, pays for APIs, signs up for things
|
|
130
|
+
4. Everything is logged — full audit trail in the dashboard
|
|
131
|
+
5. You control the budget and can freeze/close anything instantly
|
|
132
|
+
|
|
133
|
+
## Payment Protocols
|
|
134
|
+
|
|
135
|
+
ClawCard is the first platform to unify both major machine payment protocols:
|
|
136
|
+
|
|
137
|
+
- **x402** (Coinbase) — Pay-per-request API payments with USDC. 50M+ transactions.
|
|
138
|
+
- **MPP** (Stripe/Tempo) — Session-based machine payments. Cards, stablecoins, Lightning.
|
|
139
|
+
|
|
140
|
+
Your agent pays for any service in either ecosystem. You never think about protocols.
|
|
77
141
|
|
|
78
142
|
## Pricing
|
|
79
143
|
|
|
80
144
|
Pay as you go. No subscriptions, no monthly fees.
|
|
81
145
|
|
|
82
146
|
- **Minimum top-up** — $5
|
|
83
|
-
- **Processing fee** — 10%
|
|
147
|
+
- **Processing fee** — 10% on FIAT top-ups
|
|
148
|
+
- **Wallet funding fee** — 2% on FIAT-to-USDC conversion
|
|
84
149
|
- **Cards** — Unlimited
|
|
85
|
-
|
|
86
|
-
Top up your balance and your agent spends it on virtual cards.
|
|
150
|
+
- **x402/MPP payments** — Pay source price (no markup)
|
|
87
151
|
|
|
88
152
|
## Links
|
|
89
153
|
|
|
90
154
|
- [Website](https://clawcard.sh)
|
|
91
155
|
- [Docs](https://clawcard.sh/docs)
|
|
92
156
|
- [Skill](https://github.com/latchagent/skill)
|
|
157
|
+
- [Dashboard](https://clawcard.sh/dashboard)
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: clawcard
|
|
3
|
-
description: Email, SMS, virtual cards, and credential vault for autonomous agents. Run clawcard agent commands to interact with your resources.
|
|
3
|
+
description: Email, SMS, virtual cards, crypto wallet, and credential vault for autonomous agents. Run clawcard agent commands to interact with your resources.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
You have access to ClawCard via the `clawcard` CLI. All commands support `--json` for machine-readable output. Always pass `--json` when calling these commands.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## CRITICAL: Know Your Resources Before Acting
|
|
9
|
+
|
|
10
|
+
**BEFORE creating cards, sending USDC, or spending money, ALWAYS check what you already have:**
|
|
9
11
|
|
|
10
12
|
```
|
|
11
|
-
clawcard agent info --json
|
|
13
|
+
clawcard agent info --json # Your identity, email, phone, wallet, budget
|
|
14
|
+
clawcard agent cards --json # Your existing cards (check BEFORE creating new ones!)
|
|
15
|
+
clawcard agent wallet --json # Your wallet (check BEFORE creating a new one!)
|
|
16
|
+
clawcard agent budget --json # Your remaining FIAT budget
|
|
17
|
+
clawcard agent creds --json # Your stored credentials
|
|
12
18
|
```
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
**You MUST list existing cards before every purchase.** If you already have an open `merchant_locked` card for the same merchant, REUSE IT — do not create a new one. Cards are limited and creating duplicates wastes budget.
|
|
21
|
+
|
|
22
|
+
---
|
|
15
23
|
|
|
16
24
|
## Email
|
|
17
25
|
|
|
@@ -44,22 +52,38 @@ clawcard agent sms send --to "+15551234567" --body "Message" --json
|
|
|
44
52
|
|
|
45
53
|
## Virtual Cards
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
### MANDATORY: Check existing cards FIRST
|
|
56
|
+
|
|
57
|
+
**Before EVERY payment, run this:**
|
|
58
|
+
```
|
|
59
|
+
clawcard agent cards --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Look at the response. For each card, check:
|
|
63
|
+
- `status`: Is it `open`? (If `paused` or `closed`, skip it)
|
|
64
|
+
- `type`: Is it `merchant_locked`? (If so, it can be reused at the same merchant)
|
|
65
|
+
- `memo`: Does the description match the merchant/service you're paying?
|
|
66
|
+
- `spendLimitCents`: Does it have enough budget remaining?
|
|
67
|
+
|
|
68
|
+
**If you find an open merchant_locked card for the same merchant — USE IT. Do NOT create a new card.**
|
|
69
|
+
|
|
70
|
+
### Card types
|
|
48
71
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Only proceed if the user explicitly confirms.
|
|
72
|
+
- `single_use`: Auto-closes after one charge. Use for one-time purchases (domains, invoices, one-off payments). **This is the default.**
|
|
73
|
+
- `merchant_locked`: Locks to first merchant, allows repeat charges. Use ONLY when the user explicitly needs multiple purchases at the same merchant.
|
|
52
74
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
75
|
+
### Subscription warning
|
|
76
|
+
|
|
77
|
+
Cards CANNOT be topped up. If you are about to pay for a recurring subscription (monthly SaaS, hosting, etc.), STOP and warn the user: "This card has a fixed budget and can't be refilled — the renewal will fail when the budget runs out. Consider using a personal card for subscriptions."
|
|
78
|
+
|
|
79
|
+
### Commands
|
|
56
80
|
|
|
57
81
|
List cards:
|
|
58
82
|
```
|
|
59
83
|
clawcard agent cards --json
|
|
60
84
|
```
|
|
61
85
|
|
|
62
|
-
Create card:
|
|
86
|
+
Create card (ONLY after confirming no existing card works):
|
|
63
87
|
```
|
|
64
88
|
clawcard agent cards create --amount <cents> --type <single_use|merchant_locked> --memo "description" --json
|
|
65
89
|
```
|
|
@@ -74,6 +98,93 @@ Close card:
|
|
|
74
98
|
clawcard agent cards close <card-id> --json
|
|
75
99
|
```
|
|
76
100
|
|
|
101
|
+
## Stablecoin Wallet (USDC on Base)
|
|
102
|
+
|
|
103
|
+
Your agent can have a USDC wallet for crypto payments, agent-to-agent transfers, and x402 API access.
|
|
104
|
+
|
|
105
|
+
**Use wallet for:** x402 APIs (HTTP 402 responses), crypto transfers, micropayments
|
|
106
|
+
**Use cards for:** traditional merchant checkouts, websites with payment forms
|
|
107
|
+
|
|
108
|
+
### Setup
|
|
109
|
+
|
|
110
|
+
Check if you have a wallet:
|
|
111
|
+
```
|
|
112
|
+
clawcard agent wallet --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If you get `"No wallet found"`, create one via the API or run `clawcard agent wallet` interactively.
|
|
116
|
+
|
|
117
|
+
### Commands
|
|
118
|
+
|
|
119
|
+
Check balance (shows USDC + FIAT spending power):
|
|
120
|
+
```
|
|
121
|
+
clawcard agent wallet balance --json
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Send USDC to an address:
|
|
125
|
+
```
|
|
126
|
+
clawcard agent wallet send --to 0xADDRESS --amount 5.00 --json
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Pay a URL via x402 (default — when a service returns HTTP 402):
|
|
130
|
+
```
|
|
131
|
+
clawcard agent wallet send --url https://api.example.com/data --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Pay a URL via MPP (Machine Payments Protocol — Stripe/Tempo):
|
|
135
|
+
```
|
|
136
|
+
clawcard agent wallet send --url https://api.example.com/data --protocol mpp --json
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
View transaction history:
|
|
140
|
+
```
|
|
141
|
+
clawcard agent wallet transactions --json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Fund your wallet from your FIAT balance (2% conversion fee):
|
|
145
|
+
```
|
|
146
|
+
clawcard agent wallet fund --amount 10.00 --json
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Or send USDC directly to your wallet address on Base. Check your address with `clawcard agent wallet --json`.
|
|
150
|
+
|
|
151
|
+
## Discover Services
|
|
152
|
+
|
|
153
|
+
**When you need a capability you don't have** (web search, data enrichment, image generation, etc.), search the x402 ecosystem:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
clawcard agent discover --query "web search" --json
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
This returns paid API services you can access with your wallet. To use one:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
clawcard agent wallet send --url https://discovered-service.com/endpoint --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The wallet handles payment automatically via the x402 protocol. No API keys or subscriptions needed — just USDC micropayments.
|
|
166
|
+
|
|
167
|
+
Browse all available services:
|
|
168
|
+
```
|
|
169
|
+
clawcard agent discover --json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## On-Chain Identity (ERC-8004)
|
|
173
|
+
|
|
174
|
+
Your agent can have a verifiable on-chain identity — an NFT on Base that proves who the agent is, what it can do, and links to its wallet address.
|
|
175
|
+
|
|
176
|
+
Register or view identity:
|
|
177
|
+
```
|
|
178
|
+
clawcard agent identity --json
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## A2A Agent Card
|
|
182
|
+
|
|
183
|
+
View your agent's discovery card (used by other agents to find and interact with you):
|
|
184
|
+
```
|
|
185
|
+
clawcard agent card --json
|
|
186
|
+
```
|
|
187
|
+
|
|
77
188
|
## Credentials
|
|
78
189
|
|
|
79
190
|
Store and retrieve secrets. Use consistent lowercase naming.
|
|
@@ -119,34 +230,56 @@ clawcard agent billing-address --json
|
|
|
119
230
|
```
|
|
120
231
|
|
|
121
232
|
Returns: name, line1, line2, city, state, zip, country.
|
|
122
|
-
Use these values to fill billing/address fields on checkout pages.
|
|
123
233
|
|
|
124
234
|
## Paying on Checkout Pages
|
|
125
235
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
236
|
+
**FOLLOW THESE STEPS IN ORDER:**
|
|
237
|
+
|
|
238
|
+
1. **Check existing cards FIRST:**
|
|
239
|
+
```
|
|
240
|
+
clawcard agent cards --json
|
|
241
|
+
```
|
|
242
|
+
Look for an open card that matches this merchant. If found, skip to step 4.
|
|
243
|
+
|
|
244
|
+
2. **Check budget:**
|
|
245
|
+
```
|
|
246
|
+
clawcard agent budget --json
|
|
130
247
|
```
|
|
131
|
-
|
|
248
|
+
|
|
249
|
+
3. **Create a card ONLY if no existing card works:**
|
|
132
250
|
```
|
|
133
|
-
|
|
134
|
-
|
|
251
|
+
clawcard agent cards create --amount <cents> --type single_use --memo "description of purchase" --json
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
4. **Get billing address:**
|
|
255
|
+
```
|
|
256
|
+
clawcard agent billing-address --json
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
5. **Fill non-payment fields** (name, email, address, zip) using the billing address.
|
|
260
|
+
|
|
261
|
+
6. **Get card details:**
|
|
262
|
+
```
|
|
263
|
+
clawcard agent cards details <card-id> --json
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
7. **Fill card fields** (card number, expiry, CVC) yourself if possible.
|
|
267
|
+
|
|
268
|
+
8. **If card fields are in iframes you can't reach**, use the browser extension:
|
|
135
269
|
```
|
|
136
270
|
clawcard agent pay --card-id <card-id> --json
|
|
137
271
|
```
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
5. If the extension is not installed, this will return an error —
|
|
141
|
-
fall back to telling the user they need the extension installed.
|
|
142
|
-
6. After running pay, wait a moment then verify the fields are filled
|
|
143
|
-
before clicking the submit/pay button.
|
|
272
|
+
|
|
273
|
+
9. **Verify fields are filled**, then submit the payment.
|
|
144
274
|
|
|
145
275
|
## Tips
|
|
146
276
|
|
|
147
|
-
-
|
|
148
|
-
- Check budget before
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
277
|
+
- **ALWAYS check existing resources before creating new ones** — cards, wallet, credentials.
|
|
278
|
+
- Check budget before spending: `clawcard agent budget --json`
|
|
279
|
+
- For API payments that return HTTP 402, use the wallet: `clawcard agent wallet send --url <url> --json`
|
|
280
|
+
- For traditional checkouts, use cards. For crypto/x402, use the wallet.
|
|
281
|
+
- Default to `single_use` cards. Only use `merchant_locked` for repeat purchases at the same merchant.
|
|
282
|
+
- NEVER silently pay for a subscription. Always warn the user first.
|
|
283
|
+
- Store credentials with consistent naming so you can find them later.
|
|
284
|
+
- If you need a capability (search, enrichment, scraping, etc.), discover it: `clawcard agent discover --query "..." --json`
|
|
285
|
+
- If a service returns HTTP 402, your wallet can pay for it automatically.
|
package/src/agent-api.js
CHANGED
|
@@ -113,3 +113,61 @@ export const listActivity = (agentId, params = {}) => {
|
|
|
113
113
|
const query = qs.toString();
|
|
114
114
|
return agentRequest(`/api/agents/${agentId}/activity${query ? "?" + query : ""}`);
|
|
115
115
|
};
|
|
116
|
+
|
|
117
|
+
// Wallet
|
|
118
|
+
export const getWallet = (agentId) =>
|
|
119
|
+
agentRequest(`/api/agents/${agentId}/wallet`);
|
|
120
|
+
|
|
121
|
+
export const createWallet = (agentId) =>
|
|
122
|
+
agentRequest(`/api/agents/${agentId}/wallet`, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
body: JSON.stringify({}),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export const walletAction = (agentId, action) =>
|
|
128
|
+
agentRequest(`/api/agents/${agentId}/wallet`, {
|
|
129
|
+
method: "PATCH",
|
|
130
|
+
body: JSON.stringify({ action }),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
export const walletFund = (agentId, amount) =>
|
|
134
|
+
agentRequest(`/api/agents/${agentId}/wallet/fund`, {
|
|
135
|
+
method: "POST",
|
|
136
|
+
body: JSON.stringify({ amount }),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
export const walletSend = (agentId, data) =>
|
|
140
|
+
agentRequest(`/api/agents/${agentId}/wallet/send`, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
body: JSON.stringify(data),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export const walletTransactions = (agentId, params = {}) => {
|
|
146
|
+
const qs = new URLSearchParams();
|
|
147
|
+
if (params.limit) qs.set("limit", params.limit);
|
|
148
|
+
const query = qs.toString();
|
|
149
|
+
return agentRequest(`/api/agents/${agentId}/wallet/transactions${query ? "?" + query : ""}`);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Discovery
|
|
153
|
+
export const discoverServices = (params = {}) => {
|
|
154
|
+
const qs = new URLSearchParams();
|
|
155
|
+
if (params.query) qs.set("q", params.query);
|
|
156
|
+
if (params.limit) qs.set("limit", params.limit);
|
|
157
|
+
const query = qs.toString();
|
|
158
|
+
return agentRequest(`/api/discover${query ? "?" + query : ""}`);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// On-Chain Identity (ERC-8004)
|
|
162
|
+
export const getOnChainIdentity = (agentId) =>
|
|
163
|
+
agentRequest(`/api/agents/${agentId}/identity`);
|
|
164
|
+
|
|
165
|
+
export const registerOnChainIdentity = (agentId, data = {}) =>
|
|
166
|
+
agentRequest(`/api/agents/${agentId}/identity`, {
|
|
167
|
+
method: "POST",
|
|
168
|
+
body: JSON.stringify(data),
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// A2A Agent Card
|
|
172
|
+
export const getAgentCard = (agentId) =>
|
|
173
|
+
agentRequest(`/api/agents/${agentId}/agent-card`);
|
package/src/commands/agent.js
CHANGED
|
@@ -15,6 +15,16 @@ import {
|
|
|
15
15
|
getCredential,
|
|
16
16
|
getBudget,
|
|
17
17
|
listActivity,
|
|
18
|
+
getWallet,
|
|
19
|
+
createWallet as createWalletApi,
|
|
20
|
+
walletAction,
|
|
21
|
+
walletFund,
|
|
22
|
+
walletSend,
|
|
23
|
+
walletTransactions as walletTransactionsApi,
|
|
24
|
+
discoverServices,
|
|
25
|
+
getOnChainIdentity,
|
|
26
|
+
registerOnChainIdentity,
|
|
27
|
+
getAgentCard,
|
|
18
28
|
} from "../agent-api.js";
|
|
19
29
|
|
|
20
30
|
const orange = chalk.hex("#FF6B35");
|
|
@@ -38,10 +48,24 @@ export async function agentInfoCmd(options) {
|
|
|
38
48
|
if (options.json) return output(me, true);
|
|
39
49
|
|
|
40
50
|
const budget = await getBudget(me.keyId);
|
|
51
|
+
|
|
52
|
+
let wallet = null;
|
|
53
|
+
try {
|
|
54
|
+
wallet = await getWallet(me.keyId);
|
|
55
|
+
} catch {
|
|
56
|
+
// No wallet — that's fine
|
|
57
|
+
}
|
|
58
|
+
|
|
41
59
|
console.log();
|
|
42
60
|
console.log(` Name: ${orange.bold(me.name || "unnamed")}`);
|
|
43
61
|
console.log(` Email: ${me.email || "-"}`);
|
|
44
62
|
console.log(` Phone: ${me.phone || "-"}`);
|
|
63
|
+
if (wallet) {
|
|
64
|
+
console.log(` Wallet: ${orange(wallet.address)} ${chalk.dim("(Base)")}`);
|
|
65
|
+
console.log(` USDC: ${chalk.green(wallet.balanceUsdc + " USDC")}`);
|
|
66
|
+
} else {
|
|
67
|
+
console.log(` Wallet: ${chalk.dim("none — run: clawcard agent wallet")}`);
|
|
68
|
+
}
|
|
45
69
|
console.log(` Key ID: ${chalk.dim(me.keyId)}`);
|
|
46
70
|
console.log(` Budget: ${chalk.green("$" + ((budget.budgetCents || 0) / 100).toFixed(2))}`);
|
|
47
71
|
console.log();
|
|
@@ -376,3 +400,362 @@ export async function agentPayCmd(options) {
|
|
|
376
400
|
console.log(` Error: ${result.error}`);
|
|
377
401
|
}
|
|
378
402
|
}
|
|
403
|
+
|
|
404
|
+
// ── Wallet ──
|
|
405
|
+
|
|
406
|
+
export async function agentWalletCmd(options) {
|
|
407
|
+
const agentId = await getAgentId();
|
|
408
|
+
|
|
409
|
+
// Try to get existing wallet
|
|
410
|
+
try {
|
|
411
|
+
const wallet = await getWallet(agentId);
|
|
412
|
+
if (options.json) return output(wallet, true);
|
|
413
|
+
|
|
414
|
+
console.log();
|
|
415
|
+
console.log(` Address: ${orange(wallet.address)}`);
|
|
416
|
+
console.log(` Network: Base`);
|
|
417
|
+
console.log(` Balance: ${chalk.green(wallet.balanceUsdc + " USDC")}`);
|
|
418
|
+
console.log(` Status: ${wallet.status}`);
|
|
419
|
+
console.log();
|
|
420
|
+
return;
|
|
421
|
+
} catch (err) {
|
|
422
|
+
// No wallet — prompt to create
|
|
423
|
+
if (!err.message.includes("No wallet found") && !err.message.includes("404")) {
|
|
424
|
+
if (options.json) return output({ error: err.message }, true);
|
|
425
|
+
console.log(` Error: ${err.message}`);
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (options.json) {
|
|
431
|
+
return output({ error: "No wallet found" }, true);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Interactive prompt to create
|
|
435
|
+
const prompts = await import("@clack/prompts");
|
|
436
|
+
const shouldCreate = await prompts.confirm({
|
|
437
|
+
message: "No wallet detected. Create a USDC wallet on Base?",
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
if (prompts.isCancel(shouldCreate) || !shouldCreate) {
|
|
441
|
+
console.log(" Wallet creation cancelled.");
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
try {
|
|
446
|
+
const wallet = await createWalletApi(agentId);
|
|
447
|
+
console.log();
|
|
448
|
+
console.log(` ${chalk.green("Wallet created!")}`);
|
|
449
|
+
console.log();
|
|
450
|
+
console.log(` Address: ${orange(wallet.address)}`);
|
|
451
|
+
console.log(` Network: Base`);
|
|
452
|
+
console.log(` Balance: ${wallet.balanceUsdc} USDC`);
|
|
453
|
+
console.log(` Status: ${wallet.status}`);
|
|
454
|
+
console.log();
|
|
455
|
+
console.log(chalk.dim(" Fund via FIAT balance or send USDC directly to the address above."));
|
|
456
|
+
console.log();
|
|
457
|
+
} catch (err) {
|
|
458
|
+
console.log(` Error creating wallet: ${err.message}`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export async function agentWalletBalanceCmd(options) {
|
|
463
|
+
const agentId = await getAgentId();
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
const wallet = await getWallet(agentId);
|
|
467
|
+
const budget = await getBudget(agentId);
|
|
468
|
+
const fiatBudget = (budget.budgetCents || 0) / 100;
|
|
469
|
+
const usdcBalance = parseFloat(wallet.balanceUsdc);
|
|
470
|
+
const effective = usdcBalance + fiatBudget;
|
|
471
|
+
|
|
472
|
+
if (options.json) return output({ ...wallet, fiatBudgetCents: budget.budgetCents, effectiveUsdc: effective.toFixed(2) }, true);
|
|
473
|
+
|
|
474
|
+
console.log();
|
|
475
|
+
console.log(` USDC Balance: ${chalk.green(wallet.balanceUsdc + " USDC")}`);
|
|
476
|
+
console.log(` FIAT Budget: ${chalk.green("$" + fiatBudget.toFixed(2))} ${chalk.dim("(available for auto-conversion)")}`);
|
|
477
|
+
console.log(` Effective: ${chalk.green("~$" + effective.toFixed(2))} ${chalk.dim("total spending power")}`);
|
|
478
|
+
console.log();
|
|
479
|
+
} catch (err) {
|
|
480
|
+
if (options.json) return output({ error: err.message }, true);
|
|
481
|
+
console.log(` Error: ${err.message}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export async function agentWalletSendCmd(options) {
|
|
486
|
+
// Validate input before making any API calls
|
|
487
|
+
if (options.to && options.url) {
|
|
488
|
+
const err = "Cannot use both --to and --url. Use --to for direct sends, --url for x402.";
|
|
489
|
+
if (options.json) return output({ success: false, error: err }, true);
|
|
490
|
+
console.log(` Error: ${err}`);
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
if (options.to && !options.amount) {
|
|
494
|
+
const err = "--to requires --amount";
|
|
495
|
+
if (options.json) return output({ success: false, error: err }, true);
|
|
496
|
+
console.log(` Error: ${err}`);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (options.amount && !options.to) {
|
|
500
|
+
const err = "--amount requires --to";
|
|
501
|
+
if (options.json) return output({ success: false, error: err }, true);
|
|
502
|
+
console.log(` Error: ${err}`);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
if (!options.to && !options.url) {
|
|
506
|
+
const err = "Provide --to <address> --amount <usdc> or --url <x402-url>";
|
|
507
|
+
if (options.json) return output({ success: false, error: err }, true);
|
|
508
|
+
console.log(` Error: ${err}`);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const agentId = await getAgentId();
|
|
513
|
+
|
|
514
|
+
const data = {};
|
|
515
|
+
if (options.to) {
|
|
516
|
+
data.to = options.to;
|
|
517
|
+
data.amountUsdc = options.amount;
|
|
518
|
+
} else if (options.url) {
|
|
519
|
+
data.url = options.url;
|
|
520
|
+
if (options.protocol) data.protocol = options.protocol;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (options.memo) data.memo = options.memo;
|
|
524
|
+
|
|
525
|
+
try {
|
|
526
|
+
const result = await walletSend(agentId, data);
|
|
527
|
+
if (options.json) return output(result, true);
|
|
528
|
+
|
|
529
|
+
if (result.success) {
|
|
530
|
+
console.log();
|
|
531
|
+
console.log(` ${chalk.green("Sent!")} ${result.amountUsdc} USDC → ${result.to}`);
|
|
532
|
+
console.log(` TX: ${chalk.dim(result.txHash)}`);
|
|
533
|
+
console.log(` Protocol: ${result.protocol}`);
|
|
534
|
+
if (result.fiatConverted) {
|
|
535
|
+
console.log(` Converted: ${result.fiatConverted} from FIAT budget`);
|
|
536
|
+
}
|
|
537
|
+
console.log();
|
|
538
|
+
} else {
|
|
539
|
+
console.log(` Error: ${result.error}`);
|
|
540
|
+
}
|
|
541
|
+
} catch (err) {
|
|
542
|
+
if (options.json) return output({ error: err.message }, true);
|
|
543
|
+
console.log(` Error: ${err.message}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export async function agentWalletTransactionsCmd(options) {
|
|
548
|
+
const agentId = await getAgentId();
|
|
549
|
+
|
|
550
|
+
try {
|
|
551
|
+
const result = await walletTransactionsApi(agentId, { limit: options.limit });
|
|
552
|
+
if (options.json) return output(result, true);
|
|
553
|
+
|
|
554
|
+
const txns = result.transactions || [];
|
|
555
|
+
if (!txns.length) {
|
|
556
|
+
console.log(" No wallet transactions");
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
console.log();
|
|
561
|
+
for (const t of txns) {
|
|
562
|
+
const dir = t.type === "receive" ? chalk.green("←") : t.type === "send" ? chalk.blue("→") : chalk.yellow("⟳");
|
|
563
|
+
const date = new Date(t.createdAt).toLocaleString();
|
|
564
|
+
console.log(` ${dir} ${t.amountUsdc} USDC ${chalk.dim(t.counterparty || "")} ${chalk.dim(t.protocol)} ${chalk.dim(date)}`);
|
|
565
|
+
}
|
|
566
|
+
console.log();
|
|
567
|
+
} catch (err) {
|
|
568
|
+
if (options.json) return output({ error: err.message }, true);
|
|
569
|
+
console.log(` Error: ${err.message}`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
export async function agentWalletFundCmd(options) {
|
|
574
|
+
if (!options.amount) {
|
|
575
|
+
const err = "--amount is required (in dollars, e.g., 10.00)";
|
|
576
|
+
if (options.json) return output({ success: false, error: err }, true);
|
|
577
|
+
console.log(` Error: ${err}`);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const agentId = await getAgentId();
|
|
582
|
+
try {
|
|
583
|
+
const result = await walletFund(agentId, options.amount);
|
|
584
|
+
if (options.json) return output(result, true);
|
|
585
|
+
|
|
586
|
+
if (result.success) {
|
|
587
|
+
console.log();
|
|
588
|
+
console.log(` ${chalk.green("Funded!")} ${result.funded} USDC added to wallet`);
|
|
589
|
+
console.log(` Cost: $${(result.costCents / 100).toFixed(2)} (includes $${(result.feeCents / 100).toFixed(2)} fee)`);
|
|
590
|
+
console.log(` TX: ${chalk.dim(result.txHash)}`);
|
|
591
|
+
console.log(` Budget: $${(result.newFiatBudgetCents / 100).toFixed(2)} remaining`);
|
|
592
|
+
console.log();
|
|
593
|
+
} else {
|
|
594
|
+
console.log(` Error: ${result.error}`);
|
|
595
|
+
}
|
|
596
|
+
} catch (err) {
|
|
597
|
+
if (options.json) return output({ success: false, error: err.message }, true);
|
|
598
|
+
console.log(` Error: ${err.message}`);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export async function agentWalletActionCmd(action, options) {
|
|
603
|
+
const agentId = await getAgentId();
|
|
604
|
+
try {
|
|
605
|
+
const result = await walletAction(agentId, action);
|
|
606
|
+
if (options.json) return output(result, true);
|
|
607
|
+
console.log(` Wallet ${action}: ${result.status}`);
|
|
608
|
+
} catch (err) {
|
|
609
|
+
if (options.json) return output({ error: err.message }, true);
|
|
610
|
+
console.log(` Error: ${err.message}`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// ── On-Chain Identity (ERC-8004) ──
|
|
615
|
+
|
|
616
|
+
export async function agentIdentityCmd(options) {
|
|
617
|
+
const agentId = await getAgentId();
|
|
618
|
+
|
|
619
|
+
// Try to get existing on-chain identity
|
|
620
|
+
try {
|
|
621
|
+
const identity = await getOnChainIdentity(agentId);
|
|
622
|
+
if (options.json) return output(identity, true);
|
|
623
|
+
|
|
624
|
+
console.log();
|
|
625
|
+
console.log(` ${orange.bold("On-Chain Identity (ERC-8004)")}`);
|
|
626
|
+
console.log();
|
|
627
|
+
if (identity.metadata) {
|
|
628
|
+
console.log(` Name: ${identity.metadata.name}`);
|
|
629
|
+
console.log(` Address: ${orange(identity.walletAddress)}`);
|
|
630
|
+
console.log(` Network: ${identity.network}`);
|
|
631
|
+
console.log(` Token ID: ${chalk.dim(identity.tokenId)}`);
|
|
632
|
+
if (identity.metadata.properties) {
|
|
633
|
+
const caps = identity.metadata.properties.capabilities || [];
|
|
634
|
+
console.log(` Capabilities: ${caps.join(", ") || "none"}`);
|
|
635
|
+
}
|
|
636
|
+
} else {
|
|
637
|
+
console.log(` Wallet: ${orange(identity.walletAddress)}`);
|
|
638
|
+
console.log(` Token ID: ${identity.tokenId}`);
|
|
639
|
+
console.log(` URI: ${chalk.dim(identity.metadataURI)}`);
|
|
640
|
+
}
|
|
641
|
+
console.log();
|
|
642
|
+
return;
|
|
643
|
+
} catch (err) {
|
|
644
|
+
// No identity found — offer to register
|
|
645
|
+
if (!err.message.includes("No on-chain identity") && !err.message.includes("No wallet") && !err.message.includes("404")) {
|
|
646
|
+
if (options.json) return output({ error: err.message }, true);
|
|
647
|
+
console.log(` Error: ${err.message}`);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// No identity found
|
|
653
|
+
if (options.json) {
|
|
654
|
+
// In JSON mode, try to register automatically
|
|
655
|
+
try {
|
|
656
|
+
const result = await registerOnChainIdentity(agentId, {});
|
|
657
|
+
return output(result, true);
|
|
658
|
+
} catch (err) {
|
|
659
|
+
return output({ error: err.message }, true);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Interactive prompt to register
|
|
664
|
+
const prompts = await import("@clack/prompts");
|
|
665
|
+
const shouldRegister = await prompts.confirm({
|
|
666
|
+
message: "No on-chain identity found. Register one now?",
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
if (prompts.isCancel(shouldRegister) || !shouldRegister) {
|
|
670
|
+
console.log(" Registration cancelled.");
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
try {
|
|
675
|
+
const result = await registerOnChainIdentity(agentId, {});
|
|
676
|
+
console.log();
|
|
677
|
+
console.log(` ${chalk.green("Identity prepared!")}`);
|
|
678
|
+
console.log();
|
|
679
|
+
console.log(` Wallet: ${orange(result.walletAddress)}`);
|
|
680
|
+
console.log(` Network: ${result.network}`);
|
|
681
|
+
console.log(` Standard: ERC-8004`);
|
|
682
|
+
if (result.metadata?.properties?.capabilities) {
|
|
683
|
+
console.log(` Capabilities: ${result.metadata.properties.capabilities.join(", ")}`);
|
|
684
|
+
}
|
|
685
|
+
console.log();
|
|
686
|
+
if (result.note) {
|
|
687
|
+
console.log(chalk.dim(` ${result.note}`));
|
|
688
|
+
console.log();
|
|
689
|
+
}
|
|
690
|
+
} catch (err) {
|
|
691
|
+
console.log(` Error registering identity: ${err.message}`);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// ── A2A Agent Card ──
|
|
696
|
+
|
|
697
|
+
export async function agentCardCmd(options) {
|
|
698
|
+
const agentId = await getAgentId();
|
|
699
|
+
|
|
700
|
+
try {
|
|
701
|
+
const card = await getAgentCard(agentId);
|
|
702
|
+
if (options.json) return output(card, true);
|
|
703
|
+
|
|
704
|
+
console.log();
|
|
705
|
+
console.log(` ${orange.bold("A2A Agent Card")}`);
|
|
706
|
+
console.log();
|
|
707
|
+
console.log(` Name: ${card.name}`);
|
|
708
|
+
console.log(` Description: ${card.description}`);
|
|
709
|
+
console.log(` URL: ${chalk.dim(card.url)}`);
|
|
710
|
+
console.log(` Version: ${card.version}`);
|
|
711
|
+
console.log(` Provider: ${card.provider.organization}`);
|
|
712
|
+
console.log();
|
|
713
|
+
console.log(` ${orange("Skills:")}`);
|
|
714
|
+
for (const skill of card.skills || []) {
|
|
715
|
+
console.log(` - ${chalk.bold(skill.name)} ${chalk.dim(`[${skill.tags.join(", ")}]`)}`);
|
|
716
|
+
console.log(` ${skill.description}`);
|
|
717
|
+
}
|
|
718
|
+
console.log();
|
|
719
|
+
console.log(` Auth: ${(card.authentication?.schemes || []).join(", ")}`);
|
|
720
|
+
console.log(` Input: ${(card.defaultInputModes || []).join(", ")}`);
|
|
721
|
+
console.log(` Output: ${(card.defaultOutputModes || []).join(", ")}`);
|
|
722
|
+
console.log();
|
|
723
|
+
} catch (err) {
|
|
724
|
+
if (options.json) return output({ error: err.message }, true);
|
|
725
|
+
console.log(` Error: ${err.message}`);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// ── Discovery ──
|
|
730
|
+
|
|
731
|
+
export async function agentDiscoverCmd(options) {
|
|
732
|
+
try {
|
|
733
|
+
const result = await discoverServices({
|
|
734
|
+
query: options.query,
|
|
735
|
+
limit: options.limit,
|
|
736
|
+
});
|
|
737
|
+
if (options.json) return output(result, true);
|
|
738
|
+
|
|
739
|
+
const services = result.services || [];
|
|
740
|
+
if (!services.length) {
|
|
741
|
+
console.log(` No services found${options.query ? ` for "${options.query}"` : ""}`);
|
|
742
|
+
console.log(chalk.dim(" The x402 ecosystem is growing — try a broader search or check back later."));
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
console.log();
|
|
747
|
+
console.log(` ${chalk.green(services.length)} services found${options.query ? ` for "${options.query}"` : ""}`);
|
|
748
|
+
console.log();
|
|
749
|
+
for (const s of services) {
|
|
750
|
+
console.log(` ${orange(s.url)}`);
|
|
751
|
+
console.log(` ${s.description}`);
|
|
752
|
+
console.log(` Price: ${chalk.green(s.priceUsdc + " USDC")} Network: ${chalk.dim(s.network)}`);
|
|
753
|
+
console.log();
|
|
754
|
+
}
|
|
755
|
+
console.log(chalk.dim(" Pay for any service: clawcard agent wallet send --url <url> --json"));
|
|
756
|
+
console.log();
|
|
757
|
+
} catch (err) {
|
|
758
|
+
if (options.json) return output({ error: err.message }, true);
|
|
759
|
+
console.log(` Error: ${err.message}`);
|
|
760
|
+
}
|
|
761
|
+
}
|
package/src/index.js
CHANGED
|
@@ -208,6 +208,78 @@ agentCards
|
|
|
208
208
|
await agentCardsActionCmd(cardId, "resume", options);
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
+
// Agent wallet
|
|
212
|
+
const agentWallet = agent.command("wallet").description("Stablecoin wallet (USDC on Base)");
|
|
213
|
+
agentWallet
|
|
214
|
+
.option("--json", "Output as JSON")
|
|
215
|
+
.action(async (options) => {
|
|
216
|
+
const { agentWalletCmd } = await import("./commands/agent.js");
|
|
217
|
+
await agentWalletCmd(options);
|
|
218
|
+
});
|
|
219
|
+
agentWallet
|
|
220
|
+
.command("balance")
|
|
221
|
+
.description("Check wallet balance + effective spending power")
|
|
222
|
+
.option("--json", "Output as JSON")
|
|
223
|
+
.action(async (options) => {
|
|
224
|
+
const { agentWalletBalanceCmd } = await import("./commands/agent.js");
|
|
225
|
+
await agentWalletBalanceCmd(options);
|
|
226
|
+
});
|
|
227
|
+
agentWallet
|
|
228
|
+
.command("send")
|
|
229
|
+
.description("Send USDC to an address or pay an x402/MPP URL")
|
|
230
|
+
.option("--to <address>", "Recipient 0x address")
|
|
231
|
+
.option("--amount <usdc>", "Amount in USDC (e.g., 5.00)")
|
|
232
|
+
.option("--url <url>", "URL to pay for access (x402 or MPP)")
|
|
233
|
+
.option("--protocol <protocol>", "Payment protocol: x402 (default) or mpp")
|
|
234
|
+
.option("--memo <memo>", "Optional memo")
|
|
235
|
+
.option("--json", "Output as JSON")
|
|
236
|
+
.action(async (options) => {
|
|
237
|
+
const { agentWalletSendCmd } = await import("./commands/agent.js");
|
|
238
|
+
await agentWalletSendCmd(options);
|
|
239
|
+
});
|
|
240
|
+
agentWallet
|
|
241
|
+
.command("transactions")
|
|
242
|
+
.description("View wallet transaction history")
|
|
243
|
+
.option("--limit <n>", "Max results", "50")
|
|
244
|
+
.option("--json", "Output as JSON")
|
|
245
|
+
.action(async (options) => {
|
|
246
|
+
const { agentWalletTransactionsCmd } = await import("./commands/agent.js");
|
|
247
|
+
await agentWalletTransactionsCmd(options);
|
|
248
|
+
});
|
|
249
|
+
agentWallet
|
|
250
|
+
.command("fund")
|
|
251
|
+
.description("Fund wallet with USDC from FIAT balance")
|
|
252
|
+
.requiredOption("--amount <dollars>", "Amount in dollars to convert (e.g., 10.00)")
|
|
253
|
+
.option("--json", "Output as JSON")
|
|
254
|
+
.action(async (options) => {
|
|
255
|
+
const { agentWalletFundCmd } = await import("./commands/agent.js");
|
|
256
|
+
await agentWalletFundCmd(options);
|
|
257
|
+
});
|
|
258
|
+
agentWallet
|
|
259
|
+
.command("freeze")
|
|
260
|
+
.description("Freeze wallet (block all sends)")
|
|
261
|
+
.option("--json", "Output as JSON")
|
|
262
|
+
.action(async (options) => {
|
|
263
|
+
const { agentWalletActionCmd } = await import("./commands/agent.js");
|
|
264
|
+
await agentWalletActionCmd("freeze", options);
|
|
265
|
+
});
|
|
266
|
+
agentWallet
|
|
267
|
+
.command("unfreeze")
|
|
268
|
+
.description("Unfreeze wallet")
|
|
269
|
+
.option("--json", "Output as JSON")
|
|
270
|
+
.action(async (options) => {
|
|
271
|
+
const { agentWalletActionCmd } = await import("./commands/agent.js");
|
|
272
|
+
await agentWalletActionCmd("unfreeze", options);
|
|
273
|
+
});
|
|
274
|
+
agentWallet
|
|
275
|
+
.command("close")
|
|
276
|
+
.description("Permanently close wallet")
|
|
277
|
+
.option("--json", "Output as JSON")
|
|
278
|
+
.action(async (options) => {
|
|
279
|
+
const { agentWalletActionCmd } = await import("./commands/agent.js");
|
|
280
|
+
await agentWalletActionCmd("close", options);
|
|
281
|
+
});
|
|
282
|
+
|
|
211
283
|
// Agent credentials
|
|
212
284
|
const agentCreds = agent.command("creds").description("Credential vault");
|
|
213
285
|
agentCreds
|
|
@@ -278,6 +350,38 @@ agent
|
|
|
278
350
|
await agentBillingAddressCmd(options);
|
|
279
351
|
});
|
|
280
352
|
|
|
353
|
+
// Agent on-chain identity (ERC-8004)
|
|
354
|
+
agent
|
|
355
|
+
.command("identity")
|
|
356
|
+
.description("Register or view ERC-8004 on-chain identity")
|
|
357
|
+
.option("--json", "Output as JSON")
|
|
358
|
+
.action(async (options) => {
|
|
359
|
+
const { agentIdentityCmd } = await import("./commands/agent.js");
|
|
360
|
+
await agentIdentityCmd(options);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// Agent A2A card
|
|
364
|
+
agent
|
|
365
|
+
.command("card")
|
|
366
|
+
.description("View A2A agent card (discovery document)")
|
|
367
|
+
.option("--json", "Output as JSON")
|
|
368
|
+
.action(async (options) => {
|
|
369
|
+
const { agentCardCmd } = await import("./commands/agent.js");
|
|
370
|
+
await agentCardCmd(options);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
// Agent discover (x402 service discovery)
|
|
374
|
+
agent
|
|
375
|
+
.command("discover")
|
|
376
|
+
.description("Discover paid services in the x402 ecosystem")
|
|
377
|
+
.option("--query <query>", "Search term (e.g., 'web search', 'enrichment')")
|
|
378
|
+
.option("--limit <n>", "Max results", "20")
|
|
379
|
+
.option("--json", "Output as JSON")
|
|
380
|
+
.action(async (options) => {
|
|
381
|
+
const { agentDiscoverCmd } = await import("./commands/agent.js");
|
|
382
|
+
await agentDiscoverCmd(options);
|
|
383
|
+
});
|
|
384
|
+
|
|
281
385
|
// Settings
|
|
282
386
|
program
|
|
283
387
|
.command("settings")
|