@btc-vision/cli 1.0.0 → 1.0.2
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/build/commands/AcceptCommand.js +2 -2
- package/build/commands/CompileCommand.js +11 -12
- package/build/commands/ConfigCommand.js +3 -7
- package/build/commands/DeprecateCommand.js +2 -2
- package/build/commands/InfoCommand.js +2 -2
- package/build/commands/InitCommand.d.ts +2 -0
- package/build/commands/InitCommand.js +114 -20
- package/build/commands/InstallCommand.js +1 -1
- package/build/commands/KeygenCommand.js +1 -1
- package/build/commands/ListCommand.js +6 -2
- package/build/commands/LoginCommand.js +22 -10
- package/build/commands/LogoutCommand.js +1 -1
- package/build/commands/PublishCommand.js +3 -3
- package/build/commands/SearchCommand.js +1 -1
- package/build/commands/SignCommand.js +11 -11
- package/build/commands/TransferCommand.js +3 -3
- package/build/commands/UndeprecateCommand.js +1 -1
- package/build/commands/VerifyCommand.js +5 -2
- package/build/commands/WhoamiCommand.js +1 -1
- package/build/lib/PackageRegistry.abi.js +1 -1
- package/build/lib/binary.d.ts +5 -2
- package/build/lib/binary.js +18 -10
- package/build/lib/config.d.ts +1 -1
- package/build/lib/credentials.d.ts +1 -1
- package/build/lib/ipfs.js +3 -2
- package/build/lib/manifest.d.ts +1 -1
- package/build/lib/manifest.js +23 -12
- package/build/lib/provider.js +1 -1
- package/build/lib/registry.d.ts +1 -1
- package/build/lib/wallet.d.ts +5 -5
- package/build/lib/wallet.js +31 -31
- package/build/types/PackageRegistry.d.ts +1 -1
- package/build/types/index.js +1 -1
- package/package.json +3 -3
- package/src/commands/CompileCommand.ts +13 -14
- package/src/commands/InitCommand.ts +87 -5
- package/src/commands/SignCommand.ts +9 -21
- package/src/lib/binary.ts +24 -22
- package/src/lib/config.ts +3 -4
- package/src/lib/ipfs.ts +0 -1
- package/src/lib/manifest.ts +31 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { getPendingScopeTransfer, getPendingTransfer } from '../lib/registry.js';
|
|
4
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
6
|
export class AcceptCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -3,10 +3,10 @@ import * as path from 'path';
|
|
|
3
3
|
import * as esbuild from 'esbuild';
|
|
4
4
|
import bytenode from 'bytenode';
|
|
5
5
|
import { BaseCommand } from './BaseCommand.js';
|
|
6
|
-
import {
|
|
7
|
-
import { buildOpnetBinary, formatFileSize
|
|
6
|
+
import { getManifestPath, loadManifest } from '../lib/manifest.js';
|
|
7
|
+
import { buildOpnetBinary, formatFileSize } from '../lib/binary.js';
|
|
8
8
|
import { CLIWallet } from '../lib/wallet.js';
|
|
9
|
-
import {
|
|
9
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
10
10
|
export class CompileCommand extends BaseCommand {
|
|
11
11
|
constructor() {
|
|
12
12
|
super('compile', 'Compile plugin to .opnet binary format');
|
|
@@ -70,8 +70,8 @@ export class CompileCommand extends BaseCommand {
|
|
|
70
70
|
this.logger.info(`Found proto file (${formatFileSize(proto.length)})`);
|
|
71
71
|
}
|
|
72
72
|
let publicKey;
|
|
73
|
-
let signature;
|
|
74
73
|
let mldsaLevel;
|
|
74
|
+
let signFn;
|
|
75
75
|
if (options.sign) {
|
|
76
76
|
this.logger.info('Loading wallet for signing...');
|
|
77
77
|
const credentials = loadCredentials();
|
|
@@ -85,27 +85,25 @@ export class CompileCommand extends BaseCommand {
|
|
|
85
85
|
mldsaLevel = wallet.securityLevel;
|
|
86
86
|
publicKey = wallet.mldsaPublicKey;
|
|
87
87
|
this.logger.success(`Wallet loaded (MLDSA-${mldsaLevel})`);
|
|
88
|
-
|
|
89
|
-
const metadataBytes = Buffer.from(JSON.stringify(manifest), 'utf-8');
|
|
90
|
-
const checksum = computeChecksum(metadataBytes, bytecode, proto);
|
|
91
|
-
signature = wallet.signMLDSA(checksum);
|
|
92
|
-
this.logger.success(`Plugin signed (${formatFileSize(signature.length)} signature)`);
|
|
88
|
+
signFn = (checksum) => wallet.signMLDSA(checksum);
|
|
93
89
|
}
|
|
94
90
|
else {
|
|
95
91
|
this.logger.warn('Skipping signing (--no-sign)');
|
|
96
92
|
mldsaLevel = 44;
|
|
97
93
|
publicKey = Buffer.alloc(1312);
|
|
98
|
-
signature = Buffer.alloc(2420);
|
|
99
94
|
}
|
|
100
95
|
this.logger.info('Assembling .opnet binary...');
|
|
101
|
-
const binary = buildOpnetBinary({
|
|
96
|
+
const { binary, checksum } = buildOpnetBinary({
|
|
102
97
|
mldsaLevel,
|
|
103
98
|
publicKey,
|
|
104
|
-
signature,
|
|
105
99
|
metadata: manifest,
|
|
106
100
|
bytecode,
|
|
107
101
|
proto,
|
|
102
|
+
signFn,
|
|
108
103
|
});
|
|
104
|
+
if (options.sign) {
|
|
105
|
+
this.logger.success(`Plugin signed (checksum: sha256:${checksum.toString('hex').substring(0, 16)}...)`);
|
|
106
|
+
}
|
|
109
107
|
this.logger.success(`Binary assembled (${formatFileSize(binary.length)})`);
|
|
110
108
|
const outputPath = options.output ||
|
|
111
109
|
path.join(projectDir, 'build', `${manifest.name.replace(/^@/, '').replace(/\//g, '-')}.opnet`);
|
|
@@ -121,6 +119,7 @@ export class CompileCommand extends BaseCommand {
|
|
|
121
119
|
this.logger.log(`Plugin: ${manifest.name}@${manifest.version}`);
|
|
122
120
|
this.logger.log(`Type: ${manifest.pluginType}`);
|
|
123
121
|
this.logger.log(`MLDSA Level: ${mldsaLevel}`);
|
|
122
|
+
this.logger.log(`Checksum: sha256:${checksum.toString('hex')}`);
|
|
124
123
|
this.logger.log(`Signed: ${options.sign ? 'Yes' : 'No'}`);
|
|
125
124
|
this.logger.log('');
|
|
126
125
|
if (!options.sign) {
|
|
@@ -2,7 +2,7 @@ import { Command } from 'commander';
|
|
|
2
2
|
import * as os from 'os';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { BaseCommand } from './BaseCommand.js';
|
|
5
|
-
import {
|
|
5
|
+
import { displayConfig, getConfigValue, saveConfig, setConfigValue } from '../lib/config.js';
|
|
6
6
|
export class ConfigCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
8
8
|
super('config', 'Manage CLI configuration');
|
|
@@ -33,9 +33,7 @@ export class ConfigCommand extends BaseCommand {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
createListCommand() {
|
|
36
|
-
return new Command('list')
|
|
37
|
-
.description('List all configuration values')
|
|
38
|
-
.action(() => {
|
|
36
|
+
return new Command('list').description('List all configuration values').action(() => {
|
|
39
37
|
this.handleList();
|
|
40
38
|
});
|
|
41
39
|
}
|
|
@@ -48,9 +46,7 @@ export class ConfigCommand extends BaseCommand {
|
|
|
48
46
|
});
|
|
49
47
|
}
|
|
50
48
|
createPathCommand() {
|
|
51
|
-
return new Command('path')
|
|
52
|
-
.description('Show configuration file path')
|
|
53
|
-
.action(() => {
|
|
49
|
+
return new Command('path').description('Show configuration file path').action(() => {
|
|
54
50
|
this.handlePath();
|
|
55
51
|
});
|
|
56
52
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { confirm, input } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
3
|
import { getPackage, getVersion, isVersionImmutable } from '../lib/registry.js';
|
|
4
|
-
import {
|
|
4
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
6
|
export class DeprecateCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -2,8 +2,8 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as crypto from 'crypto';
|
|
4
4
|
import { BaseCommand } from './BaseCommand.js';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { formatFileSize, getParsedMldsaLevel, parseOpnetBinary } from '../lib/binary.js';
|
|
6
|
+
import { getManifestPath, loadManifest } from '../lib/manifest.js';
|
|
7
7
|
export class InfoCommand extends BaseCommand {
|
|
8
8
|
constructor() {
|
|
9
9
|
super('info', 'Display information about a plugin or .opnet file');
|
|
@@ -11,6 +11,8 @@ export declare class InitCommand extends BaseCommand {
|
|
|
11
11
|
private createEntryPoint;
|
|
12
12
|
private createGitignore;
|
|
13
13
|
private createReadme;
|
|
14
|
+
private createEslintConfig;
|
|
15
|
+
private createPrettierConfig;
|
|
14
16
|
private toPascalCase;
|
|
15
17
|
}
|
|
16
18
|
export declare const initCommand: import("commander").Command;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import { input, select
|
|
3
|
+
import { confirm, input, select } from '@inquirer/prompts';
|
|
4
4
|
import { BaseCommand } from './BaseCommand.js';
|
|
5
5
|
import { validatePluginName } from '../lib/manifest.js';
|
|
6
6
|
export class InitCommand extends BaseCommand {
|
|
@@ -45,21 +45,29 @@ export class InitCommand extends BaseCommand {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
this.logger.info('\nOPNet Plugin Initialization\n');
|
|
48
|
-
const pluginName = name ||
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
const pluginName = name ||
|
|
49
|
+
(await input({
|
|
50
|
+
message: 'Plugin name:',
|
|
51
|
+
default: path.basename(process.cwd()),
|
|
52
|
+
validate: (value) => {
|
|
53
|
+
const errors = validatePluginName(value);
|
|
54
|
+
return errors.length > 0 ? errors[0] : true;
|
|
55
|
+
},
|
|
56
|
+
}));
|
|
57
|
+
const description = (await input({ message: 'Description:', default: '' })) || undefined;
|
|
58
|
+
const authorName = await input({
|
|
59
|
+
message: 'Author name:',
|
|
60
|
+
default: process.env.USER || 'Author',
|
|
55
61
|
});
|
|
56
|
-
const
|
|
57
|
-
const authorName = await input({ message: 'Author name:', default: process.env.USER || 'Author' });
|
|
58
|
-
const authorEmail = await input({ message: 'Author email (optional):', default: '' }) || undefined;
|
|
62
|
+
const authorEmail = (await input({ message: 'Author email (optional):', default: '' })) || undefined;
|
|
59
63
|
const pluginType = await select({
|
|
60
64
|
message: 'Plugin type:',
|
|
61
65
|
choices: [
|
|
62
|
-
{
|
|
66
|
+
{
|
|
67
|
+
name: 'Standalone',
|
|
68
|
+
value: 'standalone',
|
|
69
|
+
description: 'Independent plugin',
|
|
70
|
+
},
|
|
63
71
|
{ name: 'Library', value: 'library', description: 'Shared library' },
|
|
64
72
|
],
|
|
65
73
|
default: options?.template || 'standalone',
|
|
@@ -74,7 +82,10 @@ export class InitCommand extends BaseCommand {
|
|
|
74
82
|
const projectDir = process.cwd();
|
|
75
83
|
const pluginJsonPath = path.join(projectDir, 'plugin.json');
|
|
76
84
|
if (fs.existsSync(pluginJsonPath) && !force) {
|
|
77
|
-
const overwrite = await confirm({
|
|
85
|
+
const overwrite = await confirm({
|
|
86
|
+
message: 'plugin.json exists. Overwrite?',
|
|
87
|
+
default: false,
|
|
88
|
+
});
|
|
78
89
|
if (!overwrite) {
|
|
79
90
|
this.logger.warn('Initialization cancelled.');
|
|
80
91
|
return;
|
|
@@ -94,16 +105,17 @@ export class InitCommand extends BaseCommand {
|
|
|
94
105
|
this.createEntryPoint(projectDir, config, force);
|
|
95
106
|
this.createGitignore(projectDir, force);
|
|
96
107
|
this.createReadme(projectDir, config, force);
|
|
108
|
+
this.createEslintConfig(projectDir, force);
|
|
109
|
+
this.createPrettierConfig(projectDir, force);
|
|
97
110
|
}
|
|
98
111
|
createPluginJson(projectDir, config) {
|
|
99
112
|
const manifest = {
|
|
100
113
|
name: config.pluginName,
|
|
101
114
|
version: '1.0.0',
|
|
102
|
-
opnetVersion: '
|
|
115
|
+
opnetVersion: '>=0.0.1',
|
|
103
116
|
main: 'dist/index.jsc',
|
|
104
117
|
target: 'bytenode',
|
|
105
118
|
type: 'plugin',
|
|
106
|
-
checksum: '',
|
|
107
119
|
author: config.authorEmail
|
|
108
120
|
? { name: config.authorName, email: config.authorEmail }
|
|
109
121
|
: { name: config.authorName },
|
|
@@ -185,14 +197,25 @@ export class InitCommand extends BaseCommand {
|
|
|
185
197
|
main: 'dist/index.js',
|
|
186
198
|
scripts: {
|
|
187
199
|
build: 'tsc',
|
|
188
|
-
compile: 'opnet compile',
|
|
189
|
-
verify: 'opnet verify',
|
|
200
|
+
compile: 'npx opnet compile',
|
|
201
|
+
verify: 'npx opnet verify',
|
|
190
202
|
lint: 'eslint src/',
|
|
203
|
+
format: 'prettier --write src/',
|
|
191
204
|
},
|
|
192
|
-
author: config.authorEmail
|
|
205
|
+
author: config.authorEmail
|
|
206
|
+
? `${config.authorName} <${config.authorEmail}>`
|
|
207
|
+
: config.authorName,
|
|
193
208
|
license: 'Apache-2.0',
|
|
194
209
|
dependencies: { '@btc-vision/plugin-sdk': '^1.0.0' },
|
|
195
|
-
devDependencies: {
|
|
210
|
+
devDependencies: {
|
|
211
|
+
'@eslint/js': '^9.39.0',
|
|
212
|
+
'@types/node': '^25.0.0',
|
|
213
|
+
eslint: '^9.39.0',
|
|
214
|
+
prettier: '^3.6.0',
|
|
215
|
+
typescript: '^5.8.0',
|
|
216
|
+
'typescript-eslint': '^8.39.0',
|
|
217
|
+
'@btc-vision/cli': '^1.0.0',
|
|
218
|
+
},
|
|
196
219
|
};
|
|
197
220
|
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 4));
|
|
198
221
|
this.logger.success(' Created package.json');
|
|
@@ -329,8 +352,79 @@ Apache-2.0
|
|
|
329
352
|
`);
|
|
330
353
|
this.logger.success(' Created README.md');
|
|
331
354
|
}
|
|
355
|
+
createEslintConfig(projectDir, force) {
|
|
356
|
+
const eslintPath = path.join(projectDir, 'eslint.config.js');
|
|
357
|
+
if (fs.existsSync(eslintPath) && !force)
|
|
358
|
+
return;
|
|
359
|
+
const content = `// @ts-check
|
|
360
|
+
|
|
361
|
+
import eslint from '@eslint/js';
|
|
362
|
+
import tseslint from 'typescript-eslint';
|
|
363
|
+
|
|
364
|
+
export default tseslint.config(
|
|
365
|
+
eslint.configs.recommended,
|
|
366
|
+
...tseslint.configs.strictTypeChecked,
|
|
367
|
+
{
|
|
368
|
+
languageOptions: {
|
|
369
|
+
parserOptions: {
|
|
370
|
+
projectService: true,
|
|
371
|
+
tsconfigDirName: import.meta.dirname,
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
rules: {
|
|
375
|
+
'no-undef': 'off',
|
|
376
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
377
|
+
'no-empty': 'off',
|
|
378
|
+
'@typescript-eslint/restrict-template-expressions': 'off',
|
|
379
|
+
'@typescript-eslint/only-throw-error': 'off',
|
|
380
|
+
'@typescript-eslint/no-unnecessary-condition': 'off',
|
|
381
|
+
'@typescript-eslint/unbound-method': 'warn',
|
|
382
|
+
'@typescript-eslint/no-confusing-void-expression': 'off',
|
|
383
|
+
'@typescript-eslint/no-extraneous-class': 'off',
|
|
384
|
+
'no-async-promise-executor': 'off',
|
|
385
|
+
'@typescript-eslint/no-misused-promises': 'off',
|
|
386
|
+
'@typescript-eslint/no-unnecessary-type-parameters': 'off',
|
|
387
|
+
'@typescript-eslint/no-duplicate-enum-values': 'off',
|
|
388
|
+
'prefer-spread': 'off',
|
|
389
|
+
'@typescript-eslint/no-empty-object-type': 'off',
|
|
390
|
+
'@typescript-eslint/no-base-to-string': 'off',
|
|
391
|
+
'@typescript-eslint/no-dynamic-delete': 'off',
|
|
392
|
+
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
files: ['**/*.js'],
|
|
397
|
+
...tseslint.configs.disableTypeChecked,
|
|
398
|
+
},
|
|
399
|
+
);
|
|
400
|
+
`;
|
|
401
|
+
fs.writeFileSync(eslintPath, content);
|
|
402
|
+
this.logger.success(' Created eslint.config.js');
|
|
403
|
+
}
|
|
404
|
+
createPrettierConfig(projectDir, force) {
|
|
405
|
+
const prettierPath = path.join(projectDir, '.prettierrc.json');
|
|
406
|
+
if (fs.existsSync(prettierPath) && !force)
|
|
407
|
+
return;
|
|
408
|
+
const config = {
|
|
409
|
+
printWidth: 100,
|
|
410
|
+
trailingComma: 'all',
|
|
411
|
+
tabWidth: 4,
|
|
412
|
+
semi: true,
|
|
413
|
+
singleQuote: true,
|
|
414
|
+
quoteProps: 'as-needed',
|
|
415
|
+
bracketSpacing: true,
|
|
416
|
+
bracketSameLine: true,
|
|
417
|
+
arrowParens: 'always',
|
|
418
|
+
singleAttributePerLine: true,
|
|
419
|
+
};
|
|
420
|
+
fs.writeFileSync(prettierPath, JSON.stringify(config, null, 4));
|
|
421
|
+
this.logger.success(' Created .prettierrc.json');
|
|
422
|
+
}
|
|
332
423
|
toPascalCase(str) {
|
|
333
|
-
return str
|
|
424
|
+
return str
|
|
425
|
+
.split(/[-_]/)
|
|
426
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
427
|
+
.join('');
|
|
334
428
|
}
|
|
335
429
|
}
|
|
336
430
|
export const initCommand = new InitCommand().getCommand();
|
|
@@ -3,7 +3,7 @@ import * as path from 'path';
|
|
|
3
3
|
import { BaseCommand } from './BaseCommand.js';
|
|
4
4
|
import { getPackage, getVersion, registryToMldsaLevel } from '../lib/registry.js';
|
|
5
5
|
import { fetchFromIPFS, isValidCid } from '../lib/ipfs.js';
|
|
6
|
-
import { parseOpnetBinary, verifyChecksum
|
|
6
|
+
import { formatFileSize, parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
|
|
7
7
|
import { CLIWallet } from '../lib/wallet.js';
|
|
8
8
|
export class InstallCommand extends BaseCommand {
|
|
9
9
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import * as fs from 'fs';
|
|
3
3
|
import { BaseCommand } from './BaseCommand.js';
|
|
4
|
-
import { generateMLDSAKeypair, generateMnemonic
|
|
4
|
+
import { computePublicKeyHash, generateMLDSAKeypair, generateMnemonic } from '../lib/wallet.js';
|
|
5
5
|
import { isValidMldsaLevel } from '../lib/credentials.js';
|
|
6
6
|
export class KeygenCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { BaseCommand } from './BaseCommand.js';
|
|
4
|
-
import {
|
|
4
|
+
import { formatFileSize, parseOpnetBinary } from '../lib/binary.js';
|
|
5
5
|
export class ListCommand extends BaseCommand {
|
|
6
6
|
constructor() {
|
|
7
7
|
super('list', 'List installed plugins');
|
|
@@ -98,7 +98,11 @@ export class ListCommand extends BaseCommand {
|
|
|
98
98
|
const versionWidth = 12;
|
|
99
99
|
const typeWidth = 12;
|
|
100
100
|
const sizeWidth = 10;
|
|
101
|
-
this.logger.info('Name'.padEnd(nameWidth) +
|
|
101
|
+
this.logger.info('Name'.padEnd(nameWidth) +
|
|
102
|
+
'Version'.padEnd(versionWidth) +
|
|
103
|
+
'Type'.padEnd(typeWidth) +
|
|
104
|
+
'Size'.padEnd(sizeWidth) +
|
|
105
|
+
'Signed');
|
|
102
106
|
this.logger.info('─'.repeat(nameWidth + versionWidth + typeWidth + sizeWidth + 8));
|
|
103
107
|
for (const plugin of plugins) {
|
|
104
108
|
const signedText = plugin.signed ? 'Yes' : 'No';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { confirm, password, select } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { isValidMldsaLevel, isValidNetwork, saveCredentials } from '../lib/credentials.js';
|
|
4
|
+
import { CLIWallet, validateMnemonic } from '../lib/wallet.js';
|
|
5
5
|
export class LoginCommand extends BaseCommand {
|
|
6
6
|
constructor() {
|
|
7
7
|
super('login', 'Configure wallet credentials for signing and publishing');
|
|
@@ -95,7 +95,7 @@ export class LoginCommand extends BaseCommand {
|
|
|
95
95
|
},
|
|
96
96
|
],
|
|
97
97
|
});
|
|
98
|
-
const selectedNetwork = await select({
|
|
98
|
+
const selectedNetwork = (await select({
|
|
99
99
|
message: 'Select network:',
|
|
100
100
|
choices: [
|
|
101
101
|
{ name: 'Mainnet', value: 'mainnet' },
|
|
@@ -103,16 +103,28 @@ export class LoginCommand extends BaseCommand {
|
|
|
103
103
|
{ name: 'Regtest', value: 'regtest' },
|
|
104
104
|
],
|
|
105
105
|
default: defaultNetwork,
|
|
106
|
-
});
|
|
107
|
-
const selectedLevel = await select({
|
|
106
|
+
}));
|
|
107
|
+
const selectedLevel = (await select({
|
|
108
108
|
message: 'Select MLDSA security level:',
|
|
109
109
|
choices: [
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
{
|
|
111
|
+
name: 'MLDSA-44 (Level 2, fastest)',
|
|
112
|
+
value: 44,
|
|
113
|
+
description: '1312 byte public key',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'MLDSA-65 (Level 3, balanced)',
|
|
117
|
+
value: 65,
|
|
118
|
+
description: '1952 byte public key',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'MLDSA-87 (Level 5, most secure)',
|
|
122
|
+
value: 87,
|
|
123
|
+
description: '2592 byte public key',
|
|
124
|
+
},
|
|
113
125
|
],
|
|
114
126
|
default: defaultLevel,
|
|
115
|
-
});
|
|
127
|
+
}));
|
|
116
128
|
if (loginMethod === 'mnemonic') {
|
|
117
129
|
const mnemonic = await password({
|
|
118
130
|
message: 'Enter your mnemonic phrase (12 or 24 words):',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
|
-
import { deleteCredentials,
|
|
3
|
+
import { deleteCredentials, getCredentialSource, hasCredentials } from '../lib/credentials.js';
|
|
4
4
|
export class LogoutCommand extends BaseCommand {
|
|
5
5
|
constructor() {
|
|
6
6
|
super('logout', 'Remove stored wallet credentials');
|
|
@@ -3,11 +3,11 @@ import * as path from 'path';
|
|
|
3
3
|
import * as crypto from 'crypto';
|
|
4
4
|
import { confirm } from '@inquirer/prompts';
|
|
5
5
|
import { BaseCommand } from './BaseCommand.js';
|
|
6
|
-
import {
|
|
6
|
+
import { formatFileSize, parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
|
|
7
7
|
import { CLIWallet } from '../lib/wallet.js';
|
|
8
|
-
import {
|
|
8
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
9
9
|
import { uploadPlugin } from '../lib/ipfs.js';
|
|
10
|
-
import {
|
|
10
|
+
import { computePermissionsHash, encodeDependencies, getPackage, getScope, mldsaLevelToRegistry, parsePackageName, pluginTypeToRegistry, } from '../lib/registry.js';
|
|
11
11
|
export class PublishCommand extends BaseCommand {
|
|
12
12
|
constructor() {
|
|
13
13
|
super('publish', 'Publish a plugin to the OPNet registry');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from './BaseCommand.js';
|
|
2
|
-
import { getPackage, getVersion, registryToMldsaLevel, registryToPluginType } from '../lib/registry.js';
|
|
2
|
+
import { getPackage, getVersion, registryToMldsaLevel, registryToPluginType, } from '../lib/registry.js';
|
|
3
3
|
export class SearchCommand extends BaseCommand {
|
|
4
4
|
constructor() {
|
|
5
5
|
super('search', 'Search for plugins in the registry');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as crypto from 'crypto';
|
|
3
3
|
import { BaseCommand } from './BaseCommand.js';
|
|
4
|
-
import {
|
|
4
|
+
import { buildOpnetBinary, formatFileSize, parseOpnetBinary } from '../lib/binary.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
|
-
import {
|
|
6
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
7
7
|
export class SignCommand extends BaseCommand {
|
|
8
8
|
constructor() {
|
|
9
9
|
super('sign', 'Sign or re-sign a .opnet binary with your MLDSA key');
|
|
@@ -34,7 +34,10 @@ export class SignCommand extends BaseCommand {
|
|
|
34
34
|
const parsed = parseOpnetBinary(data);
|
|
35
35
|
this.logger.success(`Parsed: ${parsed.metadata.name}@${parsed.metadata.version}`);
|
|
36
36
|
const isUnsigned = parsed.publicKey.every((b) => b === 0);
|
|
37
|
-
const currentPkHash = crypto
|
|
37
|
+
const currentPkHash = crypto
|
|
38
|
+
.createHash('sha256')
|
|
39
|
+
.update(parsed.publicKey)
|
|
40
|
+
.digest('hex');
|
|
38
41
|
const newPkHash = wallet.mldsaPublicKeyHash;
|
|
39
42
|
if (!isUnsigned && currentPkHash !== newPkHash && !options.force) {
|
|
40
43
|
this.logger.log('');
|
|
@@ -45,20 +48,17 @@ export class SignCommand extends BaseCommand {
|
|
|
45
48
|
this.logger.log('Use --force to re-sign with your key.');
|
|
46
49
|
process.exit(1);
|
|
47
50
|
}
|
|
48
|
-
this.logger.info('Signing...');
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const signature = wallet.signMLDSA(checksum);
|
|
52
|
-
this.logger.success(`Signed (${formatFileSize(signature.length)} signature)`);
|
|
53
|
-
this.logger.info('Rebuilding binary...');
|
|
54
|
-
const newBinary = buildOpnetBinary({
|
|
51
|
+
this.logger.info('Signing and rebuilding binary...');
|
|
52
|
+
const signFn = (checksum) => wallet.signMLDSA(checksum);
|
|
53
|
+
const { binary: newBinary, checksum } = buildOpnetBinary({
|
|
55
54
|
mldsaLevel: wallet.securityLevel,
|
|
56
55
|
publicKey: wallet.mldsaPublicKey,
|
|
57
|
-
signature,
|
|
58
56
|
metadata: parsed.metadata,
|
|
59
57
|
bytecode: parsed.bytecode,
|
|
60
58
|
proto: parsed.proto ?? Buffer.alloc(0),
|
|
59
|
+
signFn,
|
|
61
60
|
});
|
|
61
|
+
this.logger.success(`Signed (checksum: sha256:${checksum.toString('hex').substring(0, 16)}...)`);
|
|
62
62
|
this.logger.success(`Binary rebuilt (${formatFileSize(newBinary.length)})`);
|
|
63
63
|
const outputPath = options.output || file;
|
|
64
64
|
fs.writeFileSync(outputPath, newBinary);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { confirm, input } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
|
-
import { getPackage,
|
|
4
|
-
import {
|
|
3
|
+
import { getPackage, getPendingScopeTransfer, getPendingTransfer, getScope, } from '../lib/registry.js';
|
|
4
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
6
|
export class TransferCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { confirm } from '@inquirer/prompts';
|
|
2
2
|
import { BaseCommand } from './BaseCommand.js';
|
|
3
3
|
import { getPackage, getVersion, isVersionImmutable } from '../lib/registry.js';
|
|
4
|
-
import {
|
|
4
|
+
import { canSign, loadCredentials } from '../lib/credentials.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
6
|
export class UndeprecateCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as crypto from 'crypto';
|
|
3
3
|
import { BaseCommand } from './BaseCommand.js';
|
|
4
|
-
import { parseOpnetBinary, verifyChecksum
|
|
4
|
+
import { formatFileSize, parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
|
|
5
5
|
import { CLIWallet } from '../lib/wallet.js';
|
|
6
6
|
export class VerifyCommand extends BaseCommand {
|
|
7
7
|
constructor() {
|
|
@@ -68,7 +68,10 @@ export class VerifyCommand extends BaseCommand {
|
|
|
68
68
|
signatureError,
|
|
69
69
|
isUnsigned,
|
|
70
70
|
metadata: parsed.metadata,
|
|
71
|
-
publicKeyHash: crypto
|
|
71
|
+
publicKeyHash: crypto
|
|
72
|
+
.createHash('sha256')
|
|
73
|
+
.update(parsed.publicKey)
|
|
74
|
+
.digest('hex'),
|
|
72
75
|
bytecodeSize: parsed.bytecode.length,
|
|
73
76
|
protoSize: parsed.proto?.length ?? 0,
|
|
74
77
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from './BaseCommand.js';
|
|
2
|
-
import {
|
|
2
|
+
import { getCredentialSource, hasCredentials, loadCredentials, maskSensitive, } from '../lib/credentials.js';
|
|
3
3
|
import { CLIWallet } from '../lib/wallet.js';
|
|
4
4
|
export class WhoamiCommand extends BaseCommand {
|
|
5
5
|
constructor() {
|
package/build/lib/binary.d.ts
CHANGED
|
@@ -6,11 +6,14 @@ export declare function verifyChecksum(parsed: IParsedPluginFile): boolean;
|
|
|
6
6
|
export declare function buildOpnetBinary(options: {
|
|
7
7
|
mldsaLevel: CLIMldsaLevel;
|
|
8
8
|
publicKey: Buffer;
|
|
9
|
-
signature: Buffer;
|
|
10
9
|
metadata: IPluginMetadata;
|
|
11
10
|
bytecode: Buffer;
|
|
12
11
|
proto?: Buffer;
|
|
13
|
-
|
|
12
|
+
signFn?: (checksum: Buffer) => Buffer;
|
|
13
|
+
}): {
|
|
14
|
+
binary: Buffer;
|
|
15
|
+
checksum: Buffer;
|
|
16
|
+
};
|
|
14
17
|
export declare function extractMetadata(data: Buffer): IPluginMetadata | null;
|
|
15
18
|
export declare function getParsedMldsaLevel(parsed: IParsedPluginFile): CLIMldsaLevel;
|
|
16
19
|
export declare function formatFileSize(bytes: number): string;
|