@routstr/cocod 0.0.16
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/.github/workflows/ci.yml +21 -0
- package/.github/workflows/npm-publish.yml +78 -0
- package/.prettierrc +10 -0
- package/AGENTS.md +244 -0
- package/CLAUDE.md +105 -0
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/SKILL.md +238 -0
- package/bun.lock +69 -0
- package/docs/API.md +92 -0
- package/docs/daemon-api.json +245 -0
- package/package.json +32 -0
- package/src/cli-shared.ts +164 -0
- package/src/cli.ts +317 -0
- package/src/daemon.ts +184 -0
- package/src/index.ts +4 -0
- package/src/logs.test.ts +54 -0
- package/src/logs.ts +118 -0
- package/src/routes.test.ts +60 -0
- package/src/routes.ts +523 -0
- package/src/utils/config.ts +17 -0
- package/src/utils/crypto.test.ts +24 -0
- package/src/utils/crypto.ts +68 -0
- package/src/utils/logger.test.ts +82 -0
- package/src/utils/logger.ts +359 -0
- package/src/utils/state.test.ts +55 -0
- package/src/utils/state.ts +128 -0
- package/src/utils/wallet.ts +51 -0
- package/tsconfig.json +29 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cocod
|
|
3
|
+
description: A Cashu ecash wallet CLI for Bitcoin and Lightning payments. Use when managing Cashu tokens, sending/receiving payments via Lightning (bolt11) or ecash, handling HTTP 402 X-Cashu payment requests, or viewing wallet history.
|
|
4
|
+
compatibility: Requires cocod CLI to be installed. Supports Cashu ecash protocol, Lightning Network payments, and NUT-24 HTTP 402 X-Cashu flows.
|
|
5
|
+
metadata:
|
|
6
|
+
project: cocod
|
|
7
|
+
type: cashu-wallet
|
|
8
|
+
skill_version: 0.0.16
|
|
9
|
+
requires_cocod_version: 0.0.16
|
|
10
|
+
networks:
|
|
11
|
+
- cashu
|
|
12
|
+
- bitcoin
|
|
13
|
+
- lightning
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Cocod - Cashu Wallet CLI
|
|
17
|
+
|
|
18
|
+
Cocod is a Cashu wallet for managing ecash tokens and making Bitcoin/Lightning payments. It uses the Cashu protocol for privacy-preserving ecash transactions.
|
|
19
|
+
|
|
20
|
+
If a web/API request returns HTTP `402 Payment Required` with an `X-Cashu` header, use this skill to parse and settle the request with cocod.
|
|
21
|
+
|
|
22
|
+
## Agent Safety Policy (Required)
|
|
23
|
+
|
|
24
|
+
When acting as an AGENT with this skill:
|
|
25
|
+
|
|
26
|
+
- Always ask for explicit user permission before running any command/flow that can spend wallet funds, unless the user has already clearly instructed you to execute that spend action.
|
|
27
|
+
- Prefer preview/inspection commands before execution whenever available. For example, run `cocod x-cashu parse <request>` to inspect costs and requirements before `cocod x-cashu handle <request>`.
|
|
28
|
+
- Treat `~/.cocod` as sensitive. Never log, print, or expose its contents (including config, mnemonic material, wallet state, sockets, and pid files) unless the user explicitly requests a specific safe subset.
|
|
29
|
+
- Always surface issues and errors encountered while using the CLI or this skill. Do not hide failures behind partial success messaging.
|
|
30
|
+
- Do not manually work around CLI issues, missing behavior, or unexpected command failures without explicit user permission.
|
|
31
|
+
|
|
32
|
+
## What is Cashu?
|
|
33
|
+
|
|
34
|
+
Cashu is a Chaumian ecash protocol that lets you hold and transfer Bitcoin-backed tokens privately. It enables unlinkable transactions using blind signatures.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Install cocod CLI
|
|
40
|
+
bun install -g cocod
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Version Compatibility
|
|
44
|
+
|
|
45
|
+
This skill is version-pinned to an exact `cocod` CLI release.
|
|
46
|
+
|
|
47
|
+
- `metadata.skill_version` must match the npm package version.
|
|
48
|
+
- `metadata.requires_cocod_version` is pinned to that exact same version.
|
|
49
|
+
|
|
50
|
+
Check your installed CLI version:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cocod --version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If the version does not match the pinned values in this file, update `cocod` before using this skill.
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Initialize your wallet (generates mnemonic automatically)
|
|
62
|
+
cocod init
|
|
63
|
+
|
|
64
|
+
# Or with a custom mint
|
|
65
|
+
cocod init --mint-url https://mint.example.com
|
|
66
|
+
|
|
67
|
+
# Check balance
|
|
68
|
+
cocod balance
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Commands
|
|
72
|
+
|
|
73
|
+
### Core Wallet
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Check daemon and wallet status
|
|
77
|
+
cocod status
|
|
78
|
+
|
|
79
|
+
# Initialize wallet with optional mnemonic
|
|
80
|
+
cocod init [mnemonic] [--passphrase <passphrase>] [--mint-url <url>]
|
|
81
|
+
|
|
82
|
+
# Unlock encrypted wallet (only required when initialised with passphrase)
|
|
83
|
+
cocod unlock <passphrase>
|
|
84
|
+
|
|
85
|
+
# Get wallet balance
|
|
86
|
+
cocod balance
|
|
87
|
+
|
|
88
|
+
# Test daemon connection
|
|
89
|
+
cocod ping
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Receiving Payments
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Receive Cashu token
|
|
96
|
+
cocod receive cashu <token>
|
|
97
|
+
|
|
98
|
+
# Create Lightning invoice to receive
|
|
99
|
+
cocod receive bolt11 <amount> [--mint-url <url>]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Sending Payments
|
|
103
|
+
|
|
104
|
+
AGENT rule: commands in this section spend wallet funds. Ask for permission first unless the user already explicitly requested the spend action.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Create Cashu token to send to someone
|
|
108
|
+
cocod send cashu <amount> [--mint-url <url>]
|
|
109
|
+
|
|
110
|
+
# Pay a Lightning invoice
|
|
111
|
+
cocod send bolt11 <invoice> [--mint-url <url>]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### HTTP 402 Web Payments (NUT-24)
|
|
115
|
+
|
|
116
|
+
Use these commands when a server responds with HTTP `402` and an `X-Cashu` payment request.
|
|
117
|
+
|
|
118
|
+
AGENT rule: `cocod x-cashu handle <request>` can spend funds. Prefer `cocod x-cashu parse <request>` first to preview amount/requirements, then ask permission before handling unless already instructed.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Parse an encoded X-Cashu request from a 402 response header
|
|
122
|
+
cocod x-cashu parse <request>
|
|
123
|
+
|
|
124
|
+
# Settle the request and get an X-Cashu payment header value
|
|
125
|
+
cocod x-cashu handle <request>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Typical flow:
|
|
129
|
+
|
|
130
|
+
1. Read `X-Cashu` from the `402` response.
|
|
131
|
+
2. Run `cocod x-cashu parse <request>` to inspect amount and mint requirements.
|
|
132
|
+
3. Run `cocod x-cashu handle <request>` to generate payment token header value.
|
|
133
|
+
4. Retry the original web request with returned `X-Cashu: cashuB...` header.
|
|
134
|
+
|
|
135
|
+
### Mints
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Add a mint URL
|
|
139
|
+
cocod mints add <url>
|
|
140
|
+
|
|
141
|
+
# List configured mints
|
|
142
|
+
cocod mints list
|
|
143
|
+
|
|
144
|
+
# Get mint information
|
|
145
|
+
cocod mints info <url>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Lightning Address (NPC)
|
|
149
|
+
|
|
150
|
+
Lightning Addresses are email-style identifiers (like `name@npubx.cash`) that let others pay you over Lightning. If you have not purchased a username, NPC provides a free address from your Nostr npub; purchasing a username gives you a human-readable handle. Buying a username is a two-step flow so you can review the required sats before confirming payment.
|
|
151
|
+
|
|
152
|
+
AGENT rule: `cocod npc username <name> --confirm` is a spend action. Ask permission before running `--confirm` unless already instructed.
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Get your NPC Lightning Address
|
|
156
|
+
cocod npc address
|
|
157
|
+
|
|
158
|
+
# Reserve/buy an NPC username (two-step)
|
|
159
|
+
cocod npc username <name>
|
|
160
|
+
cocod npc username <name> --confirm
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### History
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# View wallet history
|
|
167
|
+
cocod history
|
|
168
|
+
|
|
169
|
+
# With pagination
|
|
170
|
+
cocod history --offset 0 --limit 20
|
|
171
|
+
|
|
172
|
+
# Watch for real-time updates
|
|
173
|
+
cocod history --watch
|
|
174
|
+
|
|
175
|
+
# Limit with watch
|
|
176
|
+
cocod history --limit 50 --watch
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Daemon Control
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Start the background daemon (started automatically when not running when required)
|
|
183
|
+
cocod daemon
|
|
184
|
+
|
|
185
|
+
# Stop the daemon
|
|
186
|
+
cocod stop
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Examples
|
|
190
|
+
|
|
191
|
+
**Initialize with encryption:**
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
cocod init --passphrase "my-secret"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Receive via Lightning:**
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
cocod receive bolt11 5000
|
|
201
|
+
# Returns: lnbc50u1... (share this invoice to receive)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Pay a Lightning invoice:**
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
cocod send bolt11 lnbc100u1p3w7j3...
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Send Cashu to a friend:**
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
cocod send cashu 1000
|
|
214
|
+
# Returns: cashuAeyJ0b2tlbiI6...
|
|
215
|
+
# Friend receives with: cocod receive cashu cashuAeyJ0b2tlbiI6...
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Check status and balance:**
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
cocod status
|
|
222
|
+
cocod balance
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**View recent history:**
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
cocod history --limit 10
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Concepts
|
|
232
|
+
|
|
233
|
+
- **Cashu**: Privacy-preserving ecash protocol using blind signatures
|
|
234
|
+
- **Mint**: Server that issues and redeems Cashu tokens
|
|
235
|
+
- **Token**: Transferable Cashu string representing satoshi value
|
|
236
|
+
- **Bolt11**: Lightning Network invoice format
|
|
237
|
+
- **NPC**: Lightning Address service for receiving payments
|
|
238
|
+
- **Mnemonic**: Seed phrase for wallet recovery
|
package/bun.lock
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "cocod",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@scure/bip39": "^2.0.1",
|
|
9
|
+
"coco-cashu-core": "1.1.2-rc.50",
|
|
10
|
+
"coco-cashu-plugin-npc": "2.4.1",
|
|
11
|
+
"coco-cashu-sqlite-bun": "1.1.2-rc.50",
|
|
12
|
+
"commander": "^14.0.2",
|
|
13
|
+
"nostr-tools": "^2.22.1",
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/bun": "latest",
|
|
17
|
+
"prettier": "^3.8.1",
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"typescript": "^5",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
"packages": {
|
|
25
|
+
"@cashu/cashu-ts": ["@cashu/cashu-ts@3.6.1", "", { "dependencies": { "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/base": "^2.0.0", "@scure/bip32": "^2.0.1" } }, "sha512-ynncvX5vv/m2Dzp28m1ApxNsmrsw1p6laOdOnvlHVOPK3x4Nz3K/ScV7UjnbuwubTVeIcKP1FXEdycedhhlJbQ=="],
|
|
26
|
+
|
|
27
|
+
"@noble/ciphers": ["@noble/ciphers@2.1.1", "", {}, "sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw=="],
|
|
28
|
+
|
|
29
|
+
"@noble/curves": ["@noble/curves@2.0.1", "", { "dependencies": { "@noble/hashes": "2.0.1" } }, "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw=="],
|
|
30
|
+
|
|
31
|
+
"@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="],
|
|
32
|
+
|
|
33
|
+
"@scure/base": ["@scure/base@2.0.0", "", {}, "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w=="],
|
|
34
|
+
|
|
35
|
+
"@scure/bip32": ["@scure/bip32@2.0.1", "", { "dependencies": { "@noble/curves": "2.0.1", "@noble/hashes": "2.0.1", "@scure/base": "2.0.0" } }, "sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA=="],
|
|
36
|
+
|
|
37
|
+
"@scure/bip39": ["@scure/bip39@2.0.1", "", { "dependencies": { "@noble/hashes": "2.0.1", "@scure/base": "2.0.0" } }, "sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg=="],
|
|
38
|
+
|
|
39
|
+
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
|
|
40
|
+
|
|
41
|
+
"@types/node": ["@types/node@25.1.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA=="],
|
|
42
|
+
|
|
43
|
+
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
|
|
44
|
+
|
|
45
|
+
"coco-cashu-core": ["coco-cashu-core@1.1.2-rc.50", "", { "dependencies": { "@cashu/cashu-ts": "^3.5.0", "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/bip32": "^2.0.1" }, "peerDependencies": { "typescript": "^5" } }, "sha512-eK5YuwvCWpeCwF/GEkMo90FCyek2mS+smQ51wKjkjTKzpkVVlNln52l2h1Wwce4VMnW6GSeL2IgT8IksM8Umuw=="],
|
|
46
|
+
|
|
47
|
+
"coco-cashu-plugin-npc": ["coco-cashu-plugin-npc@2.4.1", "", { "dependencies": { "npubcash-sdk": "^0.3.2" }, "peerDependencies": { "coco-cashu-core": "^1.1.2-rc.50", "typescript": "^5.0.0" } }, "sha512-0OhqXXRLBq/2VkeuyqHrTINCEQYEk9+dCD9Vq7+M94CDf7kLKQZmoDL6leTuHJ45pIVnALcOFnjIcRoJwV7iiA=="],
|
|
48
|
+
|
|
49
|
+
"coco-cashu-sqlite-bun": ["coco-cashu-sqlite-bun@1.1.2-rc.50", "", { "peerDependencies": { "coco-cashu-core": "1.1.2-rc.50", "typescript": "^5" } }, "sha512-wYAZjGmk3Xd75rq7y6AGLji4z5/3v5rWj6xgQoa3Qq+37zKnuCeLqVt+A3x/3EcNRLmNoW/u7vQJTJP4APHhIw=="],
|
|
50
|
+
|
|
51
|
+
"commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="],
|
|
52
|
+
|
|
53
|
+
"nostr-tools": ["nostr-tools@2.22.1", "", { "dependencies": { "@noble/ciphers": "2.1.1", "@noble/curves": "2.0.1", "@noble/hashes": "2.0.1", "@scure/base": "2.0.0", "@scure/bip32": "2.0.1", "@scure/bip39": "2.0.1", "nostr-wasm": "0.1.0" }, "peerDependencies": { "typescript": ">=5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-LJKy4lU6thO6Z6CVWkfqHGDt9m/M5IfRlmEI2hBXYLw4xa3jpfIHKJxXQhx/8C3TcN0YPkMRJlhGmu/g0VH80g=="],
|
|
54
|
+
|
|
55
|
+
"nostr-wasm": ["nostr-wasm@0.1.0", "", {}, "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA=="],
|
|
56
|
+
|
|
57
|
+
"npubcash-sdk": ["npubcash-sdk@0.3.2", "", { "dependencies": { "@cashu/cashu-ts": "^3.2.2", "nostr-tools": "^2.19.4", "npubcash-types": "^0.1.1" } }, "sha512-mJwvWW6rAq04b/AHbd76T4gTeUqP2uprc01Y0ToU9ZK5co3n1PmBKWLBLbPN+VgpHhE0LubzjLq/qm70YWUugA=="],
|
|
58
|
+
|
|
59
|
+
"npubcash-types": ["npubcash-types@0.1.1", "", {}, "sha512-/HGfes2cvQpkrWOuUrdemJJhJUQu+xiXl4x+AxQtKUMGCB8uEhfrXJfAQ0n+DgtkIX1YVLOh0a/e6E5LX+fUew=="],
|
|
60
|
+
|
|
61
|
+
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
|
62
|
+
|
|
63
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
64
|
+
|
|
65
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
66
|
+
|
|
67
|
+
"npubcash-sdk/@cashu/cashu-ts": ["@cashu/cashu-ts@3.3.0", "", { "dependencies": { "@noble/curves": "^2.0.1", "@noble/hashes": "^2.0.1", "@scure/base": "^2.0.0", "@scure/bip32": "^2.0.1" } }, "sha512-hHUOhjPLK77axDdj/4qO5mJ14rkh+rZGe1Gz2RbkW2j+SIglNbc2NsKSvjvoQcshupm02FudKi9Y3s3M8ZSYzg=="],
|
|
68
|
+
}
|
|
69
|
+
}
|
package/docs/API.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# API and Command Reference
|
|
2
|
+
|
|
3
|
+
This document contains the detailed reference moved out of `README.md`.
|
|
4
|
+
|
|
5
|
+
## CLI commands
|
|
6
|
+
|
|
7
|
+
All commands are available under `cocod`.
|
|
8
|
+
|
|
9
|
+
### Wallet
|
|
10
|
+
|
|
11
|
+
- `status` - Check daemon and wallet status
|
|
12
|
+
- `init [mnemonic]` - Initialize wallet; generates mnemonic if omitted
|
|
13
|
+
- `--passphrase <str>` encrypt wallet at creation time
|
|
14
|
+
- `--mint-url <url>` set default mint URL
|
|
15
|
+
- `unlock <passphrase>` - Unlock encrypted wallet
|
|
16
|
+
- `balance` - Get wallet balances
|
|
17
|
+
- `history` - List history entries
|
|
18
|
+
- `--offset <number>` default `0`
|
|
19
|
+
- `--limit <number>` default `20`, max `100`
|
|
20
|
+
- `--watch` stream real-time updates after initial fetch
|
|
21
|
+
|
|
22
|
+
### Receive
|
|
23
|
+
|
|
24
|
+
- `receive cashu <token>` - Receive a Cashu token
|
|
25
|
+
- `receive bolt11 <amount>` - Create a Lightning invoice
|
|
26
|
+
- `--mint-url <url>` override default mint for this request
|
|
27
|
+
|
|
28
|
+
### Send
|
|
29
|
+
|
|
30
|
+
- `send cashu <amount>` - Create a Cashu token to send
|
|
31
|
+
- `--mint-url <url>` override default mint
|
|
32
|
+
- `send bolt11 <invoice>` - Pay a Lightning invoice
|
|
33
|
+
- `--mint-url <url>` override default mint
|
|
34
|
+
|
|
35
|
+
### Mints
|
|
36
|
+
|
|
37
|
+
- `mints add <url>` - Add mint URL
|
|
38
|
+
- `mints list` - List configured mints
|
|
39
|
+
- `mints info <url>` - Fetch mint metadata
|
|
40
|
+
|
|
41
|
+
### NPC
|
|
42
|
+
|
|
43
|
+
- `npc address` - Get your NPC Lightning address
|
|
44
|
+
- `npc username <name>` - Begin username purchase flow
|
|
45
|
+
- `--confirm` confirm payment and complete purchase
|
|
46
|
+
|
|
47
|
+
### X-Cashu / NUT-24
|
|
48
|
+
|
|
49
|
+
- `x-cashu parse <request>` - Parse an encoded payment request
|
|
50
|
+
- `x-cashu handle <request>` - Settle request and return `X-Cashu: cashuB...` header value
|
|
51
|
+
|
|
52
|
+
### Daemon control
|
|
53
|
+
|
|
54
|
+
- `ping` - Check daemon connectivity
|
|
55
|
+
- `daemon` - Start daemon in foreground
|
|
56
|
+
- `stop` - Stop daemon
|
|
57
|
+
|
|
58
|
+
## Daemon HTTP endpoints
|
|
59
|
+
|
|
60
|
+
The CLI talks to the daemon over HTTP on a UNIX socket.
|
|
61
|
+
|
|
62
|
+
- Socket path env var: `COCOD_SOCKET`
|
|
63
|
+
- Default socket: `~/.cocod/cocod.sock`
|
|
64
|
+
|
|
65
|
+
### Response shape
|
|
66
|
+
|
|
67
|
+
- Success: `{ "output": <value> }`
|
|
68
|
+
- Error: `{ "error": "message" }`
|
|
69
|
+
|
|
70
|
+
### Endpoint list
|
|
71
|
+
|
|
72
|
+
- `GET /ping`
|
|
73
|
+
- `GET /status`
|
|
74
|
+
- `POST /init`
|
|
75
|
+
- `POST /unlock`
|
|
76
|
+
- `GET /balance`
|
|
77
|
+
- `POST /receive/cashu`
|
|
78
|
+
- `POST /receive/bolt11`
|
|
79
|
+
- `POST /send/cashu`
|
|
80
|
+
- `POST /send/bolt11`
|
|
81
|
+
- `POST /x-cashu/parse`
|
|
82
|
+
- `POST /x-cashu/handle`
|
|
83
|
+
- `POST /mints/add`
|
|
84
|
+
- `GET /mints/list`
|
|
85
|
+
- `POST /mints/info`
|
|
86
|
+
- `GET /history`
|
|
87
|
+
- `GET /events` (SSE stream)
|
|
88
|
+
- `GET /npc/address`
|
|
89
|
+
- `POST /npc/username`
|
|
90
|
+
- `POST /stop`
|
|
91
|
+
|
|
92
|
+
For full request/response and status details, see `docs/daemon-api.json`.
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cocod-daemon-api",
|
|
3
|
+
"version": "0.0.12",
|
|
4
|
+
"transport": {
|
|
5
|
+
"protocol": "http",
|
|
6
|
+
"unixSocketEnv": "COCOD_SOCKET",
|
|
7
|
+
"defaultUnixSocket": "~/.cocod/cocod.sock"
|
|
8
|
+
},
|
|
9
|
+
"responseContract": {
|
|
10
|
+
"success": {
|
|
11
|
+
"shape": {
|
|
12
|
+
"output": "unknown"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"error": {
|
|
16
|
+
"shape": {
|
|
17
|
+
"error": "string"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"endpoints": [
|
|
22
|
+
{
|
|
23
|
+
"path": "/ping",
|
|
24
|
+
"method": "GET",
|
|
25
|
+
"state": "any",
|
|
26
|
+
"responses": {
|
|
27
|
+
"200": "{ output: \"pong\" }"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "/status",
|
|
32
|
+
"method": "GET",
|
|
33
|
+
"state": "any",
|
|
34
|
+
"responses": {
|
|
35
|
+
"200": "{ output: \"UNINITIALIZED\" | \"LOCKED\" | \"UNLOCKED\" | \"ERROR\" }"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "/init",
|
|
40
|
+
"method": "POST",
|
|
41
|
+
"state": "UNINITIALIZED",
|
|
42
|
+
"body": {
|
|
43
|
+
"mnemonic": "string (optional)",
|
|
44
|
+
"passphrase": "string (optional)",
|
|
45
|
+
"mintUrl": "string (optional)"
|
|
46
|
+
},
|
|
47
|
+
"responses": {
|
|
48
|
+
"200": "{ output: string }",
|
|
49
|
+
"400": "{ error: \"Invalid mnemonic\" }",
|
|
50
|
+
"409": "{ error: string }",
|
|
51
|
+
"500": "{ error: string }"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"path": "/unlock",
|
|
56
|
+
"method": "POST",
|
|
57
|
+
"state": "LOCKED",
|
|
58
|
+
"body": {
|
|
59
|
+
"passphrase": "string"
|
|
60
|
+
},
|
|
61
|
+
"responses": {
|
|
62
|
+
"200": "{ output: \"Unlocked\" }",
|
|
63
|
+
"400": "{ error: string }",
|
|
64
|
+
"401": "{ error: string }",
|
|
65
|
+
"409": "{ error: string }",
|
|
66
|
+
"503": "{ error: string }"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"path": "/balance",
|
|
71
|
+
"method": "GET",
|
|
72
|
+
"state": "UNLOCKED",
|
|
73
|
+
"responses": {
|
|
74
|
+
"200": "{ output: Record<string, { sats: number }> }",
|
|
75
|
+
"403": "{ error: string }",
|
|
76
|
+
"503": "{ error: string }",
|
|
77
|
+
"500": "{ error: string }"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"path": "/receive/cashu",
|
|
82
|
+
"method": "POST",
|
|
83
|
+
"state": "UNLOCKED",
|
|
84
|
+
"body": {
|
|
85
|
+
"token": "string"
|
|
86
|
+
},
|
|
87
|
+
"responses": {
|
|
88
|
+
"200": "{ output: string }",
|
|
89
|
+
"500": "{ error: string }"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"path": "/receive/bolt11",
|
|
94
|
+
"method": "POST",
|
|
95
|
+
"state": "UNLOCKED",
|
|
96
|
+
"body": {
|
|
97
|
+
"amount": "number",
|
|
98
|
+
"mintUrl": "string (optional)"
|
|
99
|
+
},
|
|
100
|
+
"responses": {
|
|
101
|
+
"200": "{ output: string }",
|
|
102
|
+
"500": "{ error: string }"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"path": "/send/cashu",
|
|
107
|
+
"method": "POST",
|
|
108
|
+
"state": "UNLOCKED",
|
|
109
|
+
"body": {
|
|
110
|
+
"amount": "number",
|
|
111
|
+
"mintUrl": "string (optional)"
|
|
112
|
+
},
|
|
113
|
+
"responses": {
|
|
114
|
+
"200": "{ output: string }",
|
|
115
|
+
"500": "{ error: string }"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"path": "/send/bolt11",
|
|
120
|
+
"method": "POST",
|
|
121
|
+
"state": "UNLOCKED",
|
|
122
|
+
"body": {
|
|
123
|
+
"invoice": "string",
|
|
124
|
+
"mintUrl": "string (optional)"
|
|
125
|
+
},
|
|
126
|
+
"responses": {
|
|
127
|
+
"200": "{ output: string }",
|
|
128
|
+
"500": "{ error: string }"
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"path": "/x-cashu/parse",
|
|
133
|
+
"method": "POST",
|
|
134
|
+
"state": "UNLOCKED",
|
|
135
|
+
"body": {
|
|
136
|
+
"request": "string"
|
|
137
|
+
},
|
|
138
|
+
"responses": {
|
|
139
|
+
"200": "{ output: string }",
|
|
140
|
+
"400": "{ error: string }",
|
|
141
|
+
"500": "{ error: string }"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"path": "/x-cashu/handle",
|
|
146
|
+
"method": "POST",
|
|
147
|
+
"state": "UNLOCKED",
|
|
148
|
+
"body": {
|
|
149
|
+
"request": "string",
|
|
150
|
+
"mintUrl": "string (optional)"
|
|
151
|
+
},
|
|
152
|
+
"responses": {
|
|
153
|
+
"200": "{ output: string }",
|
|
154
|
+
"400": "{ error: string }",
|
|
155
|
+
"500": "{ error: string }"
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"path": "/mints/add",
|
|
160
|
+
"method": "POST",
|
|
161
|
+
"state": "UNLOCKED",
|
|
162
|
+
"body": {
|
|
163
|
+
"url": "string"
|
|
164
|
+
},
|
|
165
|
+
"responses": {
|
|
166
|
+
"200": "{ output: string }",
|
|
167
|
+
"500": "{ error: string }"
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"path": "/mints/list",
|
|
172
|
+
"method": "GET",
|
|
173
|
+
"state": "UNLOCKED",
|
|
174
|
+
"responses": {
|
|
175
|
+
"200": "{ output: string }",
|
|
176
|
+
"500": "{ error: string }"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"path": "/mints/info",
|
|
181
|
+
"method": "POST",
|
|
182
|
+
"state": "UNLOCKED",
|
|
183
|
+
"body": {
|
|
184
|
+
"url": "string"
|
|
185
|
+
},
|
|
186
|
+
"responses": {
|
|
187
|
+
"200": "{ output: unknown }",
|
|
188
|
+
"500": "{ error: string }"
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"path": "/history",
|
|
193
|
+
"method": "GET",
|
|
194
|
+
"state": "UNLOCKED",
|
|
195
|
+
"query": {
|
|
196
|
+
"offset": "number (optional, default 0)",
|
|
197
|
+
"limit": "number (optional, default 20, max 100)"
|
|
198
|
+
},
|
|
199
|
+
"responses": {
|
|
200
|
+
"200": "{ output: unknown[] }",
|
|
201
|
+
"400": "{ error: string }"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"path": "/events",
|
|
206
|
+
"method": "GET",
|
|
207
|
+
"state": "UNLOCKED",
|
|
208
|
+
"responses": {
|
|
209
|
+
"200": "text/event-stream"
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"path": "/npc/address",
|
|
214
|
+
"method": "GET",
|
|
215
|
+
"state": "UNLOCKED",
|
|
216
|
+
"responses": {
|
|
217
|
+
"200": "{ output: string }",
|
|
218
|
+
"500": "{ error: string }"
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"path": "/npc/username",
|
|
223
|
+
"method": "POST",
|
|
224
|
+
"state": "UNLOCKED",
|
|
225
|
+
"body": {
|
|
226
|
+
"username": "string",
|
|
227
|
+
"confirm": "boolean (optional)"
|
|
228
|
+
},
|
|
229
|
+
"responses": {
|
|
230
|
+
"200": "{ output: unknown }",
|
|
231
|
+
"400": "{ error: string }",
|
|
232
|
+
"402": "{ error: string }",
|
|
233
|
+
"500": "{ error: string }"
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"path": "/stop",
|
|
238
|
+
"method": "POST",
|
|
239
|
+
"state": "any",
|
|
240
|
+
"responses": {
|
|
241
|
+
"200": "{ output: \"Daemon stopping\" }"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@routstr/cocod",
|
|
3
|
+
"version": "0.0.16",
|
|
4
|
+
"module": "src/index.ts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"bin": {
|
|
8
|
+
"cocod": "./src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "bun src/index.ts",
|
|
12
|
+
"daemon": "bun src/index.ts daemon",
|
|
13
|
+
"lint": "tsc --noEmit",
|
|
14
|
+
"test": "bun test",
|
|
15
|
+
"format": "prettier --write ."
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/bun": "latest",
|
|
19
|
+
"prettier": "^3.8.1"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"typescript": "^5"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@scure/bip39": "^2.0.1",
|
|
26
|
+
"coco-cashu-core": "1.1.2-rc.50",
|
|
27
|
+
"coco-cashu-plugin-npc": "2.4.1",
|
|
28
|
+
"coco-cashu-sqlite-bun": "1.1.2-rc.50",
|
|
29
|
+
"commander": "^14.0.2",
|
|
30
|
+
"nostr-tools": "^2.22.1"
|
|
31
|
+
}
|
|
32
|
+
}
|