@btc-vision/cli 1.0.12 → 1.1.0

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 CHANGED
@@ -3,15 +3,60 @@
3
3
  ![Bitcoin](https://img.shields.io/badge/Bitcoin-000?style=for-the-badge&logo=bitcoin&logoColor=white)
4
4
  ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
5
5
  ![NodeJS](https://img.shields.io/badge/Node%20js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)
6
- ![MongoDB](https://img.shields.io/badge/MongoDB-%234ea94b.svg?style=for-the-badge&logo=mongodb&logoColor=white)
7
6
  ![NPM](https://img.shields.io/badge/npm-CB3837?style=for-the-badge&logo=npm&logoColor=white)
8
- ![Gulp](https://img.shields.io/badge/GULP-%23CF4647.svg?style=for-the-badge&logo=gulp&logoColor=white)
9
- ![ESLint](https://img.shields.io/badge/ESLint-4B3263?style=for-the-badge&logo=eslint&logoColor=white)
10
7
 
11
8
  [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)
12
9
 
13
10
  Official command-line interface for the OPNet plugin ecosystem. Build, sign, verify, and publish plugins with
14
- quantum-resistant MLDSA signatures.
11
+ quantum-resistant MLDSA signatures. Register `.btc` domains and deploy decentralized websites on Bitcoin L1.
12
+
13
+ ## Table of Contents
14
+
15
+ - [Installation](#installation)
16
+ - [Quick Start](#quick-start)
17
+ - [Commands](#commands)
18
+ - [Configuration](#configuration)
19
+ - [`opnet config`](#opnet-config)
20
+ - [Authentication](#authentication)
21
+ - [`opnet login`](#opnet-login)
22
+ - [`opnet logout`](#opnet-logout)
23
+ - [`opnet whoami`](#opnet-whoami)
24
+ - [Key Generation](#key-generation)
25
+ - [`opnet keygen`](#opnet-keygen)
26
+ - [Plugin Development](#plugin-development)
27
+ - [`opnet init`](#opnet-init)
28
+ - [`opnet compile`](#opnet-compile)
29
+ - [`opnet verify`](#opnet-verify)
30
+ - [`opnet info`](#opnet-info)
31
+ - [`opnet sign`](#opnet-sign)
32
+ - [Registry - Publishing](#registry---publishing)
33
+ - [`opnet publish`](#opnet-publish)
34
+ - [`opnet deprecate`](#opnet-deprecate)
35
+ - [`opnet undeprecate`](#opnet-undeprecate)
36
+ - [Registry - Package Management](#registry---package-management)
37
+ - [`opnet install`](#opnet-install)
38
+ - [`opnet update`](#opnet-update)
39
+ - [`opnet list`](#opnet-list)
40
+ - [`opnet search`](#opnet-search)
41
+ - [Registry - Ownership](#registry---ownership)
42
+ - [`opnet scope:register`](#opnet-scoperegister)
43
+ - [`opnet transfer`](#opnet-transfer)
44
+ - [`opnet accept`](#opnet-accept)
45
+ - [Domains & Websites](#domains--websites)
46
+ - [`opnet domain register`](#opnet-domain-register)
47
+ - [`opnet domain info`](#opnet-domain-info)
48
+ - [`opnet website`](#opnet-website)
49
+ - [`opnet deploy`](#opnet-deploy)
50
+ - [Configuration Reference](#configuration-reference)
51
+ - [Environment Variables](#environment-variables)
52
+ - [Credential Storage](#credential-storage)
53
+ - [MLDSA Security Levels](#mldsa-security-levels)
54
+ - [.opnet Binary Format (OIP-0003)](#opnet-binary-format-oip-0003)
55
+ - [Plugin Manifest (plugin.json)](#plugin-manifest-pluginjson)
56
+ - [Workflow Examples](#workflow-examples)
57
+ - [Security](#security)
58
+ - [License](#license)
59
+ - [Links](#links)
15
60
 
16
61
  ## Installation
17
62
 
@@ -19,31 +64,36 @@ quantum-resistant MLDSA signatures.
19
64
  npm install -g @btc-vision/cli
20
65
  ```
21
66
 
22
- Or use npx:
67
+ Or use npx without installing:
23
68
 
24
69
  ```bash
25
70
  npx @btc-vision/cli <command>
26
71
  ```
27
72
 
73
+ **Requirements:** Node.js >= 20.0.0
74
+
28
75
  ## Quick Start
29
76
 
30
77
  ```bash
31
- # Initialize a new plugin project
78
+ # 1. Generate a new wallet mnemonic
79
+ opnet keygen mnemonic
80
+
81
+ # 2. Configure your wallet
82
+ opnet login
83
+
84
+ # 3. Initialize a new plugin project
32
85
  opnet init my-plugin
33
86
 
34
- # Build and compile to .opnet binary
87
+ # 4. Build and compile
35
88
  cd my-plugin
36
89
  npm install
37
90
  npm run build
38
91
  opnet compile
39
92
 
40
- # Verify the compiled binary
93
+ # 5. Verify the compiled binary
41
94
  opnet verify build/my-plugin.opnet
42
95
 
43
- # Configure your wallet for signing
44
- opnet login
45
-
46
- # Publish to the registry
96
+ # 6. Publish to the registry
47
97
  opnet publish
48
98
  ```
49
99
 
@@ -53,275 +103,601 @@ opnet publish
53
103
 
54
104
  #### `opnet config`
55
105
 
56
- Manage CLI configuration.
106
+ Manage CLI configuration stored in `~/.opnet/config.json`.
107
+
108
+ | Subcommand | Description |
109
+ |---|---|
110
+ | `config get [key]` | Get a configuration value (or all config if no key) |
111
+ | `config set <key> <value>` | Set a configuration value |
112
+ | `config list` | Display all configuration values |
113
+ | `config reset` | Reset configuration to defaults |
114
+ | `config path` | Show configuration file path |
115
+
116
+ **Examples:**
57
117
 
58
118
  ```bash
59
119
  # Show all configuration
60
120
  opnet config list
61
121
 
62
- # Get a specific value
122
+ # Get a specific value (dot notation supported)
63
123
  opnet config get defaultNetwork
64
124
  opnet config get rpcUrls.mainnet
65
125
 
66
126
  # Set a value
67
127
  opnet config set defaultNetwork testnet
128
+ opnet config set rpcUrls.regtest "http://localhost:9001"
68
129
  opnet config set ipfsPinningApiKey "your-api-key"
69
130
 
70
- # Reset to defaults
131
+ # Reset to defaults (requires confirmation)
132
+ opnet config reset
71
133
  opnet config reset --yes
72
134
 
73
135
  # Show config file path
74
136
  opnet config path
75
137
  ```
76
138
 
139
+ **Options for `config reset`:**
140
+
141
+ | Option | Description |
142
+ |---|---|
143
+ | `-y, --yes` | Skip confirmation prompt |
144
+
145
+ ---
146
+
77
147
  ### Authentication
78
148
 
79
149
  #### `opnet login`
80
150
 
81
- Configure wallet credentials for signing and publishing.
151
+ Configure wallet credentials for signing and publishing. Credentials are stored in `~/.opnet/credentials.json` with restricted permissions (owner read/write only).
152
+
153
+ **Syntax:** `opnet login [options]`
154
+
155
+ **Options:**
156
+
157
+ | Option | Description | Default |
158
+ |---|---|---|
159
+ | `-m, --mnemonic <phrase>` | BIP-39 mnemonic phrase (12 or 24 words) | — |
160
+ | `--wif <key>` | Bitcoin WIF private key (advanced) | — |
161
+ | `--mldsa <key>` | MLDSA private key hex (advanced, requires `--wif`) | — |
162
+ | `-l, --mldsa-level <level>` | MLDSA security level: `44`, `65`, or `87` | `44` |
163
+ | `-n, --network <network>` | Network: `mainnet`, `testnet`, or `regtest` | `mainnet` |
164
+
165
+ **Examples:**
82
166
 
83
167
  ```bash
84
- # Interactive mode
168
+ # Interactive mode (recommended) - prompts for mnemonic and network
85
169
  opnet login
86
170
 
87
- # With mnemonic phrase
88
- opnet login --mnemonic "your 24 word phrase..."
171
+ # With mnemonic phrase directly
172
+ opnet login --mnemonic "your twelve or twenty four word phrase here ..."
89
173
 
90
- # With specific network and MLDSA level
91
- opnet login --network testnet --mldsa-level 65
174
+ # With specific network
175
+ opnet login --mnemonic "your phrase ..." --network regtest
92
176
 
93
177
  # Advanced: WIF + standalone MLDSA key
94
- opnet login --wif "KwDiBf..." --mldsa "hex-key..."
178
+ opnet login --wif "KwDiBf..." --mldsa "hex-private-key..."
95
179
  ```
96
180
 
97
- **Options:**
181
+ After login, the CLI displays your wallet identity (P2TR address and MLDSA public key hash) for verification before saving.
98
182
 
99
- - `-m, --mnemonic <phrase>` - BIP-39 mnemonic phrase (24 words)
100
- - `--wif <key>` - Bitcoin WIF private key (advanced)
101
- - `--mldsa <key>` - MLDSA private key hex (advanced, requires --wif)
102
- - `-l, --mldsa-level <level>` - MLDSA security level (44, 65, 87) [default: 44]
103
- - `-n, --network <network>` - Network (mainnet, testnet, regtest) [default: mainnet]
104
- - `-y, --yes` - Skip confirmation prompts
183
+ ---
105
184
 
106
185
  #### `opnet logout`
107
186
 
108
- Remove stored wallet credentials.
187
+ Remove stored wallet credentials from `~/.opnet/credentials.json`. If credentials are set via environment variables, it displays instructions for unsetting them instead.
188
+
189
+ **Syntax:** `opnet logout [options]`
190
+
191
+ **Options:**
192
+
193
+ | Option | Description |
194
+ |---|---|
195
+ | `-y, --yes` | Skip confirmation prompt |
196
+
197
+ **Examples:**
109
198
 
110
199
  ```bash
111
200
  opnet logout
112
201
  opnet logout --yes
113
202
  ```
114
203
 
204
+ ---
205
+
115
206
  #### `opnet whoami`
116
207
 
117
- Display current wallet identity and configuration.
208
+ Display current wallet identity and configuration details.
209
+
210
+ **Syntax:** `opnet whoami [options]`
211
+
212
+ **Options:**
213
+
214
+ | Option | Description |
215
+ |---|---|
216
+ | `-v, --verbose` | Show detailed information (auth method, masked mnemonic/WIF, public key size) |
217
+ | `--public-key` | Show full MLDSA public key (hex) |
218
+
219
+ **Examples:**
118
220
 
119
221
  ```bash
222
+ # Basic identity
120
223
  opnet whoami
224
+
225
+ # Detailed info including auth method and masked secrets
121
226
  opnet whoami --verbose
227
+
228
+ # Include full MLDSA public key
122
229
  opnet whoami --public-key
123
230
  ```
124
231
 
232
+ **Output includes:**
233
+ - Network
234
+ - MLDSA security level
235
+ - Auth source (file or environment variable)
236
+ - P2TR address
237
+ - MLDSA public key hash
238
+
239
+ ---
240
+
125
241
  ### Key Generation
126
242
 
127
243
  #### `opnet keygen`
128
244
 
129
- Generate cryptographic keys.
245
+ Generate cryptographic keys. Has three subcommands: `mnemonic`, `mldsa`, and `info`.
246
+
247
+ ##### `opnet keygen mnemonic`
248
+
249
+ Generate a new BIP-39 mnemonic phrase.
250
+
251
+ **Options:**
252
+
253
+ | Option | Description |
254
+ |---|---|
255
+ | `-o, --output <file>` | Write mnemonic to file (with secure 0600 permissions) |
130
256
 
131
257
  ```bash
132
- # Generate a new mnemonic phrase
258
+ # Display mnemonic in terminal
133
259
  opnet keygen mnemonic
260
+
261
+ # Save to file
134
262
  opnet keygen mnemonic --output my-mnemonic.txt
263
+ ```
264
+
265
+ ##### `opnet keygen mldsa`
135
266
 
136
- # Generate standalone MLDSA keypair
267
+ Generate a standalone MLDSA keypair.
268
+
269
+ **Options:**
270
+
271
+ | Option | Description | Default |
272
+ |---|---|---|
273
+ | `-l, --level <level>` | MLDSA security level: `44`, `65`, or `87` | `44` |
274
+ | `-o, --output <prefix>` | Write keys to `<prefix>.private.key` and `<prefix>.public.key` | — |
275
+ | `--json` | Output as JSON | — |
276
+
277
+ ```bash
278
+ # Generate and display MLDSA-44 keypair
137
279
  opnet keygen mldsa
280
+
281
+ # Generate MLDSA-65 keypair
138
282
  opnet keygen mldsa --level 65
139
- opnet keygen mldsa --output my-key --json
140
283
 
141
- # Show MLDSA key size information
284
+ # Save to files
285
+ opnet keygen mldsa --output my-key
286
+ # Creates: my-key.private.key (0600) and my-key.public.key (0644)
287
+
288
+ # JSON output
289
+ opnet keygen mldsa --json
290
+ ```
291
+
292
+ ##### `opnet keygen info`
293
+
294
+ Display information about MLDSA key sizes across all security levels.
295
+
296
+ ```bash
142
297
  opnet keygen info
143
298
  ```
144
299
 
300
+ Output:
301
+
302
+ ```
303
+ Level Public Key Private Key Signature
304
+ ────────────────────────────────────────────────────────────
305
+ MLDSA-44 1,312 bytes 2,560 bytes 2,420 bytes
306
+ MLDSA-65 1,952 bytes 4,032 bytes 3,309 bytes
307
+ MLDSA-87 2,592 bytes 4,896 bytes 4,627 bytes
308
+ ```
309
+
310
+ ---
311
+
145
312
  ### Plugin Development
146
313
 
147
314
  #### `opnet init`
148
315
 
149
- Initialize a new OPNet plugin project.
316
+ Scaffold a new OPNet plugin project in the current directory.
317
+
318
+ **Syntax:** `opnet init [name] [options]`
319
+
320
+ **Arguments:**
321
+
322
+ | Argument | Description | Default |
323
+ |---|---|---|
324
+ | `[name]` | Plugin name | Current directory name (interactive prompt) |
325
+
326
+ **Options:**
327
+
328
+ | Option | Description | Default |
329
+ |---|---|---|
330
+ | `-t, --template <type>` | Template type: `standalone` or `library` | `standalone` |
331
+ | `-y, --yes` | Skip prompts and use defaults | — |
332
+ | `--force` | Overwrite existing files | — |
333
+
334
+ **Examples:**
150
335
 
151
336
  ```bash
152
- # Interactive mode
337
+ # Interactive mode - prompts for name, description, author, type
153
338
  opnet init
154
339
 
155
340
  # With name
156
341
  opnet init my-plugin
157
342
 
158
- # With options
159
- opnet init my-plugin --template library --yes
343
+ # Library template with defaults
344
+ opnet init my-lib --template library --yes
160
345
 
161
- # Force overwrite
162
- opnet init --force
346
+ # Overwrite existing project files
347
+ opnet init my-plugin --force
163
348
  ```
164
349
 
165
- **Options:**
350
+ **Generated files:**
351
+
352
+ | File | Description |
353
+ |---|---|
354
+ | `plugin.json` | Plugin manifest with permissions, resources, and lifecycle configuration |
355
+ | `package.json` | Node.js package configuration with OPNet dependencies |
356
+ | `tsconfig.json` | TypeScript configuration (ES2022, NodeNext) |
357
+ | `src/index.ts` | Entry point (extends `PluginBase` for standalone, exports for library) |
358
+ | `eslint.config.js` | ESLint configuration with typescript-eslint |
359
+ | `.prettierrc.json` | Prettier formatting configuration |
360
+ | `.gitignore` | Git ignore rules |
361
+ | `README.md` | Basic readme |
362
+
363
+ **Created directories:** `src/`, `dist/`, `build/`, `test/`
166
364
 
167
- - `-t, --template <type>` - Template type (standalone, library) [default: standalone]
168
- - `-y, --yes` - Skip prompts and use defaults
169
- - `--force` - Overwrite existing files
365
+ ---
170
366
 
171
367
  #### `opnet compile`
172
368
 
173
- Compile plugin to .opnet binary format.
369
+ Compile a plugin to the `.opnet` binary format. This command:
370
+ 1. Loads and validates `plugin.json`
371
+ 2. Bundles TypeScript with esbuild (CJS format)
372
+ 3. Compiles to V8 bytecode via bytenode
373
+ 4. Optionally signs the binary with your MLDSA key
374
+ 5. Assembles the final `.opnet` binary
375
+
376
+ **Syntax:** `opnet compile [options]`
377
+
378
+ **Options:**
379
+
380
+ | Option | Description | Default |
381
+ |---|---|---|
382
+ | `-o, --output <path>` | Output file path | `./build/<name>.opnet` |
383
+ | `-d, --dir <path>` | Plugin directory | Current directory |
384
+ | `--no-sign` | Skip signing (produce unsigned binary) | Signs by default |
385
+ | `--minify` | Minify the bundled code | `true` |
386
+ | `--sourcemap` | Generate source maps | `false` |
387
+
388
+ **Examples:**
174
389
 
175
390
  ```bash
176
- # Compile current directory
391
+ # Compile current directory (signed)
177
392
  opnet compile
178
393
 
179
- # Compile specific directory
394
+ # Compile a specific directory
180
395
  opnet compile --dir ./my-plugin
181
396
 
182
397
  # Custom output path
183
398
  opnet compile --output ./dist/plugin.opnet
184
399
 
185
- # Skip signing (for testing)
400
+ # Unsigned binary (for testing)
186
401
  opnet compile --no-sign
402
+
403
+ # With source maps, no minification
404
+ opnet compile --sourcemap --no-minify
187
405
  ```
188
406
 
189
- **Options:**
407
+ **Prerequisites:**
408
+ - `plugin.json` must exist in the project directory
409
+ - `src/index.ts` must exist as the entry point
410
+ - For signed binaries, wallet must be configured (`opnet login`)
411
+
412
+ **Output information:**
413
+ - Output file path and size
414
+ - Plugin name, version, and type
415
+ - MLDSA level, SHA-256 checksum, and signing status
416
+
417
+ > **Note:** Unsigned binaries cannot be published to the registry. Use `opnet sign` to sign them later.
190
418
 
191
- - `-o, --output <path>` - Output file path
192
- - `-d, --dir <path>` - Plugin directory [default: current]
193
- - `--no-sign` - Skip signing (produce unsigned binary)
194
- - `--minify` - Minify the bundled code [default: true]
195
- - `--sourcemap` - Generate source maps
419
+ ---
196
420
 
197
421
  #### `opnet verify`
198
422
 
199
- Verify a .opnet binary signature and integrity.
423
+ Verify a `.opnet` binary's signature and integrity. Checks both the SHA-256 checksum and the MLDSA signature.
424
+
425
+ **Syntax:** `opnet verify <file> [options]`
426
+
427
+ **Arguments:**
428
+
429
+ | Argument | Description |
430
+ |---|---|
431
+ | `<file>` | Path to `.opnet` file |
432
+
433
+ **Options:**
434
+
435
+ | Option | Description |
436
+ |---|---|
437
+ | `-v, --verbose` | Show detailed information (sizes, checksums, author, permissions) |
438
+ | `--json` | Output results as JSON |
439
+
440
+ **Examples:**
200
441
 
201
442
  ```bash
202
- opnet verify plugin.opnet
203
- opnet verify plugin.opnet --verbose
204
- opnet verify plugin.opnet --json
443
+ # Basic verification
444
+ opnet verify build/my-plugin.opnet
445
+
446
+ # Detailed output
447
+ opnet verify build/my-plugin.opnet --verbose
448
+
449
+ # JSON output (useful for CI/CD)
450
+ opnet verify build/my-plugin.opnet --json
205
451
  ```
206
452
 
207
- **Options:**
453
+ **Exit codes:**
454
+ - `0` - Binary is valid and properly signed
455
+ - `1` - Verification failed (invalid checksum, invalid signature, or unsigned)
208
456
 
209
- - `-v, --verbose` - Show detailed information
210
- - `--json` - Output as JSON
457
+ **Verification checks:**
458
+ - SHA-256 checksum integrity
459
+ - MLDSA signature validity
460
+ - Unsigned binary detection
461
+
462
+ ---
211
463
 
212
464
  #### `opnet info`
213
465
 
214
- Display information about a plugin or .opnet file.
466
+ Display information about a plugin project or a compiled `.opnet` file.
467
+
468
+ **Syntax:** `opnet info [path] [options]`
469
+
470
+ **Arguments:**
471
+
472
+ | Argument | Description | Default |
473
+ |---|---|---|
474
+ | `[path]` | Path to plugin directory, `plugin.json`, or `.opnet` file | Current directory |
475
+
476
+ **Options:**
477
+
478
+ | Option | Description |
479
+ |---|---|
480
+ | `--json` | Output as JSON |
481
+
482
+ **Examples:**
215
483
 
216
484
  ```bash
217
- # Show project info
485
+ # Show project info (current directory)
218
486
  opnet info
219
487
 
220
- # Show binary info
221
- opnet info plugin.opnet
488
+ # Show info for a specific directory
489
+ opnet info ./my-plugin
490
+
491
+ # Show compiled binary info
492
+ opnet info build/my-plugin.opnet
222
493
 
223
494
  # JSON output
224
495
  opnet info --json
496
+ opnet info build/my-plugin.opnet --json
225
497
  ```
226
498
 
499
+ **For project directories, shows:**
500
+ - Plugin name, version, type, OPNet version compatibility
501
+ - Author information
502
+ - Source/dependencies/compiled status
503
+ - Permissions, resources, and lifecycle configuration
504
+ - Plugin dependencies
505
+
506
+ **For `.opnet` files, shows:**
507
+ - File size and format version
508
+ - Plugin metadata (name, version, type)
509
+ - Cryptographic info (MLDSA level, signing status, publisher hash)
510
+ - Component sizes (bytecode, metadata, proto)
511
+ - Permissions and dependencies
512
+
513
+ ---
514
+
227
515
  #### `opnet sign`
228
516
 
229
- Sign or re-sign a .opnet binary with your MLDSA key.
517
+ Sign or re-sign a `.opnet` binary with your MLDSA key. This rebuilds the binary with your key and signature.
518
+
519
+ **Syntax:** `opnet sign <file> [options]`
520
+
521
+ **Arguments:**
522
+
523
+ | Argument | Description |
524
+ |---|---|
525
+ | `<file>` | Path to `.opnet` file |
526
+
527
+ **Options:**
528
+
529
+ | Option | Description | Default |
530
+ |---|---|---|
531
+ | `-o, --output <path>` | Output file path | Overwrites input file |
532
+ | `--force` | Force re-signing even if already signed by a different key | — |
533
+
534
+ **Examples:**
230
535
 
231
536
  ```bash
232
- opnet sign plugin.opnet
233
- opnet sign plugin.opnet --output signed.opnet
234
- opnet sign plugin.opnet --force # Re-sign with different key
537
+ # Sign an unsigned binary (overwrites in-place)
538
+ opnet sign build/my-plugin.opnet
539
+
540
+ # Sign and save to a different file
541
+ opnet sign build/my-plugin.opnet --output build/signed.opnet
542
+
543
+ # Re-sign a binary that was signed by someone else
544
+ opnet sign build/plugin.opnet --force
235
545
  ```
236
546
 
237
- **Options:**
547
+ **Behavior:**
548
+ - If the binary is unsigned, it signs it with your key
549
+ - If already signed by the same key, it re-signs (refreshes the signature)
550
+ - If signed by a different key, it refuses unless `--force` is used
551
+ - Requires wallet credentials (`opnet login`)
238
552
 
239
- - `-o, --output <path>` - Output file path [default: overwrites input]
240
- - `--force` - Force re-signing even if already signed by different key
553
+ ---
241
554
 
242
- ### Registry Commands
555
+ ### Registry - Publishing
243
556
 
244
557
  #### `opnet publish`
245
558
 
246
- Publish a plugin to the OPNet registry.
559
+ Publish a plugin to the OPNet on-chain registry. This command:
560
+ 1. Parses and validates the `.opnet` binary
561
+ 2. Verifies checksum and signature
562
+ 3. Confirms your wallet matches the signer
563
+ 4. Checks scope registration (for scoped packages)
564
+ 5. Uploads the binary to IPFS
565
+ 6. Registers the package on-chain (if new)
566
+ 7. Publishes the version on-chain
567
+
568
+ **Syntax:** `opnet publish [file] [options]`
569
+
570
+ **Arguments:**
571
+
572
+ | Argument | Description | Default |
573
+ |---|---|---|
574
+ | `[file]` | Path to `.opnet` file | Auto-detected from `plugin.json` (`./build/<name>.opnet`) |
575
+
576
+ **Options:**
577
+
578
+ | Option | Description | Default |
579
+ |---|---|---|
580
+ | `-n, --network <network>` | Network to publish to | `mainnet` |
581
+ | `--dry-run` | Show what would be published without actually publishing | — |
582
+ | `-y, --yes` | Skip confirmation prompts | — |
583
+
584
+ **Examples:**
247
585
 
248
586
  ```bash
249
- # Publish from current directory
587
+ # Publish from current directory (auto-detects .opnet file)
250
588
  opnet publish
251
589
 
252
590
  # Publish specific file
253
- opnet publish plugin.opnet
591
+ opnet publish build/my-plugin.opnet
254
592
 
255
- # Dry run
593
+ # Dry run to preview
256
594
  opnet publish --dry-run
257
595
 
258
- # Specific network
259
- opnet publish --network testnet
596
+ # Publish to regtest
597
+ opnet publish --network regtest
598
+
599
+ # Non-interactive
600
+ opnet publish --yes --network regtest
260
601
  ```
261
602
 
262
- **Options:**
603
+ **Prerequisites:**
604
+ - Binary must be signed (run `opnet compile` or `opnet sign`)
605
+ - Wallet must match the binary signer
606
+ - For scoped packages (`@scope/name`), the scope must be registered first
607
+ - Wallet must have sufficient balance for transaction fees
263
608
 
264
- - `-n, --network <network>` - Network to publish to [default: mainnet]
265
- - `--dry-run` - Show what would be published without publishing
266
- - `-y, --yes` - Skip confirmation prompts
609
+ ---
267
610
 
268
611
  #### `opnet deprecate`
269
612
 
270
- Mark a package version as deprecated.
613
+ Mark a package version as deprecated. Only works within the 72-hour mutability window after publishing.
271
614
 
272
- ```bash
273
- opnet deprecate @scope/plugin
274
- opnet deprecate @scope/plugin 1.0.0
275
- opnet deprecate @scope/plugin 1.0.0 --message "Security vulnerability"
276
- ```
615
+ **Syntax:** `opnet deprecate <package> [version] [options]`
277
616
 
278
- **Options:**
617
+ **Arguments:**
279
618
 
280
- - `-m, --message <message>` - Deprecation reason/message
281
- - `-n, --network <network>` - Network [default: mainnet]
282
- - `-y, --yes` - Skip confirmation
619
+ | Argument | Description | Default |
620
+ |---|---|---|
621
+ | `<package>` | Package name (e.g., `@scope/name` or `name`) | — |
622
+ | `[version]` | Version to deprecate | Latest version |
283
623
 
284
- #### `opnet undeprecate`
624
+ **Options:**
625
+
626
+ | Option | Description | Default |
627
+ |---|---|---|
628
+ | `-m, --message <message>` | Deprecation reason/message | Interactive prompt (or "No reason provided") |
629
+ | `-n, --network <network>` | Network | `mainnet` |
630
+ | `-y, --yes` | Skip confirmation | — |
285
631
 
286
- Remove deprecation from a package version.
632
+ **Examples:**
287
633
 
288
634
  ```bash
289
- opnet undeprecate @scope/plugin 1.0.0
635
+ # Deprecate latest version (prompts for reason)
636
+ opnet deprecate @myscope/plugin
637
+
638
+ # Deprecate specific version with reason
639
+ opnet deprecate @myscope/plugin 1.0.0 --message "Security vulnerability found"
640
+
641
+ # Non-interactive
642
+ opnet deprecate @myscope/plugin 1.0.0 -m "Use v2.0.0 instead" --yes
290
643
  ```
291
644
 
292
- #### `opnet transfer`
645
+ > **Note:** Versions past the 72-hour mutability window cannot be deprecated.
293
646
 
294
- Initiate ownership transfer of a package or scope.
647
+ ---
295
648
 
296
- ```bash
297
- # Transfer a package
298
- opnet transfer my-plugin bc1q...
649
+ #### `opnet undeprecate`
299
650
 
300
- # Transfer a scope
301
- opnet transfer @myscope bc1q...
651
+ Remove deprecation from a package version. Only works within the 72-hour mutability window.
302
652
 
303
- # Cancel pending transfer
304
- opnet transfer my-plugin --cancel
305
- ```
653
+ **Syntax:** `opnet undeprecate <package> <version> [options]`
306
654
 
307
- **Options:**
655
+ **Arguments:**
308
656
 
309
- - `-n, --network <network>` - Network [default: mainnet]
310
- - `-y, --yes` - Skip confirmation
311
- - `--cancel` - Cancel pending transfer
657
+ | Argument | Description |
658
+ |---|---|
659
+ | `<package>` | Package name (e.g., `@scope/name` or `name`) |
660
+ | `<version>` | Version to undeprecate |
312
661
 
313
- #### `opnet accept`
662
+ **Options:**
314
663
 
315
- Accept pending ownership transfer.
664
+ | Option | Description | Default |
665
+ |---|---|---|
666
+ | `-n, --network <network>` | Network | `mainnet` |
667
+ | `-y, --yes` | Skip confirmation | — |
668
+
669
+ **Examples:**
316
670
 
317
671
  ```bash
318
- opnet accept my-plugin
319
- opnet accept @myscope
672
+ opnet undeprecate @myscope/plugin 1.0.0
673
+ opnet undeprecate @myscope/plugin 1.0.0 --network regtest --yes
320
674
  ```
321
675
 
676
+ ---
677
+
678
+ ### Registry - Package Management
679
+
322
680
  #### `opnet install`
323
681
 
324
- Download and verify a plugin from the registry.
682
+ Download and verify a plugin from the registry. Automatically removes older versions of the same plugin from the output directory.
683
+
684
+ **Syntax:** `opnet install <package> [options]`
685
+
686
+ **Arguments:**
687
+
688
+ | Argument | Description |
689
+ |---|---|
690
+ | `<package>` | Package name (optionally with `@version`), or a raw IPFS CID |
691
+
692
+ **Options:**
693
+
694
+ | Option | Description | Default |
695
+ |---|---|---|
696
+ | `-o, --output <path>` | Output directory | `./plugins/` |
697
+ | `-n, --network <network>` | Network | `mainnet` |
698
+ | `--skip-verify` | Skip signature verification | — |
699
+
700
+ **Examples:**
325
701
 
326
702
  ```bash
327
703
  # Install latest version
@@ -330,150 +706,567 @@ opnet install @scope/plugin
330
706
  # Install specific version
331
707
  opnet install @scope/plugin@1.0.0
332
708
 
333
- # Install from IPFS CID
709
+ # Install an unscoped package
710
+ opnet install my-plugin
711
+
712
+ # Install directly from IPFS CID
334
713
  opnet install QmXyz...
335
714
 
336
715
  # Custom output directory
337
716
  opnet install @scope/plugin --output ./my-plugins
717
+
718
+ # Skip signature verification (not recommended)
719
+ opnet install @scope/plugin --skip-verify
338
720
  ```
339
721
 
340
- **Options:**
722
+ **What happens:**
723
+ 1. Resolves the package and version from the on-chain registry
724
+ 2. Downloads the binary from IPFS
725
+ 3. Verifies checksum integrity
726
+ 4. Verifies MLDSA signature (unless `--skip-verify`)
727
+ 5. Removes older versions of the same plugin from the output directory
728
+ 6. Saves to `<output>/<package>-<version>.opnet`
341
729
 
342
- - `-o, --output <path>` - Output directory [default: ./plugins/]
343
- - `-n, --network <network>` - Network [default: mainnet]
344
- - `--skip-verify` - Skip signature verification
730
+ ---
345
731
 
346
732
  #### `opnet update`
347
733
 
348
- Update installed plugins to latest versions.
734
+ Check and update installed plugins to their latest versions.
735
+
736
+ **Syntax:** `opnet update [package] [options]`
737
+
738
+ **Arguments:**
739
+
740
+ | Argument | Description | Default |
741
+ |---|---|---|
742
+ | `[package]` | Specific package to update | All installed plugins |
743
+
744
+ **Options:**
745
+
746
+ | Option | Description | Default |
747
+ |---|---|---|
748
+ | `-d, --dir <path>` | Plugins directory | `./plugins/` |
749
+ | `-n, --network <network>` | Network | `mainnet` |
750
+ | `--skip-verify` | Skip signature verification | — |
751
+
752
+ **Examples:**
349
753
 
350
754
  ```bash
351
- # Update all plugins
755
+ # Update all installed plugins
352
756
  opnet update
353
757
 
354
- # Update specific plugin
758
+ # Update a specific plugin
355
759
  opnet update @scope/plugin
356
760
 
357
761
  # Custom plugins directory
358
762
  opnet update --dir ./my-plugins
359
- ```
360
763
 
361
- **Options:**
764
+ # Different network
765
+ opnet update --network regtest
766
+ ```
362
767
 
363
- - `-d, --dir <path>` - Plugins directory [default: ./plugins/]
364
- - `-n, --network <network>` - Network [default: mainnet]
365
- - `--skip-verify` - Skip signature verification
768
+ ---
366
769
 
367
770
  #### `opnet list`
368
771
 
369
- List installed plugins.
772
+ List all installed plugins in a directory. Alias: `opnet ls`.
773
+
774
+ **Syntax:** `opnet list [options]`
775
+
776
+ **Options:**
777
+
778
+ | Option | Description | Default |
779
+ |---|---|---|
780
+ | `-d, --dir <path>` | Plugins directory | `./plugins/` |
781
+ | `--json` | Output as JSON | — |
782
+ | `-v, --verbose` | Show detailed information per plugin | — |
783
+
784
+ **Examples:**
370
785
 
371
786
  ```bash
787
+ # List plugins (table view)
372
788
  opnet list
373
789
  opnet ls
790
+
791
+ # Detailed list
374
792
  opnet list --verbose
793
+
794
+ # JSON output
375
795
  opnet list --json
796
+
797
+ # Custom directory
376
798
  opnet list --dir ./my-plugins
377
799
  ```
378
800
 
379
- **Options:**
801
+ **Table output columns:** Name, Version, Type, Size, Signed
380
802
 
381
- - `-d, --dir <path>` - Plugins directory [default: ./plugins/]
382
- - `--json` - Output as JSON
383
- - `-v, --verbose` - Show detailed information
803
+ ---
384
804
 
385
805
  #### `opnet search`
386
806
 
387
- Search for plugins in the registry.
807
+ Search for a plugin in the on-chain registry by exact package name.
808
+
809
+ **Syntax:** `opnet search <query> [options]`
810
+
811
+ **Arguments:**
812
+
813
+ | Argument | Description |
814
+ |---|---|
815
+ | `<query>` | Package name or `@scope/name` |
816
+
817
+ **Options:**
818
+
819
+ | Option | Description | Default |
820
+ |---|---|---|
821
+ | `-n, --network <network>` | Network | `mainnet` |
822
+ | `--json` | Output as JSON | — |
823
+
824
+ **Examples:**
388
825
 
389
826
  ```bash
390
- opnet search plugin-name
827
+ opnet search my-plugin
391
828
  opnet search @scope/plugin
392
- opnet search plugin-name --json
829
+ opnet search @scope/plugin --json
830
+ opnet search my-plugin --network regtest
393
831
  ```
394
832
 
833
+ **Output includes:**
834
+ - Package name, latest version, total version count
835
+ - Owner address
836
+ - Latest version details: type, MLDSA level, OPNet version range, IPFS CID, deprecation status, publish block
837
+ - Install command
838
+
839
+ ---
840
+
841
+ ### Registry - Ownership
842
+
843
+ #### `opnet scope:register`
844
+
845
+ Register a new scope (namespace) in the on-chain registry. Scopes are required for publishing scoped packages (`@scope/name`). Registration has a one-time fee.
846
+
847
+ **Syntax:** `opnet scope:register <name> [options]`
848
+
849
+ **Arguments:**
850
+
851
+ | Argument | Description |
852
+ |---|---|
853
+ | `<name>` | Scope name (without `@` prefix) |
854
+
855
+ **Options:**
856
+
857
+ | Option | Description | Default |
858
+ |---|---|---|
859
+ | `-n, --network <network>` | Network | `mainnet` |
860
+ | `-y, --yes` | Skip confirmation | — |
861
+
862
+ **Scope name rules:**
863
+ - Must start with a lowercase letter
864
+ - Can contain only lowercase letters, numbers, and hyphens
865
+ - Must end with a letter or number
866
+
867
+ **Examples:**
868
+
869
+ ```bash
870
+ # Register a scope
871
+ opnet scope:register myscope
872
+
873
+ # With @ prefix (auto-stripped)
874
+ opnet scope:register @myscope
875
+
876
+ # On regtest
877
+ opnet scope:register myscope --network regtest --yes
878
+ ```
879
+
880
+ ---
881
+
882
+ #### `opnet transfer`
883
+
884
+ Initiate ownership transfer of a package or scope. The new owner must call `opnet accept` to complete the transfer. You can also cancel a pending transfer.
885
+
886
+ **Syntax:** `opnet transfer <name> [newOwner] [options]`
887
+
888
+ **Arguments:**
889
+
890
+ | Argument | Description |
891
+ |---|---|
892
+ | `<name>` | Package name or `@scope` (scope if starts with `@` and no `/`) |
893
+ | `[newOwner]` | New owner address (prompted if not provided) |
894
+
395
895
  **Options:**
396
896
 
397
- - `-n, --network <network>` - Network [default: mainnet]
398
- - `--json` - Output as JSON
897
+ | Option | Description | Default |
898
+ |---|---|---|
899
+ | `-n, --network <network>` | Network | `mainnet` |
900
+ | `-y, --yes` | Skip confirmation | — |
901
+ | `--cancel` | Cancel a pending transfer instead of initiating one | — |
902
+
903
+ **Examples:**
904
+
905
+ ```bash
906
+ # Transfer a package
907
+ opnet transfer my-plugin bc1p...
908
+
909
+ # Transfer a scope
910
+ opnet transfer @myscope bc1p...
911
+
912
+ # Interactive (prompts for new owner address)
913
+ opnet transfer my-plugin
914
+
915
+ # Cancel a pending transfer
916
+ opnet transfer my-plugin --cancel
917
+ opnet transfer @myscope --cancel
918
+ ```
919
+
920
+ ---
921
+
922
+ #### `opnet accept`
923
+
924
+ Accept a pending ownership transfer for a package or scope.
925
+
926
+ **Syntax:** `opnet accept <name> [options]`
927
+
928
+ **Arguments:**
929
+
930
+ | Argument | Description |
931
+ |---|---|
932
+ | `<name>` | Package name or `@scope` |
933
+
934
+ **Options:**
935
+
936
+ | Option | Description | Default |
937
+ |---|---|---|
938
+ | `-n, --network <network>` | Network | `mainnet` |
939
+ | `-y, --yes` | Skip confirmation | — |
940
+
941
+ **Examples:**
942
+
943
+ ```bash
944
+ # Accept package transfer
945
+ opnet accept my-plugin
946
+
947
+ # Accept scope transfer
948
+ opnet accept @myscope
949
+
950
+ # Non-interactive
951
+ opnet accept my-plugin --network regtest --yes
952
+ ```
953
+
954
+ ---
955
+
956
+ ### Domains & Websites
957
+
958
+ #### `opnet domain register`
959
+
960
+ Register a new `.btc` domain on the BTC Name Resolver. Domain pricing is tiered based on name length and keyword value.
961
+
962
+ **Syntax:** `opnet domain register <name> [options]`
963
+
964
+ **Arguments:**
965
+
966
+ | Argument | Description |
967
+ |---|---|
968
+ | `<name>` | Domain name to register (without `.btc` suffix) |
969
+
970
+ **Options:**
971
+
972
+ | Option | Description | Default |
973
+ |---|---|---|
974
+ | `-n, --network <network>` | Network | `mainnet` |
975
+ | `--dry-run` | Show what would happen without registering | — |
976
+ | `-y, --yes` | Skip confirmation prompts | — |
977
+
978
+ **Pricing tiers:**
979
+
980
+ | Tier | Price | Description |
981
+ |---|---|---|
982
+ | Ultra Legendary (Tier 0) | 10 BTC | Iconic crypto/tech names |
983
+ | Legendary (Tier 1) | 1 BTC | Single character or top keywords |
984
+ | Premium (Tier 2) | 0.25 BTC | Two character or major protocols |
985
+ | High Value (Tier 3) | 0.1 BTC | Three character or valuable keywords |
986
+ | Valuable (Tier 4) | 0.05 BTC | Four character or common keywords |
987
+ | Common Premium (Tier 5) | 0.01 BTC | Five character domains |
988
+ | Notable (Tier 6) | 0.005 BTC | Notable keywords |
989
+ | Standard | 0.001 BTC | Standard domains (6+ characters) |
990
+
991
+ **Examples:**
992
+
993
+ ```bash
994
+ # Register a domain
995
+ opnet domain register mysite
996
+
997
+ # Preview without registering
998
+ opnet domain register mysite --dry-run
999
+
1000
+ # Register on regtest
1001
+ opnet domain register mysite --network regtest --yes
1002
+ ```
1003
+
1004
+ > **Note:** Subdomains cannot be registered directly. Register the parent domain first.
1005
+
1006
+ ---
1007
+
1008
+ #### `opnet domain info`
1009
+
1010
+ Look up information about a `.btc` domain. Shows registration status, owner, contenthash (website), and pricing for available domains.
1011
+
1012
+ **Syntax:** `opnet domain info <name> [options]`
1013
+
1014
+ **Arguments:**
1015
+
1016
+ | Argument | Description |
1017
+ |---|---|
1018
+ | `<name>` | Domain name (with or without `.btc` suffix) |
1019
+
1020
+ **Options:**
1021
+
1022
+ | Option | Description | Default |
1023
+ |---|---|---|
1024
+ | `-n, --network <network>` | Network | `mainnet` |
1025
+
1026
+ **Examples:**
1027
+
1028
+ ```bash
1029
+ # Look up a domain
1030
+ opnet domain info mysite
1031
+ opnet domain info mysite.btc
1032
+
1033
+ # Check on regtest
1034
+ opnet domain info mysite --network regtest
1035
+ ```
1036
+
1037
+ **For registered domains, shows:**
1038
+ - Owner address
1039
+ - Creation block
1040
+ - TTL
1041
+ - Website contenthash (if set) with IPFS/IPNS gateway URL
1042
+
1043
+ **For unregistered domains, shows:**
1044
+ - Availability status
1045
+ - Registration price and pricing tier
1046
+ - Registration command
1047
+
1048
+ ---
1049
+
1050
+ #### `opnet website`
1051
+
1052
+ Publish a website to a `.btc` domain by setting its contenthash. Supports IPFS CIDv0, CIDv1, IPNS, and SHA256 content hashes.
399
1053
 
400
- ## Configuration
1054
+ **Syntax:** `opnet website <domain> <contenthash> [options]`
401
1055
 
402
- Configuration is stored in `~/.opnet/config.json`:
1056
+ **Arguments:**
1057
+
1058
+ | Argument | Description |
1059
+ |---|---|
1060
+ | `<domain>` | Domain name (e.g., `mysite` or `mysite.btc`) |
1061
+ | `<contenthash>` | IPFS CID, IPNS ID, or SHA256 hash |
1062
+
1063
+ **Options:**
1064
+
1065
+ | Option | Description | Default |
1066
+ |---|---|---|
1067
+ | `-n, --network <network>` | Network | `mainnet` |
1068
+ | `--dry-run` | Show what would be published without publishing | — |
1069
+ | `-y, --yes` | Skip confirmation prompts | — |
1070
+ | `-t, --type <type>` | Contenthash type: `cidv0`, `cidv1`, `ipns`, `sha256` | Auto-detected |
1071
+
1072
+ **Examples:**
1073
+
1074
+ ```bash
1075
+ # Publish with IPFS CID (auto-detected type)
1076
+ opnet website mysite QmXyz...abc
1077
+ opnet website mysite bafybeiabc...
1078
+
1079
+ # Publish with IPNS
1080
+ opnet website mysite k51qzi5uqu5d... --type ipns
1081
+
1082
+ # Publish with SHA256 hash
1083
+ opnet website mysite abc123...def --type sha256
1084
+
1085
+ # Dry run
1086
+ opnet website mysite QmXyz... --dry-run
1087
+
1088
+ # Subdomain support
1089
+ opnet website blog.mysite QmXyz...
1090
+ ```
1091
+
1092
+ **Contenthash type auto-detection:**
1093
+ - Starts with `Qm` → CIDv0
1094
+ - Starts with `bafy` → CIDv1
1095
+ - Starts with `k51` or `12D3` → IPNS
1096
+ - 64 hex characters → SHA256
1097
+
1098
+ ---
1099
+
1100
+ #### `opnet deploy`
1101
+
1102
+ Upload a website directory or file to IPFS and publish the resulting CID to a `.btc` domain in a single command. Combines IPFS upload + on-chain contenthash update.
1103
+
1104
+ **Syntax:** `opnet deploy <domain> <path> [options]`
1105
+
1106
+ **Arguments:**
1107
+
1108
+ | Argument | Description |
1109
+ |---|---|
1110
+ | `<domain>` | Domain name (e.g., `mysite` or `mysite.btc`) |
1111
+ | `<path>` | Path to website directory or HTML file |
1112
+
1113
+ **Options:**
1114
+
1115
+ | Option | Description | Default |
1116
+ |---|---|---|
1117
+ | `-n, --network <network>` | Network | `mainnet` |
1118
+ | `--dry-run` | Upload to IPFS but don't update on-chain | — |
1119
+ | `-y, --yes` | Skip confirmation prompts | — |
1120
+
1121
+ **Examples:**
1122
+
1123
+ ```bash
1124
+ # Deploy a directory
1125
+ opnet deploy mysite ./dist
1126
+
1127
+ # Deploy a single HTML file
1128
+ opnet deploy mysite ./index.html
1129
+
1130
+ # Upload to IPFS only (no on-chain update)
1131
+ opnet deploy mysite ./dist --dry-run
1132
+
1133
+ # Non-interactive deployment to regtest
1134
+ opnet deploy mysite ./dist --network regtest --yes
1135
+ ```
1136
+
1137
+ **What happens:**
1138
+ 1. Validates domain ownership
1139
+ 2. Uploads the directory/file to IPFS
1140
+ 3. Sets the CIDv1 contenthash on-chain
1141
+ 4. Waits for transaction confirmation
1142
+
1143
+ ---
1144
+
1145
+ ## Configuration Reference
1146
+
1147
+ Configuration is stored in `~/.opnet/config.json`. All values can be set with `opnet config set` or overridden with environment variables.
403
1148
 
404
1149
  ```json
405
1150
  {
406
- "defaultNetwork": "mainnet",
1151
+ "defaultNetwork": "regtest",
407
1152
  "rpcUrls": {
408
1153
  "mainnet": "https://api.opnet.org",
409
1154
  "testnet": "https://testnet.opnet.org",
410
1155
  "regtest": "https://regtest.opnet.org"
411
1156
  },
412
1157
  "ipfsGateway": "https://ipfs.opnet.org/ipfs/",
413
- "ipfsGateways": [
414
- "https://ipfs.opnet.org/ipfs/",
415
- "https://ipfs.io/ipfs/"
416
- ],
1158
+ "ipfsGateways": ["https://ipfs.opnet.org/ipfs/"],
417
1159
  "ipfsPinningEndpoint": "https://ipfs.opnet.org/api/v0/add",
418
1160
  "ipfsPinningApiKey": "",
1161
+ "ipfsPinningSecret": "",
1162
+ "ipfsPinningAuthHeader": "Authorization",
419
1163
  "registryAddresses": {
420
1164
  "mainnet": "",
421
1165
  "testnet": "",
422
- "regtest": ""
1166
+ "regtest": "0x0737..."
1167
+ },
1168
+ "resolverAddresses": {
1169
+ "mainnet": "",
1170
+ "testnet": "",
1171
+ "regtest": "0x271e..."
423
1172
  },
424
1173
  "defaultMldsaLevel": 44,
425
1174
  "indexerUrl": "https://indexer.opnet.org"
426
1175
  }
427
1176
  ```
428
1177
 
1178
+ | Key | Description |
1179
+ |---|---|
1180
+ | `defaultNetwork` | Default network for all commands (`mainnet`, `testnet`, `regtest`) |
1181
+ | `rpcUrls.<network>` | JSON-RPC endpoint for each network |
1182
+ | `ipfsGateway` | Primary IPFS gateway for downloads |
1183
+ | `ipfsGateways` | Fallback IPFS gateways |
1184
+ | `ipfsPinningEndpoint` | IPFS pinning service URL |
1185
+ | `ipfsPinningApiKey` | IPFS pinning API key or JWT token |
1186
+ | `ipfsPinningSecret` | IPFS pinning API secret (for key+secret auth) |
1187
+ | `ipfsPinningAuthHeader` | Authorization header name for pinning service |
1188
+ | `registryAddresses.<network>` | On-chain package registry contract address |
1189
+ | `resolverAddresses.<network>` | On-chain BTC Name Resolver contract address |
1190
+ | `defaultMldsaLevel` | Default MLDSA security level for key generation |
1191
+ | `indexerUrl` | Indexer API URL for search operations |
1192
+
429
1193
  ## Environment Variables
430
1194
 
431
- | Variable | Description |
432
- |-------------------------------|-------------------------------------|
433
- | `OPNET_MNEMONIC` | BIP-39 mnemonic phrase |
434
- | `OPNET_PRIVATE_KEY` | Bitcoin WIF private key |
435
- | `OPNET_MLDSA_KEY` | MLDSA private key (hex) |
436
- | `OPNET_MLDSA_LEVEL` | MLDSA security level (44, 65, 87) |
437
- | `OPNET_NETWORK` | Network (mainnet, testnet, regtest) |
438
- | `OPNET_RPC_URL` | RPC endpoint URL |
439
- | `OPNET_IPFS_GATEWAY` | IPFS gateway URL |
440
- | `OPNET_IPFS_PINNING_ENDPOINT` | IPFS pinning service endpoint |
441
- | `OPNET_IPFS_PINNING_KEY` | IPFS pinning API key |
442
- | `OPNET_REGISTRY_ADDRESS` | Registry contract address |
443
- | `OPNET_INDEXER_URL` | Indexer API URL |
1195
+ Environment variables override file-based configuration and credentials. Useful for CI/CD pipelines.
1196
+
1197
+ | Variable | Description | Overrides |
1198
+ |---|---|---|
1199
+ | `OPNET_MNEMONIC` | BIP-39 mnemonic phrase | Credentials file |
1200
+ | `OPNET_PRIVATE_KEY` | Bitcoin WIF private key | Credentials file |
1201
+ | `OPNET_MLDSA_KEY` | MLDSA private key (hex) | Credentials file |
1202
+ | `OPNET_MLDSA_LEVEL` | MLDSA security level (`44`, `65`, `87`) | Credentials file |
1203
+ | `OPNET_NETWORK` | Network (`mainnet`, `testnet`, `regtest`) | `defaultNetwork` config |
1204
+ | `OPNET_RPC_URL` | RPC endpoint URL | `rpcUrls.<network>` config |
1205
+ | `OPNET_IPFS_GATEWAY` | IPFS gateway URL | `ipfsGateway` config |
1206
+ | `OPNET_IPFS_PINNING_ENDPOINT` | IPFS pinning service endpoint | `ipfsPinningEndpoint` config |
1207
+ | `OPNET_IPFS_PINNING_KEY` | IPFS pinning API key | `ipfsPinningApiKey` config |
1208
+ | `OPNET_REGISTRY_ADDRESS` | Registry contract address | `registryAddresses.<network>` config |
1209
+ | `OPNET_INDEXER_URL` | Indexer API URL | `indexerUrl` config |
1210
+
1211
+ **CI/CD example:**
1212
+
1213
+ ```bash
1214
+ export OPNET_MNEMONIC="your mnemonic phrase here"
1215
+ export OPNET_NETWORK="regtest"
1216
+ opnet compile && opnet publish --yes
1217
+ ```
1218
+
1219
+ ## Credential Storage
1220
+
1221
+ Credentials are stored in `~/.opnet/credentials.json` with restricted permissions (`0600` - owner read/write only).
1222
+
1223
+ **Two authentication methods:**
1224
+
1225
+ 1. **BIP-39 Mnemonic** (recommended) - Derives both Bitcoin (secp256k1) and MLDSA keys from a single phrase
1226
+ 2. **WIF + MLDSA key** (advanced) - Separate Bitcoin private key and standalone MLDSA private key
1227
+
1228
+ **Priority order:** Environment variables > credentials file
444
1229
 
445
1230
  ## MLDSA Security Levels
446
1231
 
447
- | Level | Public Key | Signature | Security |
448
- |----------|-------------|-------------|----------|
449
- | MLDSA-44 | 1,312 bytes | 2,420 bytes | ~128-bit |
450
- | MLDSA-65 | 1,952 bytes | 3,309 bytes | ~192-bit |
451
- | MLDSA-87 | 2,592 bytes | 4,627 bytes | ~256-bit |
1232
+ OPNet uses ML-DSA (Module-Lattice-Based Digital Signature Algorithm) for quantum-resistant signatures.
1233
+
1234
+ | Level | Public Key | Private Key | Signature | Security |
1235
+ |---|---|---|---|---|
1236
+ | MLDSA-44 | 1,312 bytes | 2,560 bytes | 2,420 bytes | ~128-bit |
1237
+ | MLDSA-65 | 1,952 bytes | 4,032 bytes | 3,309 bytes | ~192-bit |
1238
+ | MLDSA-87 | 2,592 bytes | 4,896 bytes | 4,627 bytes | ~256-bit |
1239
+
1240
+ > **Note:** OPNet currently only supports MLDSA-44 on-chain.
452
1241
 
453
1242
  ## .opnet Binary Format (OIP-0003)
454
1243
 
455
1244
  The `.opnet` binary format consists of:
456
1245
 
457
- 1. **Magic bytes** (8 bytes): `OPNETPLG`
458
- 2. **Format version** (4 bytes): uint32 LE
459
- 3. **MLDSA level** (1 byte): 0=44, 1=65, 2=87
460
- 4. **Public key** (variable): Based on MLDSA level
461
- 5. **Signature** (variable): Based on MLDSA level
462
- 6. **Metadata length** (4 bytes): uint32 LE
463
- 7. **Metadata** (variable): JSON bytes
464
- 8. **Bytecode length** (4 bytes): uint32 LE
465
- 9. **Bytecode** (variable): V8 bytecode
466
- 10. **Proto length** (4 bytes): uint32 LE
467
- 11. **Proto** (variable): Protobuf definitions
468
- 12. **Checksum** (32 bytes): SHA-256 of metadata + bytecode + proto
1246
+ | Section | Size | Description |
1247
+ |---|---|---|
1248
+ | Magic bytes | 8 bytes | `OPNETPLG` |
1249
+ | Format version | 4 bytes | uint32 LE |
1250
+ | MLDSA level | 1 byte | `0`=MLDSA-44, `1`=MLDSA-65, `2`=MLDSA-87 |
1251
+ | Public key | Variable | Size depends on MLDSA level |
1252
+ | Signature | Variable | Size depends on MLDSA level |
1253
+ | Metadata length | 4 bytes | uint32 LE |
1254
+ | Metadata | Variable | JSON-encoded plugin manifest |
1255
+ | Bytecode length | 4 bytes | uint32 LE |
1256
+ | Bytecode | Variable | V8 bytecode (bytenode compiled) |
1257
+ | Proto length | 4 bytes | uint32 LE |
1258
+ | Proto | Variable | Protobuf definitions (optional) |
1259
+ | Checksum | 32 bytes | SHA-256 of metadata + bytecode + proto |
469
1260
 
470
1261
  ## Plugin Manifest (plugin.json)
471
1262
 
1263
+ The `plugin.json` file defines your plugin's metadata, permissions, resource limits, and lifecycle configuration.
1264
+
472
1265
  ```json
473
1266
  {
474
1267
  "name": "my-plugin",
475
1268
  "version": "1.0.0",
476
- "opnetVersion": "^1.0.0",
1269
+ "opnetVersion": ">=0.0.1",
477
1270
  "main": "dist/index.jsc",
478
1271
  "target": "bytenode",
479
1272
  "type": "plugin",
@@ -498,37 +1291,139 @@ The `.opnet` binary format consists of:
498
1291
  "onFinalized": false
499
1292
  },
500
1293
  "mempool": {
501
- "txFeed": false
1294
+ "txFeed": false,
1295
+ "txSubmit": false
502
1296
  },
503
1297
  "api": {
504
1298
  "addEndpoints": false,
505
1299
  "addWebsocket": false
506
1300
  },
1301
+ "threading": {
1302
+ "maxWorkers": 1,
1303
+ "maxMemoryMB": 256
1304
+ },
507
1305
  "filesystem": {
508
1306
  "configDir": false,
509
1307
  "tempDir": false
510
1308
  }
511
1309
  },
512
1310
  "resources": {
513
- "maxMemoryMB": 256,
514
- "maxCpuPercent": 25,
515
- "maxStorageMB": 100
1311
+ "memory": {
1312
+ "maxHeapMB": 256,
1313
+ "maxOldGenMB": 128,
1314
+ "maxYoungGenMB": 64
1315
+ },
1316
+ "cpu": {
1317
+ "maxThreads": 2,
1318
+ "priority": "normal"
1319
+ },
1320
+ "timeout": {
1321
+ "initMs": 30000,
1322
+ "hookMs": 5000,
1323
+ "shutdownMs": 10000
1324
+ }
516
1325
  },
517
- "dependencies": {},
518
1326
  "lifecycle": {
519
- "autoStart": true,
520
- "restartOnCrash": true,
521
- "maxRestarts": 3
522
- }
1327
+ "loadPriority": 100,
1328
+ "enabledByDefault": true,
1329
+ "requiresRestart": false
1330
+ },
1331
+ "dependencies": {}
523
1332
  }
524
1333
  ```
525
1334
 
1335
+ **Permissions reference:**
1336
+
1337
+ | Permission | Description |
1338
+ |---|---|
1339
+ | `database.enabled` | Access to plugin database |
1340
+ | `database.collections` | Allowed collection names |
1341
+ | `blocks.preProcess` | Hook before block processing |
1342
+ | `blocks.postProcess` | Hook after block processing |
1343
+ | `blocks.onChange` | Hook on block changes |
1344
+ | `epochs.onChange` | Hook on epoch changes |
1345
+ | `epochs.onFinalized` | Hook on epoch finalization |
1346
+ | `mempool.txFeed` | Subscribe to mempool transactions |
1347
+ | `mempool.txSubmit` | Submit transactions to mempool |
1348
+ | `api.addEndpoints` | Register custom API endpoints |
1349
+ | `api.addWebsocket` | Register WebSocket handlers |
1350
+ | `threading.maxWorkers` | Maximum worker threads |
1351
+ | `threading.maxMemoryMB` | Maximum memory per worker |
1352
+ | `filesystem.configDir` | Access to config directory |
1353
+ | `filesystem.tempDir` | Access to temp directory |
1354
+
1355
+ ## Workflow Examples
1356
+
1357
+ ### Publish a new plugin
1358
+
1359
+ ```bash
1360
+ # Create project
1361
+ opnet init my-plugin
1362
+ cd my-plugin
1363
+ npm install
1364
+
1365
+ # Develop your plugin
1366
+ # Edit src/index.ts
1367
+
1368
+ # Build and compile
1369
+ npm run build
1370
+ opnet compile
1371
+
1372
+ # Verify
1373
+ opnet verify build/my-plugin.opnet
1374
+
1375
+ # Register scope (if using scoped name)
1376
+ opnet scope:register myscope --network regtest
1377
+
1378
+ # Publish
1379
+ opnet publish --network regtest
1380
+ ```
1381
+
1382
+ ### Register a domain and deploy a website
1383
+
1384
+ ```bash
1385
+ # Register a .btc domain
1386
+ opnet domain register mysite --network regtest
1387
+
1388
+ # Option A: Deploy from a directory (upload + publish in one step)
1389
+ opnet deploy mysite ./dist --network regtest
1390
+
1391
+ # Option B: Manual two-step process
1392
+ # 1. Upload to IPFS separately, get the CID
1393
+ # 2. Set the contenthash
1394
+ opnet website mysite QmXyz... --network regtest
1395
+ ```
1396
+
1397
+ ### Transfer ownership
1398
+
1399
+ ```bash
1400
+ # Current owner initiates transfer
1401
+ opnet transfer @myscope bc1p...newowner
1402
+
1403
+ # New owner accepts
1404
+ opnet accept @myscope
1405
+ ```
1406
+
1407
+ ### CI/CD pipeline
1408
+
1409
+ ```bash
1410
+ export OPNET_MNEMONIC="your mnemonic"
1411
+ export OPNET_NETWORK="mainnet"
1412
+
1413
+ npm run build
1414
+ opnet compile
1415
+ opnet verify build/my-plugin.opnet --json
1416
+ opnet publish --yes
1417
+ ```
1418
+
526
1419
  ## Security
527
1420
 
528
- - Credentials are stored with restricted permissions (0600)
529
- - All binaries are signed with quantum-resistant MLDSA signatures
530
- - Checksums verify binary integrity
1421
+ - Credentials are stored with restricted permissions (`0600` - owner read/write only)
1422
+ - All plugin binaries are signed with quantum-resistant MLDSA signatures
1423
+ - SHA-256 checksums verify binary integrity
531
1424
  - IPFS CIDs provide content-addressed storage
1425
+ - On-chain registry ensures immutable publishing records
1426
+ - 72-hour mutability window for deprecation/undeprecation after publishing
532
1427
 
533
1428
  ## License
534
1429
 
@@ -539,3 +1434,4 @@ Apache-2.0
539
1434
  - [OPNet Documentation](https://docs.opnet.org)
540
1435
  - [Plugin SDK](https://github.com/btc-vision/plugin-sdk)
541
1436
  - [OPNet Node](https://github.com/btc-vision/opnet-node)
1437
+ - [Report Issues](https://github.com/btc-vision/opnet-cli/issues)