@1sat/cli 0.0.51 → 0.0.53
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/package.json +8 -6
- package/scripts/resubmit-bsv21-discovery.ts +33 -0
- package/src/cli.ts +14 -5
- package/src/commands/config.ts +1 -6
- package/src/commands/identity.ts +1 -8
- package/src/commands/locks.ts +1 -5
- package/src/commands/opns.ts +1 -5
- package/src/commands/ordinals.ts +1 -9
- package/src/commands/remote.ts +1 -11
- package/src/commands/serve-messagebox.ts +233 -0
- package/src/commands/serve.ts +26 -9
- package/src/commands/social.ts +1 -3
- package/src/commands/sweep.ts +1 -4
- package/src/commands/tokens.ts +248 -16
- package/src/commands/tx.ts +1 -3
- package/src/commands/wallet.ts +1 -20
- package/src/config.ts +24 -0
- package/src/help.ts +719 -101
- package/src/types/messagebox-server.d.ts +15 -0
package/src/help.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Help text and version display for the 1sat CLI.
|
|
3
|
+
*
|
|
4
|
+
* COMMANDS is the single source of truth. Both text help and `--json`
|
|
5
|
+
* agent-discovery output are rendered from it.
|
|
3
6
|
*/
|
|
4
7
|
|
|
5
8
|
import { readFileSync } from 'node:fs'
|
|
@@ -24,116 +27,731 @@ export function printVersion(): void {
|
|
|
24
27
|
console.log(`1sat ${getVersion()}`)
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
export
|
|
30
|
+
export interface ArgSpec {
|
|
31
|
+
flag: string
|
|
32
|
+
values?: string
|
|
33
|
+
description?: string
|
|
34
|
+
required?: boolean
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SubcommandSpec {
|
|
38
|
+
name: string
|
|
39
|
+
description: string
|
|
40
|
+
positional?: string
|
|
41
|
+
args?: ArgSpec[]
|
|
42
|
+
unavailable?: boolean
|
|
43
|
+
notes?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface CommandSpec {
|
|
47
|
+
group: string
|
|
48
|
+
name: string
|
|
49
|
+
description: string
|
|
50
|
+
positional?: string
|
|
51
|
+
args?: ArgSpec[]
|
|
52
|
+
subcommands?: SubcommandSpec[]
|
|
53
|
+
notes?: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const GLOBAL_OPTIONS: ArgSpec[] = [
|
|
57
|
+
{ flag: '--json', description: 'Output as JSON' },
|
|
58
|
+
{ flag: '--quiet', description: 'Suppress output (also -q)' },
|
|
59
|
+
{ flag: '--yes', description: 'Skip confirmation prompts (also -y)' },
|
|
60
|
+
{
|
|
61
|
+
flag: '--chain',
|
|
62
|
+
values: '<main|test>',
|
|
63
|
+
description: 'Network (default: main)',
|
|
64
|
+
},
|
|
65
|
+
{ flag: '--help', description: 'Show help (also -h)' },
|
|
66
|
+
{ flag: '--version', description: 'Show version (also -v)' },
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
export const ENV_VARS: { name: string; description: string }[] = [
|
|
70
|
+
{
|
|
71
|
+
name: 'PRIVATE_KEY_WIF',
|
|
72
|
+
description: 'WIF private key (bypasses encrypted keyfile)',
|
|
73
|
+
},
|
|
74
|
+
{ name: 'ONESAT_PASSWORD', description: 'Password for encrypted keyfile' },
|
|
75
|
+
{
|
|
76
|
+
name: 'ONESAT_PORT',
|
|
77
|
+
description: 'Override server port (used by `1sat serve`)',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'ONESAT_MCP_URL',
|
|
81
|
+
description:
|
|
82
|
+
'Override wallet-desktop MCP URL (default http://127.0.0.1:3322)',
|
|
83
|
+
},
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
export const COMMANDS: CommandSpec[] = [
|
|
87
|
+
// Setup
|
|
88
|
+
{
|
|
89
|
+
group: 'Setup',
|
|
90
|
+
name: 'init',
|
|
91
|
+
description:
|
|
92
|
+
'Interactive wallet setup wizard (creates encrypted keyfile and config)',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
group: 'Setup',
|
|
96
|
+
name: 'config',
|
|
97
|
+
description: 'Manage CLI configuration in ~/.1sat/cli/config.json',
|
|
98
|
+
subcommands: [
|
|
99
|
+
{ name: 'show', description: 'Display current configuration' },
|
|
100
|
+
{
|
|
101
|
+
name: 'set',
|
|
102
|
+
description: 'Set a config value',
|
|
103
|
+
positional: '<dotted.path> <value>',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'unset',
|
|
107
|
+
description: 'Remove a configuration key',
|
|
108
|
+
positional: '<dotted.path>',
|
|
109
|
+
},
|
|
110
|
+
{ name: 'path', description: 'Print config directory path' },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
group: 'Setup',
|
|
115
|
+
name: 'remote',
|
|
116
|
+
description: 'Manage remote wallet storage',
|
|
117
|
+
subcommands: [
|
|
118
|
+
{
|
|
119
|
+
name: 'add',
|
|
120
|
+
description: 'Add a remote storage as backup',
|
|
121
|
+
positional: '<url>',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'list',
|
|
125
|
+
description: 'List configured remotes and active storage',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'delete',
|
|
129
|
+
description: 'Remove a remote from the backup list',
|
|
130
|
+
positional: '<url>',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'set-active',
|
|
134
|
+
description: 'Switch active storage to a remote or back to local',
|
|
135
|
+
positional: '<url | local>',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'status',
|
|
139
|
+
description: 'Fetch GET /account/status from a remote',
|
|
140
|
+
positional: '[url]',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'topup',
|
|
144
|
+
description: 'Buy capacity on a remote',
|
|
145
|
+
positional: '[url]',
|
|
146
|
+
args: [{ flag: '--units', values: '<n>' }],
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
// Wallet
|
|
152
|
+
{
|
|
153
|
+
group: 'Wallet',
|
|
154
|
+
name: 'wallet',
|
|
155
|
+
description: 'Wallet operations (balance, send, BRC-100 interface)',
|
|
156
|
+
subcommands: [
|
|
157
|
+
{ name: 'balance', description: 'Show wallet balance in satoshis' },
|
|
158
|
+
{
|
|
159
|
+
name: 'address',
|
|
160
|
+
description: 'Show BRC-29 deposit address(es)',
|
|
161
|
+
args: [
|
|
162
|
+
{
|
|
163
|
+
flag: '--prefix',
|
|
164
|
+
values: '<p>',
|
|
165
|
+
description: 'BRC-29 prefix (default: 1sat)',
|
|
166
|
+
},
|
|
167
|
+
{ flag: '--start-index', values: '<n>' },
|
|
168
|
+
{ flag: '--count', values: '<n>' },
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'send',
|
|
173
|
+
description:
|
|
174
|
+
'Send BSV. Specify exactly one of --to, --script, or --data-asm',
|
|
175
|
+
args: [
|
|
176
|
+
{ flag: '--to', values: '<address>' },
|
|
177
|
+
{ flag: '--script', values: '<hex>' },
|
|
178
|
+
{ flag: '--data-asm', values: '"<asm>"' },
|
|
179
|
+
{
|
|
180
|
+
flag: '--sats',
|
|
181
|
+
values: '<n>',
|
|
182
|
+
description: 'Required with --to or --script',
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'send-all',
|
|
188
|
+
description: 'Send all BSV to an address (empties the wallet)',
|
|
189
|
+
args: [{ flag: '--to', values: '<address>', required: true }],
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'sync',
|
|
193
|
+
description: 'Sync inbound payments at BRC-29 deposit addresses',
|
|
194
|
+
args: [
|
|
195
|
+
{ flag: '--prefix', values: '<p>' },
|
|
196
|
+
{ flag: '--start-index', values: '<n>' },
|
|
197
|
+
{ flag: '--count', values: '<n>' },
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'info',
|
|
202
|
+
description: 'Show address, identity key, balance, and network',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'list-outputs',
|
|
206
|
+
description: 'List wallet outputs in a basket (BRC-100)',
|
|
207
|
+
args: [
|
|
208
|
+
{ flag: '--basket', values: '<name>', required: true },
|
|
209
|
+
{ flag: '--tags', values: '<t1,t2>' },
|
|
210
|
+
{ flag: '--limit', values: '<n>' },
|
|
211
|
+
{ flag: '--include-tags' },
|
|
212
|
+
{ flag: '--include', values: '<val>' },
|
|
213
|
+
],
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: 'relinquish-output',
|
|
217
|
+
description: 'Remove output from basket (BRC-100)',
|
|
218
|
+
args: [
|
|
219
|
+
{ flag: '--basket', values: '<name>', required: true },
|
|
220
|
+
{ flag: '--output', values: '<txid.vout>', required: true },
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: 'list-actions',
|
|
225
|
+
description: 'List wallet actions (BRC-100)',
|
|
226
|
+
args: [
|
|
227
|
+
{ flag: '--labels', values: '<l1,l2>' },
|
|
228
|
+
{ flag: '--limit', values: '<n>' },
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
name: 'create-action',
|
|
233
|
+
description: 'Create a raw action (BRC-100)',
|
|
234
|
+
positional: "'<json>'",
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: 'sign-action',
|
|
238
|
+
description: 'Sign a raw action (BRC-100)',
|
|
239
|
+
positional: "'<json>'",
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: 'abort-action',
|
|
243
|
+
description: 'Abort a pending action (BRC-100)',
|
|
244
|
+
args: [{ flag: '--reference', values: '<ref>', required: true }],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: 'list-certificates',
|
|
248
|
+
description: 'List certificates (BRC-100)',
|
|
249
|
+
args: [
|
|
250
|
+
{ flag: '--certifiers', values: '<c1,c2>' },
|
|
251
|
+
{ flag: '--types', values: '<t1,t2>' },
|
|
252
|
+
{ flag: '--limit', values: '<n>' },
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: 'relinquish-certificate',
|
|
257
|
+
description: 'Relinquish a certificate (BRC-100)',
|
|
258
|
+
args: [
|
|
259
|
+
{ flag: '--type', values: '<t>', required: true },
|
|
260
|
+
{ flag: '--serialNumber', values: '<s>', required: true },
|
|
261
|
+
{ flag: '--certifier', values: '<c>', required: true },
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
// Ordinals
|
|
268
|
+
{
|
|
269
|
+
group: 'Ordinals',
|
|
270
|
+
name: 'ordinals',
|
|
271
|
+
description: '1Sat Ordinal inscriptions',
|
|
272
|
+
subcommands: [
|
|
273
|
+
{ name: 'list', description: 'List owned ordinals/inscriptions' },
|
|
274
|
+
{
|
|
275
|
+
name: 'mint',
|
|
276
|
+
description: 'Mint a new ordinal inscription',
|
|
277
|
+
args: [
|
|
278
|
+
{ flag: '--file', values: '<path>', required: true },
|
|
279
|
+
{
|
|
280
|
+
flag: '--type',
|
|
281
|
+
values: '<mime>',
|
|
282
|
+
description: 'Override auto-detected MIME type',
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
flag: '--map',
|
|
286
|
+
values: '<json>',
|
|
287
|
+
description: 'MAP metadata as JSON object',
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
flag: '--sign-with-bap',
|
|
291
|
+
description: 'Sign inscription with BAP identity',
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: 'transfer',
|
|
297
|
+
description: 'Transfer an ordinal',
|
|
298
|
+
args: [
|
|
299
|
+
{ flag: '--outpoint', values: '<txid.vout>', required: true },
|
|
300
|
+
{ flag: '--to', values: '<address>', required: true },
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: 'sell',
|
|
305
|
+
description: 'List an ordinal for sale (OrdLock)',
|
|
306
|
+
args: [
|
|
307
|
+
{ flag: '--outpoint', values: '<txid.vout>', required: true },
|
|
308
|
+
{ flag: '--price', values: '<sats>', required: true },
|
|
309
|
+
],
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: 'cancel',
|
|
313
|
+
description: 'Cancel an ordinal listing',
|
|
314
|
+
args: [{ flag: '--outpoint', values: '<txid.vout>', required: true }],
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: 'buy',
|
|
318
|
+
description: 'Purchase a listed ordinal',
|
|
319
|
+
args: [{ flag: '--outpoint', values: '<txid.vout>', required: true }],
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: 'burn',
|
|
323
|
+
description: 'Burn ordinals permanently',
|
|
324
|
+
args: [
|
|
325
|
+
{ flag: '--outpoints', values: '<op1,op2,...>', required: true },
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
// Tokens
|
|
332
|
+
{
|
|
333
|
+
group: 'Tokens (BSV21)',
|
|
334
|
+
name: 'tokens',
|
|
335
|
+
description: 'BSV21 fungible tokens',
|
|
336
|
+
subcommands: [
|
|
337
|
+
{ name: 'balances', description: 'Show token balances by token ID' },
|
|
338
|
+
{
|
|
339
|
+
name: 'list',
|
|
340
|
+
description: 'List owned token UTXOs',
|
|
341
|
+
args: [{ flag: '--token-id', values: '<id>' }],
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: 'send',
|
|
345
|
+
description: 'Transfer tokens',
|
|
346
|
+
args: [
|
|
347
|
+
{ flag: '--token-id', values: '<id>', required: true },
|
|
348
|
+
{ flag: '--amount', values: '<n>', required: true },
|
|
349
|
+
{ flag: '--to', values: '<address>' },
|
|
350
|
+
{ flag: '--counterparty', values: '<pubkey-hex>' },
|
|
351
|
+
{ flag: '--locking-script', values: '<hex>' },
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'deploy-mint',
|
|
356
|
+
description: 'Deploy a new BSV21 token with fixed supply (deploy+mint)',
|
|
357
|
+
args: [
|
|
358
|
+
{ flag: '--symbol', values: '<ticker>', required: true },
|
|
359
|
+
{ flag: '--amount', values: '<total-supply>', required: true },
|
|
360
|
+
{ flag: '--decimals', values: '<0-18>' },
|
|
361
|
+
{ flag: '--icon', values: '<url-or-data-uri>' },
|
|
362
|
+
{ flag: '--to', values: '<address>' },
|
|
363
|
+
{ flag: '--counterparty', values: '<pubkey-hex>' },
|
|
364
|
+
{ flag: '--locking-script', values: '<hex>' },
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'deploy-auth',
|
|
369
|
+
description:
|
|
370
|
+
'Deploy a new BSV21 token with mintable supply via auth UTXOs (deploy+auth)',
|
|
371
|
+
args: [
|
|
372
|
+
{ flag: '--symbol', values: '<ticker>', required: true },
|
|
373
|
+
{ flag: '--decimals', values: '<0-18>' },
|
|
374
|
+
{ flag: '--icon', values: '<url-or-data-uri>' },
|
|
375
|
+
{ flag: '--to', values: '<address>' },
|
|
376
|
+
{ flag: '--counterparty', values: '<pubkey-hex>' },
|
|
377
|
+
{ flag: '--locking-script', values: '<hex>' },
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: 'mint',
|
|
382
|
+
description:
|
|
383
|
+
'Spend an auth UTXO to mint new supply, re-issue authority, or burn it',
|
|
384
|
+
args: [
|
|
385
|
+
{ flag: '--token-id', values: '<id>', required: true },
|
|
386
|
+
{ flag: '--amount', values: '<n>' },
|
|
387
|
+
{ flag: '--to', values: '<address>' },
|
|
388
|
+
{ flag: '--counterparty', values: '<pubkey-hex>' },
|
|
389
|
+
{ flag: '--locking-script', values: '<hex>' },
|
|
390
|
+
{ flag: '--auth-to', values: '<address>' },
|
|
391
|
+
{ flag: '--auth-counterparty', values: '<pubkey-hex>' },
|
|
392
|
+
{ flag: '--auth-locking-script', values: '<hex>' },
|
|
393
|
+
{ flag: '--end-minting' },
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: 'buy',
|
|
398
|
+
description: 'Purchase listed tokens',
|
|
399
|
+
args: [
|
|
400
|
+
{ flag: '--outpoint', values: '<txid.vout>', required: true },
|
|
401
|
+
{ flag: '--token-id', values: '<id>', required: true },
|
|
402
|
+
{ flag: '--amount', values: '<n>', required: true },
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
},
|
|
407
|
+
|
|
408
|
+
// Locks
|
|
409
|
+
{
|
|
410
|
+
group: 'Locks',
|
|
411
|
+
name: 'locks',
|
|
412
|
+
description: 'Time-locked BSV',
|
|
413
|
+
subcommands: [
|
|
414
|
+
{ name: 'info', description: 'Show locked totals and maturity status' },
|
|
415
|
+
{
|
|
416
|
+
name: 'lock',
|
|
417
|
+
description: 'Time-lock BSV until a block height',
|
|
418
|
+
args: [
|
|
419
|
+
{ flag: '--sats', values: '<amount>', required: true },
|
|
420
|
+
{
|
|
421
|
+
flag: '--blocks',
|
|
422
|
+
values: '<n>',
|
|
423
|
+
required: true,
|
|
424
|
+
description: 'Target unlock block height',
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
},
|
|
428
|
+
{ name: 'unlock', description: 'Unlock all matured locks' },
|
|
429
|
+
],
|
|
430
|
+
},
|
|
431
|
+
|
|
432
|
+
// Identity
|
|
433
|
+
{
|
|
434
|
+
group: 'Identity (BAP)',
|
|
435
|
+
name: 'identity',
|
|
436
|
+
description: 'BAP (Bitcoin Attestation Protocol) identity management',
|
|
437
|
+
subcommands: [
|
|
438
|
+
{ name: 'create', description: 'Create/publish a BAP identity on-chain' },
|
|
439
|
+
{
|
|
440
|
+
name: 'update-profile',
|
|
441
|
+
description: 'Update BAP identity profile',
|
|
442
|
+
args: [{ flag: '--profile', values: '<json>', required: true }],
|
|
443
|
+
},
|
|
444
|
+
{ name: 'info', description: 'Show identity public key' },
|
|
445
|
+
{
|
|
446
|
+
name: 'sign',
|
|
447
|
+
description: 'Sign a message with identity key (BSM)',
|
|
448
|
+
args: [
|
|
449
|
+
{ flag: '--message', values: '<text>', required: true },
|
|
450
|
+
{ flag: '--encoding', values: '<utf8|hex|base64>' },
|
|
451
|
+
],
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: 'verify',
|
|
455
|
+
description: 'Verify a signed message',
|
|
456
|
+
unavailable: true,
|
|
457
|
+
notes: 'Not yet implemented.',
|
|
458
|
+
args: [
|
|
459
|
+
{ flag: '--message', values: '<text>', required: true },
|
|
460
|
+
{ flag: '--sig', values: '<sig>', required: true },
|
|
461
|
+
{ flag: '--address', values: '<addr>', required: true },
|
|
462
|
+
],
|
|
463
|
+
},
|
|
464
|
+
],
|
|
465
|
+
},
|
|
466
|
+
|
|
467
|
+
// Social
|
|
468
|
+
{
|
|
469
|
+
group: 'Social',
|
|
470
|
+
name: 'social',
|
|
471
|
+
description: 'On-chain social posts (BSocial)',
|
|
472
|
+
subcommands: [
|
|
473
|
+
{
|
|
474
|
+
name: 'post',
|
|
475
|
+
description: 'Create an on-chain social post',
|
|
476
|
+
args: [
|
|
477
|
+
{ flag: '--content', values: '<text>', required: true },
|
|
478
|
+
{ flag: '--app', values: '<name>' },
|
|
479
|
+
{
|
|
480
|
+
flag: '--content-type',
|
|
481
|
+
values: '<text/plain|text/markdown>',
|
|
482
|
+
},
|
|
483
|
+
{ flag: '--tags', values: '<t1,t2>' },
|
|
484
|
+
],
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
},
|
|
488
|
+
|
|
489
|
+
// OpNS
|
|
490
|
+
{
|
|
491
|
+
group: 'OpNS',
|
|
492
|
+
name: 'opns',
|
|
493
|
+
description: 'Ordinals Name System — bind BAP identity to a name',
|
|
494
|
+
subcommands: [
|
|
495
|
+
{
|
|
496
|
+
name: 'register',
|
|
497
|
+
description: 'Register identity on an OpNS name',
|
|
498
|
+
args: [{ flag: '--outpoint', values: '<txid.vout>', required: true }],
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
name: 'deregister',
|
|
502
|
+
description: 'Deregister identity from an OpNS name',
|
|
503
|
+
args: [{ flag: '--outpoint', values: '<txid.vout>', required: true }],
|
|
504
|
+
},
|
|
505
|
+
{ name: 'lookup', description: 'List OpNS names from wallet' },
|
|
506
|
+
],
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
// Sweep
|
|
510
|
+
{
|
|
511
|
+
group: 'Sweep',
|
|
512
|
+
name: 'sweep',
|
|
513
|
+
description: 'Import assets from external private keys',
|
|
514
|
+
subcommands: [
|
|
515
|
+
{
|
|
516
|
+
name: 'scan',
|
|
517
|
+
description:
|
|
518
|
+
'Scan an address for sweepable UTXOs (BSV, ordinals, BSV21)',
|
|
519
|
+
args: [{ flag: '--wif', values: '<key>', required: true }],
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
name: 'import',
|
|
523
|
+
description: 'Sweep UTXOs from a WIF into the wallet',
|
|
524
|
+
args: [{ flag: '--wif', values: '<key>', required: true }],
|
|
525
|
+
},
|
|
526
|
+
],
|
|
527
|
+
},
|
|
528
|
+
|
|
529
|
+
// Server
|
|
530
|
+
{
|
|
531
|
+
group: 'Server',
|
|
532
|
+
name: 'serve',
|
|
533
|
+
description:
|
|
534
|
+
'Run wallet HTTP server and/or monitor daemon (config under server.* in config.json)',
|
|
535
|
+
subcommands: [
|
|
536
|
+
{
|
|
537
|
+
name: '(no subcommand)',
|
|
538
|
+
description: 'Wallet server + monitor daemon',
|
|
539
|
+
},
|
|
540
|
+
{ name: 'wallet', description: 'Wallet server only (BRC-100 HTTP)' },
|
|
541
|
+
{ name: 'monitor', description: 'Monitor daemon only' },
|
|
542
|
+
{
|
|
543
|
+
name: 'messagebox',
|
|
544
|
+
description:
|
|
545
|
+
'BSV message-box server (port 8771 default; uses wallet identity)',
|
|
546
|
+
},
|
|
547
|
+
],
|
|
548
|
+
},
|
|
549
|
+
|
|
550
|
+
// MCP
|
|
551
|
+
{
|
|
552
|
+
group: 'MCP',
|
|
553
|
+
name: 'mcp-proxy',
|
|
554
|
+
description:
|
|
555
|
+
'stdio JSON-RPC bridge to a running wallet-desktop MCP server (default http://127.0.0.1:3322). Performs BRC-31 handshake using ~/.1sat-wallet/mcp-agent.key.',
|
|
556
|
+
},
|
|
557
|
+
|
|
558
|
+
// Advanced
|
|
559
|
+
{
|
|
560
|
+
group: 'Advanced',
|
|
561
|
+
name: 'action',
|
|
562
|
+
description:
|
|
563
|
+
'Execute any registered @1sat/actions action by name. Run with no args to list all actions.',
|
|
564
|
+
positional: "[<name> ['<json>']]",
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
group: 'Advanced',
|
|
568
|
+
name: 'tx',
|
|
569
|
+
description: 'Transaction utilities',
|
|
570
|
+
subcommands: [
|
|
571
|
+
{
|
|
572
|
+
name: 'decode',
|
|
573
|
+
description: 'Decode a raw transaction hex',
|
|
574
|
+
positional: '<hex>',
|
|
575
|
+
},
|
|
576
|
+
],
|
|
577
|
+
},
|
|
578
|
+
|
|
579
|
+
// Help
|
|
580
|
+
{
|
|
581
|
+
group: 'Help',
|
|
582
|
+
name: 'help',
|
|
583
|
+
description:
|
|
584
|
+
'Show this help. Use --json for machine-readable output. Use `1sat <command> help` for per-command help.',
|
|
585
|
+
},
|
|
586
|
+
]
|
|
587
|
+
|
|
588
|
+
export function getCommand(name: string): CommandSpec | undefined {
|
|
589
|
+
return COMMANDS.find((c) => c.name === name)
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function formatArgUsage(arg: ArgSpec): string {
|
|
593
|
+
const core = arg.values ? `${arg.flag} ${arg.values}` : arg.flag
|
|
594
|
+
return arg.required ? core : `[${core}]`
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function formatSubcommandLine(sub: SubcommandSpec): string {
|
|
598
|
+
const parts: string[] = []
|
|
599
|
+
if (sub.positional) parts.push(sub.positional)
|
|
600
|
+
if (sub.args) parts.push(...sub.args.map(formatArgUsage))
|
|
601
|
+
return parts.join(' ')
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
export function printHelp(json = false): void {
|
|
605
|
+
if (json) {
|
|
606
|
+
printHelpJson()
|
|
607
|
+
return
|
|
608
|
+
}
|
|
609
|
+
printHelpText()
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function printHelpJson(): void {
|
|
613
|
+
const tree = COMMANDS.map((cmd) => ({
|
|
614
|
+
group: cmd.group,
|
|
615
|
+
name: cmd.name,
|
|
616
|
+
description: cmd.description,
|
|
617
|
+
...(cmd.positional ? { positional: cmd.positional } : {}),
|
|
618
|
+
...(cmd.args ? { args: cmd.args } : {}),
|
|
619
|
+
...(cmd.notes ? { notes: cmd.notes } : {}),
|
|
620
|
+
...(cmd.subcommands
|
|
621
|
+
? {
|
|
622
|
+
subcommands: cmd.subcommands.map((s) => ({
|
|
623
|
+
name: s.name,
|
|
624
|
+
description: s.description,
|
|
625
|
+
...(s.positional ? { positional: s.positional } : {}),
|
|
626
|
+
...(s.args ? { args: s.args } : {}),
|
|
627
|
+
...(s.unavailable ? { unavailable: true } : {}),
|
|
628
|
+
...(s.notes ? { notes: s.notes } : {}),
|
|
629
|
+
})),
|
|
630
|
+
}
|
|
631
|
+
: {}),
|
|
632
|
+
}))
|
|
633
|
+
|
|
634
|
+
console.log(
|
|
635
|
+
JSON.stringify(
|
|
636
|
+
{
|
|
637
|
+
name: '1sat',
|
|
638
|
+
version: getVersion(),
|
|
639
|
+
description: 'CLI for 1Sat Ordinals SDK',
|
|
640
|
+
usage: '1sat <command> [subcommand] [options]',
|
|
641
|
+
configDir: '~/.1sat/cli/',
|
|
642
|
+
globalOptions: GLOBAL_OPTIONS,
|
|
643
|
+
envVars: ENV_VARS,
|
|
644
|
+
commands: tree,
|
|
645
|
+
},
|
|
646
|
+
null,
|
|
647
|
+
2,
|
|
648
|
+
),
|
|
649
|
+
)
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function printHelpText(): void {
|
|
28
653
|
const dim = chalk.dim
|
|
29
654
|
const cyan = chalk.cyan
|
|
30
655
|
const bold = chalk.bold
|
|
31
656
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
${cyan(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
${
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
${
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
${bold('Identity (BAP):')}
|
|
87
|
-
${cyan('identity create')} Create a new BAP identity
|
|
88
|
-
${cyan('identity update-profile')} Update BAP identity profile (--profile <json>)
|
|
89
|
-
${cyan('identity info')} Show identity information
|
|
90
|
-
${cyan('identity sign')} Sign a message with identity key
|
|
91
|
-
${cyan('identity verify')} Verify a signed message
|
|
92
|
-
|
|
93
|
-
${bold('Social:')}
|
|
94
|
-
${cyan('social post')} Create an on-chain social post
|
|
95
|
-
|
|
96
|
-
${bold('OpNS:')}
|
|
97
|
-
${cyan('opns register')} Register identity on OpNS name
|
|
98
|
-
${cyan('opns deregister')} Deregister identity from OpNS name
|
|
99
|
-
${cyan('opns lookup')} Look up an OpNS name
|
|
100
|
-
|
|
101
|
-
${bold('Sweep:')}
|
|
102
|
-
${cyan('sweep scan')} Scan an address for UTXOs
|
|
103
|
-
${cyan('sweep import')} Import UTXOs into wallet
|
|
104
|
-
|
|
105
|
-
${bold('Advanced:')}
|
|
106
|
-
${cyan('action')} <name> [json] Execute a registered action by name
|
|
107
|
-
${cyan('tx decode')} <hex> Decode a raw transaction
|
|
108
|
-
|
|
109
|
-
${bold('Global Options:')}
|
|
110
|
-
${dim('--json')} Output as JSON
|
|
111
|
-
${dim('--quiet, -q')} Suppress output
|
|
112
|
-
${dim('--yes, -y')} Skip confirmations
|
|
113
|
-
${dim('--chain <main|test>')} Network (default: main)
|
|
114
|
-
${dim('--help, -h')} Show help
|
|
115
|
-
${dim('--version, -v')} Show version
|
|
116
|
-
|
|
117
|
-
${bold('Environment Variables:')}
|
|
118
|
-
${dim('PRIVATE_KEY_WIF')} Private key (bypasses encrypted keyfile)
|
|
119
|
-
${dim('ONESAT_PASSWORD')} Password for encrypted keyfile
|
|
120
|
-
|
|
121
|
-
${bold('Config:')} ~/.1sat/cli/
|
|
122
|
-
`)
|
|
657
|
+
const lines: string[] = []
|
|
658
|
+
lines.push('')
|
|
659
|
+
lines.push(`${bold('1sat')} - CLI for 1Sat Ordinals SDK`)
|
|
660
|
+
lines.push('')
|
|
661
|
+
lines.push(bold('Usage:'))
|
|
662
|
+
lines.push(' 1sat <command> [subcommand] [options]')
|
|
663
|
+
lines.push(' 1sat <command> help Per-command help')
|
|
664
|
+
lines.push(' 1sat help --json Machine-readable command tree')
|
|
665
|
+
lines.push('')
|
|
666
|
+
|
|
667
|
+
let currentGroup = ''
|
|
668
|
+
for (const cmd of COMMANDS) {
|
|
669
|
+
if (cmd.group !== currentGroup) {
|
|
670
|
+
lines.push(bold(`${cmd.group}:`))
|
|
671
|
+
currentGroup = cmd.group
|
|
672
|
+
}
|
|
673
|
+
const head = cmd.subcommands
|
|
674
|
+
? `${cmd.name} <subcommand>`
|
|
675
|
+
: cmd.positional
|
|
676
|
+
? `${cmd.name} ${cmd.positional}`
|
|
677
|
+
: cmd.name
|
|
678
|
+
lines.push(` ${cyan(head.padEnd(28))} ${dim(cmd.description)}`)
|
|
679
|
+
|
|
680
|
+
if (cmd.subcommands) {
|
|
681
|
+
for (const sub of cmd.subcommands) {
|
|
682
|
+
const usage = formatSubcommandLine(sub)
|
|
683
|
+
const label = `${cmd.name} ${sub.name}${usage ? ` ${usage}` : ''}`
|
|
684
|
+
const tag = sub.unavailable ? ' (unavailable)' : ''
|
|
685
|
+
lines.push(
|
|
686
|
+
` ${cyan(label.padEnd(58))} ${dim(sub.description + tag)}`,
|
|
687
|
+
)
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
lines.push('')
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
lines.push(bold('Global Options:'))
|
|
694
|
+
for (const opt of GLOBAL_OPTIONS) {
|
|
695
|
+
const usage = opt.values ? `${opt.flag} ${opt.values}` : opt.flag
|
|
696
|
+
lines.push(` ${dim(usage.padEnd(26))} ${dim(opt.description ?? '')}`)
|
|
697
|
+
}
|
|
698
|
+
lines.push('')
|
|
699
|
+
|
|
700
|
+
lines.push(bold('Environment Variables:'))
|
|
701
|
+
for (const env of ENV_VARS) {
|
|
702
|
+
lines.push(` ${dim(env.name.padEnd(26))} ${dim(env.description)}`)
|
|
703
|
+
}
|
|
704
|
+
lines.push('')
|
|
705
|
+
|
|
706
|
+
lines.push(`${bold('Config:')} ~/.1sat/cli/`)
|
|
707
|
+
lines.push('')
|
|
708
|
+
|
|
709
|
+
console.log(lines.join('\n'))
|
|
123
710
|
}
|
|
124
711
|
|
|
125
|
-
export function printCommandHelp(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
)
|
|
712
|
+
export function printCommandHelp(commandName: string, json = false): void {
|
|
713
|
+
const spec = getCommand(commandName)
|
|
714
|
+
if (!spec) {
|
|
715
|
+
if (json) {
|
|
716
|
+
console.log(JSON.stringify({ error: `Unknown command: ${commandName}` }))
|
|
717
|
+
} else {
|
|
718
|
+
console.error(`Unknown command: ${commandName}`)
|
|
719
|
+
}
|
|
720
|
+
return
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (json) {
|
|
724
|
+
console.log(JSON.stringify(spec, null, 2))
|
|
725
|
+
return
|
|
726
|
+
}
|
|
727
|
+
|
|
129
728
|
const bold = chalk.bold
|
|
130
729
|
const cyan = chalk.cyan
|
|
131
730
|
const dim = chalk.dim
|
|
132
731
|
|
|
133
|
-
console.log(`\n${bold(`1sat ${command}`)}`)
|
|
134
|
-
console.log(`\n${bold('Subcommands:')}`)
|
|
135
|
-
for (const [sub, desc] of Object.entries(subcommands)) {
|
|
136
|
-
console.log(` ${cyan(sub.padEnd(20))} ${dim(desc)}`)
|
|
137
|
-
}
|
|
138
732
|
console.log()
|
|
733
|
+
console.log(`${bold(`1sat ${spec.name}`)} - ${spec.description}`)
|
|
734
|
+
if (spec.notes) console.log(dim(` ${spec.notes}`))
|
|
735
|
+
console.log()
|
|
736
|
+
|
|
737
|
+
if (spec.subcommands) {
|
|
738
|
+
console.log(bold('Subcommands:'))
|
|
739
|
+
for (const sub of spec.subcommands) {
|
|
740
|
+
const usage = formatSubcommandLine(sub)
|
|
741
|
+
const label = `${sub.name}${usage ? ` ${usage}` : ''}`
|
|
742
|
+
const tag = sub.unavailable ? ' (unavailable)' : ''
|
|
743
|
+
console.log(` ${cyan(label.padEnd(56))} ${dim(sub.description + tag)}`)
|
|
744
|
+
if (sub.notes) console.log(dim(` ${sub.notes}`))
|
|
745
|
+
}
|
|
746
|
+
console.log()
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (spec.args && spec.args.length > 0) {
|
|
750
|
+
console.log(bold('Options:'))
|
|
751
|
+
for (const arg of spec.args) {
|
|
752
|
+
const usage = formatArgUsage(arg)
|
|
753
|
+
console.log(` ${cyan(usage.padEnd(36))} ${dim(arg.description ?? '')}`)
|
|
754
|
+
}
|
|
755
|
+
console.log()
|
|
756
|
+
}
|
|
139
757
|
}
|