cocod 0.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/.github/workflows/npm-publish.yml +37 -0
- package/.prettierrc +10 -0
- package/AGENTS.md +210 -0
- package/CLAUDE.md +105 -0
- package/README.md +179 -0
- package/package.json +32 -0
- package/src/cli-shared.ts +163 -0
- package/src/cli.ts +188 -0
- package/src/daemon.ts +115 -0
- package/src/index.ts +4 -0
- package/src/routes.ts +298 -0
- package/src/utils/config.ts +16 -0
- package/src/utils/crypto.ts +68 -0
- package/src/utils/state.ts +128 -0
- package/src/utils/wallet.ts +49 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
- uses: actions/setup-node@v4
|
|
19
|
+
with:
|
|
20
|
+
node-version: 20
|
|
21
|
+
registry-url: "https://registry.npmjs.org"
|
|
22
|
+
- name: Configure git user
|
|
23
|
+
run: |
|
|
24
|
+
git config user.name "github-actions[bot]"
|
|
25
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
26
|
+
- name: Bump version
|
|
27
|
+
run: npm version patch --no-git-tag-version
|
|
28
|
+
- name: Publish to npm
|
|
29
|
+
env:
|
|
30
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
31
|
+
run: npm publish --access public
|
|
32
|
+
- name: Commit version bump
|
|
33
|
+
run: |
|
|
34
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
35
|
+
git add package.json
|
|
36
|
+
git commit -m "chore(release): v$VERSION [skip ci]"
|
|
37
|
+
git push
|
package/.prettierrc
ADDED
package/AGENTS.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This repository is a small Bun + TypeScript CLI/daemon.
|
|
4
|
+
Agents should optimize for: minimal diffs, strict types, Bun-native APIs, and predictable CLI UX.
|
|
5
|
+
|
|
6
|
+
## Ground Rules (Repo Policy)
|
|
7
|
+
|
|
8
|
+
- Runtime: Bun (not Node). Prefer Bun APIs over Node/polyfills.
|
|
9
|
+
- Module system: ESM (`"type": "module"` in `package.json`).
|
|
10
|
+
- TypeScript is the linter: `tsc --noEmit` is the primary check.
|
|
11
|
+
- No Cursor/Copilot rule files were found (`.cursor/rules/**`, `.cursorrules`, `.github/copilot-instructions.md`).
|
|
12
|
+
- Also follow `CLAUDE.md` (Bun defaults, preferred APIs, testing conventions).
|
|
13
|
+
|
|
14
|
+
## Project Shape
|
|
15
|
+
|
|
16
|
+
- `src/index.ts`: entrypoint for the `cocod` binary (shebang: `#!/usr/bin/env bun`).
|
|
17
|
+
- `src/cli.ts` + `src/cli-shared.ts`: Commander-based CLI.
|
|
18
|
+
- `src/daemon.ts`: background daemon implemented with `Bun.serve()` on a UNIX socket.
|
|
19
|
+
- `src/routes.ts`: HTTP route handlers for the daemon (endpoints like /balance, /receive, /init, etc.).
|
|
20
|
+
- `src/utils/`:
|
|
21
|
+
- `state.ts`: DaemonStateManager and wallet state logic
|
|
22
|
+
- `wallet.ts`: Wallet initialization helpers
|
|
23
|
+
- `crypto.ts`: Mnemonic encryption/decryption
|
|
24
|
+
- `config.ts`: Configuration paths, env vars, and types
|
|
25
|
+
- IPC: CLI talks to daemon via `fetch()` with Bun's `RequestInit.unix` option.
|
|
26
|
+
|
|
27
|
+
Key paths/env:
|
|
28
|
+
|
|
29
|
+
- Socket: `COCOD_SOCKET` (default `/tmp/cocod.sock`).
|
|
30
|
+
- PID file: `COCOD_PID` (default `/tmp/cocod.pid`).
|
|
31
|
+
- Wallet config: `~/.config/cocod/config.json` (generated; do not commit).
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
All commands run from repo root (`/home/egge/projects/cocod`).
|
|
36
|
+
|
|
37
|
+
### Install
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
bun install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Run the CLI (foreground)
|
|
44
|
+
|
|
45
|
+
- Entrypoint:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
bun src/index.ts --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- Via npm-style script (use `--` to pass args):
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
bun run start -- --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- Common commands:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
bun src/index.ts balance
|
|
61
|
+
bun src/index.ts ping
|
|
62
|
+
bun src/index.ts mint list
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Start the daemon
|
|
66
|
+
|
|
67
|
+
The daemon can be started explicitly, but the CLI also auto-starts it when needed.
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
bun run daemon
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Build / bundle
|
|
74
|
+
|
|
75
|
+
There is no required build step (the CLI runs directly via Bun + TypeScript).
|
|
76
|
+
|
|
77
|
+
- Optional: produce a bundled artifact:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
bun build src/index.ts --outdir dist --target bun
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Lint / typecheck
|
|
84
|
+
|
|
85
|
+
This repo currently uses TypeScript as the main lint gate.
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
bun run lint
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If you need to run tsc directly:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
bunx tsc --noEmit
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Tests
|
|
98
|
+
|
|
99
|
+
There are currently no committed test files, but Bun's test runner is the expected choice.
|
|
100
|
+
|
|
101
|
+
- Run all tests:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
bun test
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- Run a single test file:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
bun test path/to/file.test.ts
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- Run a single test by name (recommended when adding tests):
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
bun test -t "ping returns pong"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Notes:
|
|
120
|
+
|
|
121
|
+
- Prefer test files named `*.test.ts` and colocated near the code they test.
|
|
122
|
+
- Use `import { test, expect } from "bun:test";`.
|
|
123
|
+
|
|
124
|
+
## Code Style
|
|
125
|
+
|
|
126
|
+
There is no formatter config in this repo. Match existing style and avoid drive-by reformatting.
|
|
127
|
+
|
|
128
|
+
### Formatting
|
|
129
|
+
|
|
130
|
+
- Indentation: 2 spaces.
|
|
131
|
+
- Quotes: double quotes for strings.
|
|
132
|
+
- Semicolons: use them consistently (match surrounding file).
|
|
133
|
+
- Line length: keep lines reasonably short; wrap long function signatures.
|
|
134
|
+
|
|
135
|
+
### Imports
|
|
136
|
+
|
|
137
|
+
- Order:
|
|
138
|
+
1. external packages
|
|
139
|
+
2. blank line
|
|
140
|
+
3. local relative imports
|
|
141
|
+
- Prefer `import type { ... }` for type-only imports.
|
|
142
|
+
- Prefer named imports; avoid default imports unless the package is default-first.
|
|
143
|
+
- Keep relative imports extensionless (match current code). Only include `.js` when required by ESM packages.
|
|
144
|
+
|
|
145
|
+
### Types and strictness
|
|
146
|
+
|
|
147
|
+
`tsconfig.json` enables strict TypeScript plus `noUncheckedIndexedAccess`.
|
|
148
|
+
|
|
149
|
+
- Avoid `any`. Use `unknown` at boundaries and narrow.
|
|
150
|
+
- Validate untrusted inputs (CLI args, request bodies, env vars).
|
|
151
|
+
- When indexing objects, handle `undefined` explicitly (e.g., `balance[mintUrl] || 0`).
|
|
152
|
+
- Prefer explicit return types on exported functions and non-trivial helpers.
|
|
153
|
+
- Use discriminated unions / literal types for protocol-like payloads.
|
|
154
|
+
|
|
155
|
+
### Naming
|
|
156
|
+
|
|
157
|
+
- Files: kebab-case for multiword modules (e.g., `cli-shared.ts`).
|
|
158
|
+
- Types/interfaces: `PascalCase`.
|
|
159
|
+
- Functions/variables: `camelCase`.
|
|
160
|
+
- Constants: `UPPER_SNAKE_CASE` for configuration-like values.
|
|
161
|
+
- CLI commands: lowercase; nouns/verbs consistent with existing Commander usage.
|
|
162
|
+
|
|
163
|
+
### Error handling
|
|
164
|
+
|
|
165
|
+
General:
|
|
166
|
+
|
|
167
|
+
- Only `process.exit()` from true CLI entrypoints.
|
|
168
|
+
- Prefer throwing `Error` (or subclasses) from library-ish functions.
|
|
169
|
+
- In `catch`, treat the error as `unknown`; derive a safe message:
|
|
170
|
+
- `error instanceof Error ? error.message : String(error)`.
|
|
171
|
+
|
|
172
|
+
Daemon (`src/daemon.ts`):
|
|
173
|
+
|
|
174
|
+
- Return JSON with either `{ output: string }` or `{ error: string }`.
|
|
175
|
+
- Use proper HTTP status codes for failures (e.g., 400 for bad input, 404 unknown endpoint, 500 unexpected).
|
|
176
|
+
- Do not swallow errors silently; if you intentionally suppress errors (e.g., delete stale files), add a short comment.
|
|
177
|
+
|
|
178
|
+
CLI (`src/cli-shared.ts`):
|
|
179
|
+
|
|
180
|
+
- Print user-facing errors to stderr (`console.error`).
|
|
181
|
+
- Exit with code 1 for expected failures.
|
|
182
|
+
- For daemon connectivity issues, prefer actionable messages (socket path, how to start daemon).
|
|
183
|
+
|
|
184
|
+
### Bun-specific guidance (from `CLAUDE.md`)
|
|
185
|
+
|
|
186
|
+
- Use `bun <file>` / `bun run <script>` (not `node`, `ts-node`, `npm`).
|
|
187
|
+
- Use `bun test` (not jest/vitest).
|
|
188
|
+
- Use `Bun.serve()` routes/websocket support (not express).
|
|
189
|
+
- Prefer `Bun.file` for file IO; Bun loads `.env` automatically (avoid `dotenv`).
|
|
190
|
+
- Prefer Bun-native DB/network libs where applicable:
|
|
191
|
+
- `bun:sqlite` for SQLite (avoid `better-sqlite3`)
|
|
192
|
+
- `Bun.sql` for Postgres (avoid `pg`)
|
|
193
|
+
- `Bun.redis` for Redis (avoid `ioredis`)
|
|
194
|
+
- built-in `WebSocket` (avoid `ws`)
|
|
195
|
+
|
|
196
|
+
## Editing Expectations for Agents
|
|
197
|
+
|
|
198
|
+
- Keep diffs surgical; do not reformat unrelated code.
|
|
199
|
+
- Preserve CLI UX and backward compatibility of command names/flags unless explicitly requested.
|
|
200
|
+
- Avoid committing/generated artifacts (e.g., `coco.db`, sockets, pid files, `.env`).
|
|
201
|
+
- When adding new commands/routes:
|
|
202
|
+
- update Commander wiring in `src/cli.ts`
|
|
203
|
+
- add a daemon handler in `src/daemon.ts` (and ensure it returns the `{ output | error }` shape)
|
|
204
|
+
- keep the CLI/daemon contract explicit (method, path, request/response types).
|
|
205
|
+
|
|
206
|
+
## Quick Debugging Checklist
|
|
207
|
+
|
|
208
|
+
- CLI can't connect: verify `COCOD_SOCKET` matches daemon and the socket exists.
|
|
209
|
+
- Daemon won't start: check for stale `/tmp/cocod.sock` and `/tmp/cocod.pid`.
|
|
210
|
+
- Type errors: run `bun run lint` and fix strictness issues (especially `undefined` from indexing).
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Default to using Bun instead of Node.js.
|
|
2
|
+
|
|
3
|
+
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
|
|
4
|
+
- Use `bun test` instead of `jest` or `vitest`
|
|
5
|
+
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
|
|
6
|
+
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
|
|
7
|
+
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
|
|
8
|
+
- Use `bunx <package> <command>` instead of `npx <package> <command>`
|
|
9
|
+
- Bun automatically loads .env, so don't use dotenv.
|
|
10
|
+
|
|
11
|
+
## APIs
|
|
12
|
+
|
|
13
|
+
- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
|
|
14
|
+
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
|
|
15
|
+
- `Bun.redis` for Redis. Don't use `ioredis`.
|
|
16
|
+
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
|
|
17
|
+
- `WebSocket` is built-in. Don't use `ws`.
|
|
18
|
+
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
|
|
19
|
+
- Bun.$`ls` instead of execa.
|
|
20
|
+
|
|
21
|
+
## Testing
|
|
22
|
+
|
|
23
|
+
Use `bun test` to run tests.
|
|
24
|
+
|
|
25
|
+
```ts#index.test.ts
|
|
26
|
+
import { test, expect } from "bun:test";
|
|
27
|
+
|
|
28
|
+
test("hello world", () => {
|
|
29
|
+
expect(1).toBe(1);
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Frontend
|
|
34
|
+
|
|
35
|
+
Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
|
|
36
|
+
|
|
37
|
+
Server:
|
|
38
|
+
|
|
39
|
+
```ts#index.ts
|
|
40
|
+
import index from "./index.html"
|
|
41
|
+
|
|
42
|
+
Bun.serve({
|
|
43
|
+
routes: {
|
|
44
|
+
"/": index,
|
|
45
|
+
"/api/users/:id": {
|
|
46
|
+
GET: (req) => {
|
|
47
|
+
return new Response(JSON.stringify({ id: req.params.id }));
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
// optional websocket support
|
|
52
|
+
websocket: {
|
|
53
|
+
open: (ws) => {
|
|
54
|
+
ws.send("Hello, world!");
|
|
55
|
+
},
|
|
56
|
+
message: (ws, message) => {
|
|
57
|
+
ws.send(message);
|
|
58
|
+
},
|
|
59
|
+
close: (ws) => {
|
|
60
|
+
// handle close
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
development: {
|
|
64
|
+
hmr: true,
|
|
65
|
+
console: true,
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
|
|
71
|
+
|
|
72
|
+
```html#index.html
|
|
73
|
+
<html>
|
|
74
|
+
<body>
|
|
75
|
+
<h1>Hello, world!</h1>
|
|
76
|
+
<script type="module" src="./frontend.tsx"></script>
|
|
77
|
+
</body>
|
|
78
|
+
</html>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
With the following `frontend.tsx`:
|
|
82
|
+
|
|
83
|
+
```tsx#frontend.tsx
|
|
84
|
+
import React from "react";
|
|
85
|
+
import { createRoot } from "react-dom/client";
|
|
86
|
+
|
|
87
|
+
// import .css files directly and it works
|
|
88
|
+
import './index.css';
|
|
89
|
+
|
|
90
|
+
const root = createRoot(document.body);
|
|
91
|
+
|
|
92
|
+
export default function Frontend() {
|
|
93
|
+
return <h1>Hello, world!</h1>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
root.render(<Frontend />);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Then, run index.ts
|
|
100
|
+
|
|
101
|
+
```sh
|
|
102
|
+
bun --hot ./index.ts
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# cocod
|
|
2
|
+
|
|
3
|
+
A Cashu wallet CLI and daemon built with Bun and TypeScript.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`cocod` is a [Cashu](https://cashu.space/) e-cash wallet with a client-daemon architecture. It provides a command-line interface for managing Cashu tokens while a background daemon handles all wallet operations, state management, and mint communication.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- **Wallet Management**: Initialize with BIP39 mnemonics, optional passphrase encryption
|
|
12
|
+
- **Token Operations**: Receive Cashu tokens, check balances across mints
|
|
13
|
+
- **Lightning Integration**: Create BOLT11 invoices to mint new tokens
|
|
14
|
+
- **Nostr Payment Codes**: NPC addresses for receiving payments
|
|
15
|
+
- **Transaction History**: View and paginate wallet history
|
|
16
|
+
- **Real-time Updates**: SSE endpoint for live event streaming
|
|
17
|
+
- **Multi-mint Support**: Add and manage multiple Cashu mints
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Check daemon status
|
|
31
|
+
bun src/index.ts status
|
|
32
|
+
|
|
33
|
+
# Initialize wallet (generates mnemonic automatically)
|
|
34
|
+
bun src/index.ts init
|
|
35
|
+
|
|
36
|
+
# Or initialize with your own mnemonic
|
|
37
|
+
bun src/index.ts init "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
|
38
|
+
|
|
39
|
+
# Unlock encrypted wallet (if passphrase was set)
|
|
40
|
+
bun src/index.ts unlock "your-passphrase"
|
|
41
|
+
|
|
42
|
+
# Check balance
|
|
43
|
+
bun src/index.ts balance
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Available Commands
|
|
47
|
+
|
|
48
|
+
#### Wallet Operations
|
|
49
|
+
|
|
50
|
+
| Command | Description |
|
|
51
|
+
| --------------------- | --------------------------------------------------------------- |
|
|
52
|
+
| `status` | Check daemon and wallet status |
|
|
53
|
+
| `init [mnemonic]` | Initialize wallet (generates mnemonic if not provided) |
|
|
54
|
+
| `unlock <passphrase>` | Unlock encrypted wallet |
|
|
55
|
+
| `balance` | Get wallet balance across all mints |
|
|
56
|
+
| `receive <token>` | Receive a Cashu token |
|
|
57
|
+
| `history` | View wallet history (supports `--offset`, `--limit`, `--watch`) |
|
|
58
|
+
|
|
59
|
+
#### Mint Management
|
|
60
|
+
|
|
61
|
+
| Command | Description |
|
|
62
|
+
| ---------------------- | --------------------------------------- |
|
|
63
|
+
| `mint add <url>` | Add a new mint URL |
|
|
64
|
+
| `mint list` | List configured mints |
|
|
65
|
+
| `mint bolt11 <amount>` | Create Lightning invoice to mint tokens |
|
|
66
|
+
|
|
67
|
+
#### NPC (npub.cash)
|
|
68
|
+
|
|
69
|
+
| Command | Description |
|
|
70
|
+
| ------------- | -------------------------------------- |
|
|
71
|
+
| `npc address` | Get NPC address for receiving payments |
|
|
72
|
+
|
|
73
|
+
#### Daemon Control
|
|
74
|
+
|
|
75
|
+
| Command | Description |
|
|
76
|
+
| -------- | -------------------------------------- |
|
|
77
|
+
| `ping` | Test daemon connectivity |
|
|
78
|
+
| `stop` | Stop the background daemon |
|
|
79
|
+
| `daemon` | Start the background daemon explicitly |
|
|
80
|
+
|
|
81
|
+
### Examples
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Add a mint
|
|
85
|
+
bun src/index.ts mint add https://mint.example.com
|
|
86
|
+
|
|
87
|
+
# Create a Lightning invoice for 1000 sats
|
|
88
|
+
bun src/index.ts mint bolt11 1000
|
|
89
|
+
|
|
90
|
+
# Receive a Cashu token
|
|
91
|
+
bun src/index.ts receive "cashuAeyJ0b2tlbiI6W3sicHJvb2ZzIjpbeyJ..."
|
|
92
|
+
|
|
93
|
+
# View last 10 history entries
|
|
94
|
+
bun src/index.ts history --limit 10
|
|
95
|
+
|
|
96
|
+
# Watch history in real-time
|
|
97
|
+
bun src/index.ts history --watch
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Architecture
|
|
101
|
+
|
|
102
|
+
### Client-Daemon Model
|
|
103
|
+
|
|
104
|
+
- **CLI** (`src/cli.ts`): Thin client that sends HTTP requests to the daemon via Unix socket
|
|
105
|
+
- **Daemon** (`src/daemon.ts`): Background service using `Bun.serve()` that handles all wallet operations
|
|
106
|
+
|
|
107
|
+
The CLI automatically starts the daemon if it's not already running.
|
|
108
|
+
|
|
109
|
+
### IPC Communication
|
|
110
|
+
|
|
111
|
+
Communication happens over a Unix domain socket:
|
|
112
|
+
|
|
113
|
+
- Default: `~/.cocod/cocod.sock`
|
|
114
|
+
- Configurable via `COCOD_SOCKET` environment variable
|
|
115
|
+
|
|
116
|
+
## Configuration
|
|
117
|
+
|
|
118
|
+
### Environment Variables
|
|
119
|
+
|
|
120
|
+
| Variable | Default | Description |
|
|
121
|
+
| -------------- | --------------------- | ---------------- |
|
|
122
|
+
| `COCOD_SOCKET` | `~/.cocod/cocod.sock` | Unix socket path |
|
|
123
|
+
| `COCOD_PID` | `~/.cocod/cocod.pid` | PID file path |
|
|
124
|
+
|
|
125
|
+
### Files
|
|
126
|
+
|
|
127
|
+
- **Config**: `~/.cocod/config.json`
|
|
128
|
+
- **Database**: `./coco.db` (SQLite, auto-generated)
|
|
129
|
+
- **PID file**: Tracks running daemon process
|
|
130
|
+
|
|
131
|
+
## Development
|
|
132
|
+
|
|
133
|
+
### Commands
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Run CLI
|
|
137
|
+
bun src/index.ts --help
|
|
138
|
+
|
|
139
|
+
# Run with npm-style script
|
|
140
|
+
bun run start -- --help
|
|
141
|
+
|
|
142
|
+
# Start daemon explicitly
|
|
143
|
+
bun run daemon
|
|
144
|
+
|
|
145
|
+
# Type check
|
|
146
|
+
bun run lint
|
|
147
|
+
# or
|
|
148
|
+
bunx tsc --noEmit
|
|
149
|
+
|
|
150
|
+
# Build bundle
|
|
151
|
+
bun build src/index.ts --outdir dist --target bun
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Project Structure
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
src/
|
|
158
|
+
├── index.ts # CLI entrypoint (shebang: #!/usr/bin/env bun)
|
|
159
|
+
├── cli.ts # Commander-based CLI commands
|
|
160
|
+
├── cli-shared.ts # IPC utilities
|
|
161
|
+
├── daemon.ts # Bun.serve() daemon setup
|
|
162
|
+
├── routes.ts # HTTP route handlers
|
|
163
|
+
└── utils/
|
|
164
|
+
├── config.ts # Config management
|
|
165
|
+
├── state.ts # Daemon state machine
|
|
166
|
+
├── wallet.ts # Wallet initialization
|
|
167
|
+
└── crypto.ts # Mnemonic encryption
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Dependencies
|
|
171
|
+
|
|
172
|
+
- **Bun**: Runtime and built-in APIs (`Bun.serve()`, `fetch()`, `bun:sqlite`)
|
|
173
|
+
- **Cashu**: `coco-cashu-core`, `coco-cashu-sqlite3`, `coco-cashu-plugin-npc`
|
|
174
|
+
- **CLI**: `commander` for argument parsing
|
|
175
|
+
- **Crypto**: `@scure/bip39` for mnemonics, `nostr-tools` for NPC
|
|
176
|
+
|
|
177
|
+
## License
|
|
178
|
+
|
|
179
|
+
[Add your license here]
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cocod",
|
|
3
|
+
"version": "0.0.1",
|
|
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
|
+
"format": "prettier --write ."
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/bun": "latest",
|
|
18
|
+
"prettier": "^3.8.1"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"typescript": "^5"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@scure/bip39": "^2.0.1",
|
|
25
|
+
"coco-cashu-core": "^1.1.2-rc.43",
|
|
26
|
+
"coco-cashu-plugin-npc": "^2.2.4",
|
|
27
|
+
"coco-cashu-sqlite3": "^1.1.2-rc.43",
|
|
28
|
+
"commander": "^14.0.2",
|
|
29
|
+
"nostr-tools": "^2.22.1",
|
|
30
|
+
"sqlite3": "^5.1.7"
|
|
31
|
+
}
|
|
32
|
+
}
|