@btc-vision/cli 1.0.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/.gitattributes +2 -0
- package/.github/dependabot.yml +9 -0
- package/.github/workflows/ci.yml +48 -0
- package/.prettierrc.json +12 -0
- package/CONTRIBUTING.md +56 -0
- package/LICENSE +190 -0
- package/NOTICE +17 -0
- package/README.md +509 -0
- package/SECURITY.md +35 -0
- package/build/commands/AcceptCommand.d.ts +7 -0
- package/build/commands/AcceptCommand.js +110 -0
- package/build/commands/BaseCommand.d.ts +12 -0
- package/build/commands/BaseCommand.js +27 -0
- package/build/commands/CompileCommand.d.ts +7 -0
- package/build/commands/CompileCommand.js +138 -0
- package/build/commands/ConfigCommand.d.ts +17 -0
- package/build/commands/ConfigCommand.js +124 -0
- package/build/commands/DeprecateCommand.d.ts +7 -0
- package/build/commands/DeprecateCommand.js +112 -0
- package/build/commands/InfoCommand.d.ts +10 -0
- package/build/commands/InfoCommand.js +223 -0
- package/build/commands/InitCommand.d.ts +16 -0
- package/build/commands/InitCommand.js +336 -0
- package/build/commands/InstallCommand.d.ts +7 -0
- package/build/commands/InstallCommand.js +130 -0
- package/build/commands/KeygenCommand.d.ts +13 -0
- package/build/commands/KeygenCommand.js +133 -0
- package/build/commands/ListCommand.d.ts +7 -0
- package/build/commands/ListCommand.js +117 -0
- package/build/commands/LoginCommand.d.ts +9 -0
- package/build/commands/LoginCommand.js +139 -0
- package/build/commands/LogoutCommand.d.ts +7 -0
- package/build/commands/LogoutCommand.js +57 -0
- package/build/commands/PublishCommand.d.ts +7 -0
- package/build/commands/PublishCommand.js +163 -0
- package/build/commands/SearchCommand.d.ts +7 -0
- package/build/commands/SearchCommand.js +97 -0
- package/build/commands/SignCommand.d.ts +7 -0
- package/build/commands/SignCommand.js +80 -0
- package/build/commands/TransferCommand.d.ts +8 -0
- package/build/commands/TransferCommand.js +179 -0
- package/build/commands/UndeprecateCommand.d.ts +7 -0
- package/build/commands/UndeprecateCommand.js +95 -0
- package/build/commands/UpdateCommand.d.ts +7 -0
- package/build/commands/UpdateCommand.js +130 -0
- package/build/commands/VerifyCommand.d.ts +7 -0
- package/build/commands/VerifyCommand.js +167 -0
- package/build/commands/WhoamiCommand.d.ts +7 -0
- package/build/commands/WhoamiCommand.js +84 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +64 -0
- package/build/lib/PackageRegistry.abi.d.ts +2 -0
- package/build/lib/PackageRegistry.abi.js +356 -0
- package/build/lib/binary.d.ts +16 -0
- package/build/lib/binary.js +165 -0
- package/build/lib/config.d.ts +11 -0
- package/build/lib/config.js +160 -0
- package/build/lib/credentials.d.ts +10 -0
- package/build/lib/credentials.js +89 -0
- package/build/lib/ipfs.d.ts +16 -0
- package/build/lib/ipfs.js +209 -0
- package/build/lib/manifest.d.ts +14 -0
- package/build/lib/manifest.js +88 -0
- package/build/lib/provider.d.ts +9 -0
- package/build/lib/provider.js +48 -0
- package/build/lib/registry.d.ts +58 -0
- package/build/lib/registry.js +197 -0
- package/build/lib/wallet.d.ts +32 -0
- package/build/lib/wallet.js +114 -0
- package/build/types/PackageRegistry.d.ts +177 -0
- package/build/types/PackageRegistry.js +1 -0
- package/build/types/index.d.ts +30 -0
- package/build/types/index.js +52 -0
- package/eslint.config.js +41 -0
- package/gulpfile.js +41 -0
- package/package.json +83 -0
- package/src/commands/AcceptCommand.ts +151 -0
- package/src/commands/BaseCommand.ts +59 -0
- package/src/commands/CompileCommand.ts +196 -0
- package/src/commands/ConfigCommand.ts +144 -0
- package/src/commands/DeprecateCommand.ts +156 -0
- package/src/commands/InfoCommand.ts +293 -0
- package/src/commands/InitCommand.ts +465 -0
- package/src/commands/InstallCommand.ts +179 -0
- package/src/commands/KeygenCommand.ts +157 -0
- package/src/commands/ListCommand.ts +169 -0
- package/src/commands/LoginCommand.ts +197 -0
- package/src/commands/LogoutCommand.ts +76 -0
- package/src/commands/PublishCommand.ts +230 -0
- package/src/commands/SearchCommand.ts +141 -0
- package/src/commands/SignCommand.ts +122 -0
- package/src/commands/TransferCommand.ts +235 -0
- package/src/commands/UndeprecateCommand.ts +134 -0
- package/src/commands/UpdateCommand.ts +200 -0
- package/src/commands/VerifyCommand.ts +228 -0
- package/src/commands/WhoamiCommand.ts +113 -0
- package/src/index.ts +86 -0
- package/src/lib/PackageRegistry.abi.json +765 -0
- package/src/lib/PackageRegistry.abi.ts +365 -0
- package/src/lib/binary.ts +336 -0
- package/src/lib/config.ts +265 -0
- package/src/lib/credentials.ts +176 -0
- package/src/lib/ipfs.ts +369 -0
- package/src/lib/manifest.ts +172 -0
- package/src/lib/provider.ts +121 -0
- package/src/lib/registry.ts +464 -0
- package/src/lib/wallet.ts +271 -0
- package/src/types/PackageRegistry.ts +344 -0
- package/src/types/index.ts +145 -0
- package/tsconfig.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
# @btc-vision/cli
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
[](https://github.com/prettier/prettier)
|
|
12
|
+
|
|
13
|
+
Official command-line interface for the OPNet plugin ecosystem. Build, sign, verify, and publish plugins with quantum-resistant MLDSA signatures.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @btc-vision/cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or use npx:
|
|
22
|
+
```bash
|
|
23
|
+
npx @btc-vision/cli <command>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Initialize a new plugin project
|
|
30
|
+
opnet init my-plugin
|
|
31
|
+
|
|
32
|
+
# Build and compile to .opnet binary
|
|
33
|
+
cd my-plugin
|
|
34
|
+
npm install
|
|
35
|
+
npm run build
|
|
36
|
+
opnet compile
|
|
37
|
+
|
|
38
|
+
# Verify the compiled binary
|
|
39
|
+
opnet verify build/my-plugin.opnet
|
|
40
|
+
|
|
41
|
+
# Configure your wallet for signing
|
|
42
|
+
opnet login
|
|
43
|
+
|
|
44
|
+
# Publish to the registry
|
|
45
|
+
opnet publish
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
### Configuration
|
|
51
|
+
|
|
52
|
+
#### `opnet config`
|
|
53
|
+
|
|
54
|
+
Manage CLI configuration.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Show all configuration
|
|
58
|
+
opnet config list
|
|
59
|
+
|
|
60
|
+
# Get a specific value
|
|
61
|
+
opnet config get defaultNetwork
|
|
62
|
+
opnet config get rpcUrls.mainnet
|
|
63
|
+
|
|
64
|
+
# Set a value
|
|
65
|
+
opnet config set defaultNetwork testnet
|
|
66
|
+
opnet config set ipfsPinningApiKey "your-api-key"
|
|
67
|
+
|
|
68
|
+
# Reset to defaults
|
|
69
|
+
opnet config reset --yes
|
|
70
|
+
|
|
71
|
+
# Show config file path
|
|
72
|
+
opnet config path
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Authentication
|
|
76
|
+
|
|
77
|
+
#### `opnet login`
|
|
78
|
+
|
|
79
|
+
Configure wallet credentials for signing and publishing.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Interactive mode
|
|
83
|
+
opnet login
|
|
84
|
+
|
|
85
|
+
# With mnemonic phrase
|
|
86
|
+
opnet login --mnemonic "your 24 word phrase..."
|
|
87
|
+
|
|
88
|
+
# With specific network and MLDSA level
|
|
89
|
+
opnet login --network testnet --mldsa-level 65
|
|
90
|
+
|
|
91
|
+
# Advanced: WIF + standalone MLDSA key
|
|
92
|
+
opnet login --wif "KwDiBf..." --mldsa "hex-key..."
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Options:**
|
|
96
|
+
- `-m, --mnemonic <phrase>` - BIP-39 mnemonic phrase (24 words)
|
|
97
|
+
- `--wif <key>` - Bitcoin WIF private key (advanced)
|
|
98
|
+
- `--mldsa <key>` - MLDSA private key hex (advanced, requires --wif)
|
|
99
|
+
- `-l, --mldsa-level <level>` - MLDSA security level (44, 65, 87) [default: 44]
|
|
100
|
+
- `-n, --network <network>` - Network (mainnet, testnet, regtest) [default: mainnet]
|
|
101
|
+
- `-y, --yes` - Skip confirmation prompts
|
|
102
|
+
|
|
103
|
+
#### `opnet logout`
|
|
104
|
+
|
|
105
|
+
Remove stored wallet credentials.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
opnet logout
|
|
109
|
+
opnet logout --yes
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### `opnet whoami`
|
|
113
|
+
|
|
114
|
+
Display current wallet identity and configuration.
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
opnet whoami
|
|
118
|
+
opnet whoami --verbose
|
|
119
|
+
opnet whoami --public-key
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Key Generation
|
|
123
|
+
|
|
124
|
+
#### `opnet keygen`
|
|
125
|
+
|
|
126
|
+
Generate cryptographic keys.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Generate a new mnemonic phrase
|
|
130
|
+
opnet keygen mnemonic
|
|
131
|
+
opnet keygen mnemonic --output my-mnemonic.txt
|
|
132
|
+
|
|
133
|
+
# Generate standalone MLDSA keypair
|
|
134
|
+
opnet keygen mldsa
|
|
135
|
+
opnet keygen mldsa --level 65
|
|
136
|
+
opnet keygen mldsa --output my-key --json
|
|
137
|
+
|
|
138
|
+
# Show MLDSA key size information
|
|
139
|
+
opnet keygen info
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Plugin Development
|
|
143
|
+
|
|
144
|
+
#### `opnet init`
|
|
145
|
+
|
|
146
|
+
Initialize a new OPNet plugin project.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Interactive mode
|
|
150
|
+
opnet init
|
|
151
|
+
|
|
152
|
+
# With name
|
|
153
|
+
opnet init my-plugin
|
|
154
|
+
|
|
155
|
+
# With options
|
|
156
|
+
opnet init my-plugin --template library --yes
|
|
157
|
+
|
|
158
|
+
# Force overwrite
|
|
159
|
+
opnet init --force
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Options:**
|
|
163
|
+
- `-t, --template <type>` - Template type (standalone, library) [default: standalone]
|
|
164
|
+
- `-y, --yes` - Skip prompts and use defaults
|
|
165
|
+
- `--force` - Overwrite existing files
|
|
166
|
+
|
|
167
|
+
#### `opnet compile`
|
|
168
|
+
|
|
169
|
+
Compile plugin to .opnet binary format.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Compile current directory
|
|
173
|
+
opnet compile
|
|
174
|
+
|
|
175
|
+
# Compile specific directory
|
|
176
|
+
opnet compile --dir ./my-plugin
|
|
177
|
+
|
|
178
|
+
# Custom output path
|
|
179
|
+
opnet compile --output ./dist/plugin.opnet
|
|
180
|
+
|
|
181
|
+
# Skip signing (for testing)
|
|
182
|
+
opnet compile --no-sign
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Options:**
|
|
186
|
+
- `-o, --output <path>` - Output file path
|
|
187
|
+
- `-d, --dir <path>` - Plugin directory [default: current]
|
|
188
|
+
- `--no-sign` - Skip signing (produce unsigned binary)
|
|
189
|
+
- `--minify` - Minify the bundled code [default: true]
|
|
190
|
+
- `--sourcemap` - Generate source maps
|
|
191
|
+
|
|
192
|
+
#### `opnet verify`
|
|
193
|
+
|
|
194
|
+
Verify a .opnet binary signature and integrity.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
opnet verify plugin.opnet
|
|
198
|
+
opnet verify plugin.opnet --verbose
|
|
199
|
+
opnet verify plugin.opnet --json
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Options:**
|
|
203
|
+
- `-v, --verbose` - Show detailed information
|
|
204
|
+
- `--json` - Output as JSON
|
|
205
|
+
|
|
206
|
+
#### `opnet info`
|
|
207
|
+
|
|
208
|
+
Display information about a plugin or .opnet file.
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
# Show project info
|
|
212
|
+
opnet info
|
|
213
|
+
|
|
214
|
+
# Show binary info
|
|
215
|
+
opnet info plugin.opnet
|
|
216
|
+
|
|
217
|
+
# JSON output
|
|
218
|
+
opnet info --json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `opnet sign`
|
|
222
|
+
|
|
223
|
+
Sign or re-sign a .opnet binary with your MLDSA key.
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
opnet sign plugin.opnet
|
|
227
|
+
opnet sign plugin.opnet --output signed.opnet
|
|
228
|
+
opnet sign plugin.opnet --force # Re-sign with different key
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Options:**
|
|
232
|
+
- `-o, --output <path>` - Output file path [default: overwrites input]
|
|
233
|
+
- `--force` - Force re-signing even if already signed by different key
|
|
234
|
+
|
|
235
|
+
### Registry Commands
|
|
236
|
+
|
|
237
|
+
#### `opnet publish`
|
|
238
|
+
|
|
239
|
+
Publish a plugin to the OPNet registry.
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
# Publish from current directory
|
|
243
|
+
opnet publish
|
|
244
|
+
|
|
245
|
+
# Publish specific file
|
|
246
|
+
opnet publish plugin.opnet
|
|
247
|
+
|
|
248
|
+
# Dry run
|
|
249
|
+
opnet publish --dry-run
|
|
250
|
+
|
|
251
|
+
# Specific network
|
|
252
|
+
opnet publish --network testnet
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Options:**
|
|
256
|
+
- `-n, --network <network>` - Network to publish to [default: mainnet]
|
|
257
|
+
- `--dry-run` - Show what would be published without publishing
|
|
258
|
+
- `-y, --yes` - Skip confirmation prompts
|
|
259
|
+
|
|
260
|
+
#### `opnet deprecate`
|
|
261
|
+
|
|
262
|
+
Mark a package version as deprecated.
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
opnet deprecate @scope/plugin
|
|
266
|
+
opnet deprecate @scope/plugin 1.0.0
|
|
267
|
+
opnet deprecate @scope/plugin 1.0.0 --message "Security vulnerability"
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Options:**
|
|
271
|
+
- `-m, --message <message>` - Deprecation reason/message
|
|
272
|
+
- `-n, --network <network>` - Network [default: mainnet]
|
|
273
|
+
- `-y, --yes` - Skip confirmation
|
|
274
|
+
|
|
275
|
+
#### `opnet undeprecate`
|
|
276
|
+
|
|
277
|
+
Remove deprecation from a package version.
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
opnet undeprecate @scope/plugin 1.0.0
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### `opnet transfer`
|
|
284
|
+
|
|
285
|
+
Initiate ownership transfer of a package or scope.
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Transfer a package
|
|
289
|
+
opnet transfer my-plugin bc1q...
|
|
290
|
+
|
|
291
|
+
# Transfer a scope
|
|
292
|
+
opnet transfer @myscope bc1q...
|
|
293
|
+
|
|
294
|
+
# Cancel pending transfer
|
|
295
|
+
opnet transfer my-plugin --cancel
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Options:**
|
|
299
|
+
- `-n, --network <network>` - Network [default: mainnet]
|
|
300
|
+
- `-y, --yes` - Skip confirmation
|
|
301
|
+
- `--cancel` - Cancel pending transfer
|
|
302
|
+
|
|
303
|
+
#### `opnet accept`
|
|
304
|
+
|
|
305
|
+
Accept pending ownership transfer.
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
opnet accept my-plugin
|
|
309
|
+
opnet accept @myscope
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### `opnet install`
|
|
313
|
+
|
|
314
|
+
Download and verify a plugin from the registry.
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Install latest version
|
|
318
|
+
opnet install @scope/plugin
|
|
319
|
+
|
|
320
|
+
# Install specific version
|
|
321
|
+
opnet install @scope/plugin@1.0.0
|
|
322
|
+
|
|
323
|
+
# Install from IPFS CID
|
|
324
|
+
opnet install QmXyz...
|
|
325
|
+
|
|
326
|
+
# Custom output directory
|
|
327
|
+
opnet install @scope/plugin --output ./my-plugins
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Options:**
|
|
331
|
+
- `-o, --output <path>` - Output directory [default: ./plugins/]
|
|
332
|
+
- `-n, --network <network>` - Network [default: mainnet]
|
|
333
|
+
- `--skip-verify` - Skip signature verification
|
|
334
|
+
|
|
335
|
+
#### `opnet update`
|
|
336
|
+
|
|
337
|
+
Update installed plugins to latest versions.
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# Update all plugins
|
|
341
|
+
opnet update
|
|
342
|
+
|
|
343
|
+
# Update specific plugin
|
|
344
|
+
opnet update @scope/plugin
|
|
345
|
+
|
|
346
|
+
# Custom plugins directory
|
|
347
|
+
opnet update --dir ./my-plugins
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**Options:**
|
|
351
|
+
- `-d, --dir <path>` - Plugins directory [default: ./plugins/]
|
|
352
|
+
- `-n, --network <network>` - Network [default: mainnet]
|
|
353
|
+
- `--skip-verify` - Skip signature verification
|
|
354
|
+
|
|
355
|
+
#### `opnet list`
|
|
356
|
+
|
|
357
|
+
List installed plugins.
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
opnet list
|
|
361
|
+
opnet ls
|
|
362
|
+
opnet list --verbose
|
|
363
|
+
opnet list --json
|
|
364
|
+
opnet list --dir ./my-plugins
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
**Options:**
|
|
368
|
+
- `-d, --dir <path>` - Plugins directory [default: ./plugins/]
|
|
369
|
+
- `--json` - Output as JSON
|
|
370
|
+
- `-v, --verbose` - Show detailed information
|
|
371
|
+
|
|
372
|
+
#### `opnet search`
|
|
373
|
+
|
|
374
|
+
Search for plugins in the registry.
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
opnet search plugin-name
|
|
378
|
+
opnet search @scope/plugin
|
|
379
|
+
opnet search plugin-name --json
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
**Options:**
|
|
383
|
+
- `-n, --network <network>` - Network [default: mainnet]
|
|
384
|
+
- `--json` - Output as JSON
|
|
385
|
+
|
|
386
|
+
## Configuration
|
|
387
|
+
|
|
388
|
+
Configuration is stored in `~/.opnet/config.json`:
|
|
389
|
+
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"defaultNetwork": "mainnet",
|
|
393
|
+
"rpcUrls": {
|
|
394
|
+
"mainnet": "https://api.opnet.org",
|
|
395
|
+
"testnet": "https://testnet.opnet.org",
|
|
396
|
+
"regtest": "http://localhost:9001"
|
|
397
|
+
},
|
|
398
|
+
"ipfsGateway": "https://ipfs.opnet.org/ipfs/",
|
|
399
|
+
"ipfsGateways": [
|
|
400
|
+
"https://ipfs.opnet.org/ipfs/",
|
|
401
|
+
"https://ipfs.io/ipfs/"
|
|
402
|
+
],
|
|
403
|
+
"ipfsPinningEndpoint": "https://ipfs.opnet.org/api/v0/add",
|
|
404
|
+
"ipfsPinningApiKey": "",
|
|
405
|
+
"registryAddresses": {
|
|
406
|
+
"mainnet": "",
|
|
407
|
+
"testnet": "",
|
|
408
|
+
"regtest": ""
|
|
409
|
+
},
|
|
410
|
+
"defaultMldsaLevel": 44,
|
|
411
|
+
"indexerUrl": "https://indexer.opnet.org"
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Environment Variables
|
|
416
|
+
|
|
417
|
+
| Variable | Description |
|
|
418
|
+
|----------|-------------|
|
|
419
|
+
| `OPNET_MNEMONIC` | BIP-39 mnemonic phrase |
|
|
420
|
+
| `OPNET_PRIVATE_KEY` | Bitcoin WIF private key |
|
|
421
|
+
| `OPNET_MLDSA_KEY` | MLDSA private key (hex) |
|
|
422
|
+
| `OPNET_MLDSA_LEVEL` | MLDSA security level (44, 65, 87) |
|
|
423
|
+
| `OPNET_NETWORK` | Network (mainnet, testnet, regtest) |
|
|
424
|
+
| `OPNET_RPC_URL` | RPC endpoint URL |
|
|
425
|
+
| `OPNET_IPFS_GATEWAY` | IPFS gateway URL |
|
|
426
|
+
| `OPNET_IPFS_PINNING_ENDPOINT` | IPFS pinning service endpoint |
|
|
427
|
+
| `OPNET_IPFS_PINNING_KEY` | IPFS pinning API key |
|
|
428
|
+
| `OPNET_REGISTRY_ADDRESS` | Registry contract address |
|
|
429
|
+
| `OPNET_INDEXER_URL` | Indexer API URL |
|
|
430
|
+
|
|
431
|
+
## MLDSA Security Levels
|
|
432
|
+
|
|
433
|
+
| Level | Public Key | Signature | Security |
|
|
434
|
+
|-------|------------|-----------|----------|
|
|
435
|
+
| MLDSA-44 | 1,312 bytes | 2,420 bytes | ~128-bit |
|
|
436
|
+
| MLDSA-65 | 1,952 bytes | 3,309 bytes | ~192-bit |
|
|
437
|
+
| MLDSA-87 | 2,592 bytes | 4,627 bytes | ~256-bit |
|
|
438
|
+
|
|
439
|
+
## .opnet Binary Format (OIP-0003)
|
|
440
|
+
|
|
441
|
+
The `.opnet` binary format consists of:
|
|
442
|
+
|
|
443
|
+
1. **Magic bytes** (8 bytes): `OPNETPLG`
|
|
444
|
+
2. **Format version** (4 bytes): uint32 LE
|
|
445
|
+
3. **MLDSA level** (1 byte): 0=44, 1=65, 2=87
|
|
446
|
+
4. **Public key** (variable): Based on MLDSA level
|
|
447
|
+
5. **Signature** (variable): Based on MLDSA level
|
|
448
|
+
6. **Metadata length** (4 bytes): uint32 LE
|
|
449
|
+
7. **Metadata** (variable): JSON bytes
|
|
450
|
+
8. **Bytecode length** (4 bytes): uint32 LE
|
|
451
|
+
9. **Bytecode** (variable): V8 bytecode
|
|
452
|
+
10. **Proto length** (4 bytes): uint32 LE
|
|
453
|
+
11. **Proto** (variable): Protobuf definitions
|
|
454
|
+
12. **Checksum** (32 bytes): SHA-256 of metadata + bytecode + proto
|
|
455
|
+
|
|
456
|
+
## Plugin Manifest (plugin.json)
|
|
457
|
+
|
|
458
|
+
```json
|
|
459
|
+
{
|
|
460
|
+
"name": "my-plugin",
|
|
461
|
+
"version": "1.0.0",
|
|
462
|
+
"opnetVersion": "^1.0.0",
|
|
463
|
+
"main": "dist/index.jsc",
|
|
464
|
+
"target": "bytenode",
|
|
465
|
+
"type": "plugin",
|
|
466
|
+
"author": {
|
|
467
|
+
"name": "Developer Name",
|
|
468
|
+
"email": "dev@example.com"
|
|
469
|
+
},
|
|
470
|
+
"description": "My OPNet plugin",
|
|
471
|
+
"pluginType": "standalone",
|
|
472
|
+
"permissions": {
|
|
473
|
+
"database": { "enabled": false, "collections": [] },
|
|
474
|
+
"blocks": { "preProcess": false, "postProcess": false, "onChange": false },
|
|
475
|
+
"epochs": { "onChange": false, "onFinalized": false },
|
|
476
|
+
"mempool": { "txFeed": false },
|
|
477
|
+
"api": { "addEndpoints": false, "addWebsocket": false },
|
|
478
|
+
"filesystem": { "configDir": false, "tempDir": false }
|
|
479
|
+
},
|
|
480
|
+
"resources": {
|
|
481
|
+
"maxMemoryMB": 256,
|
|
482
|
+
"maxCpuPercent": 25,
|
|
483
|
+
"maxStorageMB": 100
|
|
484
|
+
},
|
|
485
|
+
"dependencies": {},
|
|
486
|
+
"lifecycle": {
|
|
487
|
+
"autoStart": true,
|
|
488
|
+
"restartOnCrash": true,
|
|
489
|
+
"maxRestarts": 3
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
## Security
|
|
495
|
+
|
|
496
|
+
- Credentials are stored with restricted permissions (0600)
|
|
497
|
+
- All binaries are signed with quantum-resistant MLDSA signatures
|
|
498
|
+
- Checksums verify binary integrity
|
|
499
|
+
- IPFS CIDs provide content-addressed storage
|
|
500
|
+
|
|
501
|
+
## License
|
|
502
|
+
|
|
503
|
+
Apache-2.0
|
|
504
|
+
|
|
505
|
+
## Links
|
|
506
|
+
|
|
507
|
+
- [OPNet Documentation](https://docs.opnet.org)
|
|
508
|
+
- [Plugin SDK](https://github.com/btc-vision/plugin-sdk)
|
|
509
|
+
- [OPNet Node](https://github.com/btc-vision/opnet-node)
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
Use this section to tell people about which versions of your project are
|
|
6
|
+
currently being supported with security updates.
|
|
7
|
+
|
|
8
|
+
| Version | Supported |
|
|
9
|
+
|---------|--------------------|
|
|
10
|
+
| 1.0.x | :white_check_mark: |
|
|
11
|
+
|
|
12
|
+
## Reporting a Vulnerability
|
|
13
|
+
|
|
14
|
+
To report a security vulnerability, please email [anakun@opnet.org](mailto:anakun@opnet.org).
|
|
15
|
+
|
|
16
|
+
Please include the following information in your report:
|
|
17
|
+
|
|
18
|
+
- Description of the vulnerability
|
|
19
|
+
- Steps to reproduce the vulnerability
|
|
20
|
+
- Suggested mitigation or remediation steps
|
|
21
|
+
- Your name and contact information
|
|
22
|
+
- Your company or organization name (if applicable)
|
|
23
|
+
- Your preferred method of contact
|
|
24
|
+
- Any other relevant information
|
|
25
|
+
- Attach any supporting documents, screenshots, or other files that may help us understand the issue
|
|
26
|
+
|
|
27
|
+
## Security Best Practices
|
|
28
|
+
|
|
29
|
+
When using the OPNet CLI:
|
|
30
|
+
|
|
31
|
+
1. **Protect your mnemonic**: Never share your BIP-39 mnemonic phrase. Store it securely offline.
|
|
32
|
+
2. **Use secure networks**: Avoid using public Wi-Fi when performing sensitive operations.
|
|
33
|
+
3. **Verify downloads**: Always verify plugin signatures before installing.
|
|
34
|
+
4. **Keep credentials secure**: The CLI stores credentials in `~/.opnet/credentials.json` with restricted permissions (0600).
|
|
35
|
+
5. **Use testnet first**: Test your plugins on testnet before deploying to mainnet.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { confirm } from '@inquirer/prompts';
|
|
2
|
+
import { BaseCommand } from './BaseCommand.js';
|
|
3
|
+
import { getPendingTransfer, getPendingScopeTransfer } from '../lib/registry.js';
|
|
4
|
+
import { loadCredentials, canSign } from '../lib/credentials.js';
|
|
5
|
+
import { CLIWallet } from '../lib/wallet.js';
|
|
6
|
+
export class AcceptCommand extends BaseCommand {
|
|
7
|
+
constructor() {
|
|
8
|
+
super('accept', 'Accept pending ownership transfer');
|
|
9
|
+
}
|
|
10
|
+
configure() {
|
|
11
|
+
this.command
|
|
12
|
+
.argument('<name>', 'Package name or @scope')
|
|
13
|
+
.option('-n, --network <network>', 'Network', 'mainnet')
|
|
14
|
+
.option('-y, --yes', 'Skip confirmation')
|
|
15
|
+
.action((name, options) => this.execute(name, options || { network: 'mainnet' }));
|
|
16
|
+
}
|
|
17
|
+
async execute(name, options) {
|
|
18
|
+
try {
|
|
19
|
+
this.logger.info('Loading wallet...');
|
|
20
|
+
const credentials = loadCredentials();
|
|
21
|
+
if (!credentials || !canSign(credentials)) {
|
|
22
|
+
this.logger.fail('No credentials configured');
|
|
23
|
+
this.logger.warn('Run `opnet login` to configure your wallet.');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
CLIWallet.fromCredentials(credentials);
|
|
27
|
+
this.logger.success('Wallet loaded');
|
|
28
|
+
const network = (options?.network || 'mainnet');
|
|
29
|
+
const isScope = name.startsWith('@') && !name.includes('/');
|
|
30
|
+
this.logger.info('Checking pending transfer...');
|
|
31
|
+
if (isScope) {
|
|
32
|
+
const scopeName = name.substring(1);
|
|
33
|
+
const pending = await getPendingScopeTransfer(scopeName, network);
|
|
34
|
+
if (!pending) {
|
|
35
|
+
this.logger.warn('No pending transfer');
|
|
36
|
+
this.logger.log(`No pending transfer for ${name}.`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.logger.success('Found pending transfer');
|
|
40
|
+
this.logger.log('');
|
|
41
|
+
this.logger.info('Accept Transfer');
|
|
42
|
+
this.logger.log('─'.repeat(50));
|
|
43
|
+
this.logger.log(`Type: Scope`);
|
|
44
|
+
this.logger.log(`Name: ${name}`);
|
|
45
|
+
this.logger.log(`Network: ${options?.network}`);
|
|
46
|
+
this.logger.log('');
|
|
47
|
+
if (!options?.yes) {
|
|
48
|
+
const confirmed = await confirm({
|
|
49
|
+
message: `Accept ownership of ${name}?`,
|
|
50
|
+
default: true,
|
|
51
|
+
});
|
|
52
|
+
if (!confirmed) {
|
|
53
|
+
this.logger.warn('Transfer acceptance cancelled.');
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.logger.info('Accepting transfer...');
|
|
58
|
+
this.logger.warn('Acceptance transaction required.');
|
|
59
|
+
this.logger.log('Transaction would call: acceptScopeTransfer(');
|
|
60
|
+
this.logger.log(` scopeName: "${scopeName}"`);
|
|
61
|
+
this.logger.log(')');
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const pending = await getPendingTransfer(name, network);
|
|
65
|
+
if (!pending) {
|
|
66
|
+
this.logger.warn('No pending transfer');
|
|
67
|
+
this.logger.log(`No pending transfer for ${name}.`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.logger.success('Found pending transfer');
|
|
71
|
+
this.logger.log('');
|
|
72
|
+
this.logger.info('Accept Transfer');
|
|
73
|
+
this.logger.log('─'.repeat(50));
|
|
74
|
+
this.logger.log(`Type: Package`);
|
|
75
|
+
this.logger.log(`Name: ${name}`);
|
|
76
|
+
this.logger.log(`Network: ${options?.network}`);
|
|
77
|
+
this.logger.log('');
|
|
78
|
+
if (!options?.yes) {
|
|
79
|
+
const confirmed = await confirm({
|
|
80
|
+
message: `Accept ownership of ${name}?`,
|
|
81
|
+
default: true,
|
|
82
|
+
});
|
|
83
|
+
if (!confirmed) {
|
|
84
|
+
this.logger.warn('Transfer acceptance cancelled.');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
this.logger.info('Accepting transfer...');
|
|
89
|
+
this.logger.warn('Acceptance transaction required.');
|
|
90
|
+
this.logger.log('Transaction would call: acceptTransfer(');
|
|
91
|
+
this.logger.log(` packageName: "${name}"`);
|
|
92
|
+
this.logger.log(')');
|
|
93
|
+
}
|
|
94
|
+
this.logger.info('Acceptance (transaction pending)');
|
|
95
|
+
this.logger.log('');
|
|
96
|
+
this.logger.success('Transfer acceptance submitted!');
|
|
97
|
+
this.logger.warn('Note: Registry transaction support is coming soon.');
|
|
98
|
+
this.logger.log('');
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
this.logger.fail('Acceptance failed');
|
|
102
|
+
if (this.isUserCancelled(error)) {
|
|
103
|
+
this.logger.warn('Acceptance cancelled.');
|
|
104
|
+
process.exit(0);
|
|
105
|
+
}
|
|
106
|
+
this.exitWithError(this.formatError(error));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export const acceptCommand = new AcceptCommand().getCommand();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Logger } from '@btc-vision/logger';
|
|
3
|
+
export declare abstract class BaseCommand {
|
|
4
|
+
protected readonly logger: Logger;
|
|
5
|
+
protected readonly command: Command;
|
|
6
|
+
constructor(name: string, description: string);
|
|
7
|
+
getCommand(): Command;
|
|
8
|
+
protected abstract configure(): void;
|
|
9
|
+
protected formatError(error: unknown): string;
|
|
10
|
+
protected exitWithError(message: string, code?: number): never;
|
|
11
|
+
protected isUserCancelled(error: unknown): boolean;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { Logger } from '@btc-vision/logger';
|
|
3
|
+
export class BaseCommand {
|
|
4
|
+
logger;
|
|
5
|
+
command;
|
|
6
|
+
constructor(name, description) {
|
|
7
|
+
this.logger = new Logger();
|
|
8
|
+
this.command = new Command(name).description(description);
|
|
9
|
+
this.configure();
|
|
10
|
+
}
|
|
11
|
+
getCommand() {
|
|
12
|
+
return this.command;
|
|
13
|
+
}
|
|
14
|
+
formatError(error) {
|
|
15
|
+
if (error instanceof Error) {
|
|
16
|
+
return error.message;
|
|
17
|
+
}
|
|
18
|
+
return String(error);
|
|
19
|
+
}
|
|
20
|
+
exitWithError(message, code = 1) {
|
|
21
|
+
this.logger.error(message);
|
|
22
|
+
process.exit(code);
|
|
23
|
+
}
|
|
24
|
+
isUserCancelled(error) {
|
|
25
|
+
return error instanceof Error && error.message.includes('User force closed');
|
|
26
|
+
}
|
|
27
|
+
}
|