@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.
Files changed (41) hide show
  1. package/build/commands/AcceptCommand.js +2 -2
  2. package/build/commands/CompileCommand.js +11 -12
  3. package/build/commands/ConfigCommand.js +3 -7
  4. package/build/commands/DeprecateCommand.js +2 -2
  5. package/build/commands/InfoCommand.js +2 -2
  6. package/build/commands/InitCommand.d.ts +2 -0
  7. package/build/commands/InitCommand.js +114 -20
  8. package/build/commands/InstallCommand.js +1 -1
  9. package/build/commands/KeygenCommand.js +1 -1
  10. package/build/commands/ListCommand.js +6 -2
  11. package/build/commands/LoginCommand.js +22 -10
  12. package/build/commands/LogoutCommand.js +1 -1
  13. package/build/commands/PublishCommand.js +3 -3
  14. package/build/commands/SearchCommand.js +1 -1
  15. package/build/commands/SignCommand.js +11 -11
  16. package/build/commands/TransferCommand.js +3 -3
  17. package/build/commands/UndeprecateCommand.js +1 -1
  18. package/build/commands/VerifyCommand.js +5 -2
  19. package/build/commands/WhoamiCommand.js +1 -1
  20. package/build/lib/PackageRegistry.abi.js +1 -1
  21. package/build/lib/binary.d.ts +5 -2
  22. package/build/lib/binary.js +18 -10
  23. package/build/lib/config.d.ts +1 -1
  24. package/build/lib/credentials.d.ts +1 -1
  25. package/build/lib/ipfs.js +3 -2
  26. package/build/lib/manifest.d.ts +1 -1
  27. package/build/lib/manifest.js +23 -12
  28. package/build/lib/provider.js +1 -1
  29. package/build/lib/registry.d.ts +1 -1
  30. package/build/lib/wallet.d.ts +5 -5
  31. package/build/lib/wallet.js +31 -31
  32. package/build/types/PackageRegistry.d.ts +1 -1
  33. package/build/types/index.js +1 -1
  34. package/package.json +3 -3
  35. package/src/commands/CompileCommand.ts +13 -14
  36. package/src/commands/InitCommand.ts +87 -5
  37. package/src/commands/SignCommand.ts +9 -21
  38. package/src/lib/binary.ts +24 -22
  39. package/src/lib/config.ts +3 -4
  40. package/src/lib/ipfs.ts +0 -1
  41. 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 { getPendingTransfer, getPendingScopeTransfer } from '../lib/registry.js';
4
- import { loadCredentials, canSign } from '../lib/credentials.js';
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 { loadManifest, getManifestPath } from '../lib/manifest.js';
7
- import { buildOpnetBinary, formatFileSize, computeChecksum } from '../lib/binary.js';
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 { loadCredentials, canSign } from '../lib/credentials.js';
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
- this.logger.info('Signing plugin...');
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 { saveConfig, getConfigValue, setConfigValue, displayConfig, } from '../lib/config.js';
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 { input, confirm } from '@inquirer/prompts';
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 { loadCredentials, canSign } from '../lib/credentials.js';
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 { parseOpnetBinary, formatFileSize, getParsedMldsaLevel } from '../lib/binary.js';
6
- import { loadManifest, getManifestPath } from '../lib/manifest.js';
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, confirm } from '@inquirer/prompts';
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 || await input({
49
- message: 'Plugin name:',
50
- default: path.basename(process.cwd()),
51
- validate: (value) => {
52
- const errors = validatePluginName(value);
53
- return errors.length > 0 ? errors[0] : true;
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 description = await input({ message: 'Description:', default: '' }) || undefined;
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
- { name: 'Standalone', value: 'standalone', description: 'Independent plugin' },
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({ message: 'plugin.json exists. Overwrite?', default: false });
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: '^1.0.0',
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 ? `${config.authorName} <${config.authorEmail}>` : config.authorName,
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: { '@types/node': '^22.0.0', typescript: '^5.8.0', '@btc-vision/cli': '^1.0.0' },
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.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()).join('');
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, formatFileSize } from '../lib/binary.js';
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, computePublicKeyHash } from '../lib/wallet.js';
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 { parseOpnetBinary, formatFileSize } from '../lib/binary.js';
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) + 'Version'.padEnd(versionWidth) + 'Type'.padEnd(typeWidth) + 'Size'.padEnd(sizeWidth) + 'Signed');
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 { select, confirm, password } from '@inquirer/prompts';
1
+ import { confirm, password, select } from '@inquirer/prompts';
2
2
  import { BaseCommand } from './BaseCommand.js';
3
- import { saveCredentials, isValidMldsaLevel, isValidNetwork } from '../lib/credentials.js';
4
- import { validateMnemonic, CLIWallet } from '../lib/wallet.js';
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
- { name: 'MLDSA-44 (Level 2, fastest)', value: 44, description: '1312 byte public key' },
111
- { name: 'MLDSA-65 (Level 3, balanced)', value: 65, description: '1952 byte public key' },
112
- { name: 'MLDSA-87 (Level 5, most secure)', value: 87, description: '2592 byte public key' },
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, hasCredentials, getCredentialSource } from '../lib/credentials.js';
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 { parseOpnetBinary, formatFileSize, verifyChecksum } from '../lib/binary.js';
6
+ import { formatFileSize, parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
7
7
  import { CLIWallet } from '../lib/wallet.js';
8
- import { loadCredentials, canSign } from '../lib/credentials.js';
8
+ import { canSign, loadCredentials } from '../lib/credentials.js';
9
9
  import { uploadPlugin } from '../lib/ipfs.js';
10
- import { getPackage, getScope, parsePackageName, computePermissionsHash, encodeDependencies, pluginTypeToRegistry, mldsaLevelToRegistry, } from '../lib/registry.js';
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 { parseOpnetBinary, buildOpnetBinary, computeChecksum, formatFileSize } from '../lib/binary.js';
4
+ import { buildOpnetBinary, formatFileSize, parseOpnetBinary } from '../lib/binary.js';
5
5
  import { CLIWallet } from '../lib/wallet.js';
6
- import { loadCredentials, canSign } from '../lib/credentials.js';
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.createHash('sha256').update(parsed.publicKey).digest('hex');
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 metadataBytes = Buffer.from(parsed.rawMetadata, 'utf-8');
50
- const checksum = computeChecksum(metadataBytes, parsed.bytecode, parsed.proto ?? Buffer.alloc(0));
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 { input, confirm } from '@inquirer/prompts';
1
+ import { confirm, input } from '@inquirer/prompts';
2
2
  import { BaseCommand } from './BaseCommand.js';
3
- import { getPackage, getScope, getPendingTransfer, getPendingScopeTransfer, } from '../lib/registry.js';
4
- import { loadCredentials, canSign } from '../lib/credentials.js';
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 { loadCredentials, canSign } from '../lib/credentials.js';
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, formatFileSize } from '../lib/binary.js';
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.createHash('sha256').update(parsed.publicKey).digest('hex'),
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 { loadCredentials, hasCredentials, getCredentialSource, maskSensitive, } from '../lib/credentials.js';
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() {
@@ -1,5 +1,5 @@
1
- import { ABIDataTypes } from '@btc-vision/transaction';
2
1
  import { BitcoinAbiTypes } from 'opnet';
2
+ import { ABIDataTypes } from '@btc-vision/transaction';
3
3
  export const PACKAGE_REGISTRY_ABI = [
4
4
  {
5
5
  name: 'setTreasuryAddress',
@@ -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
- }): Buffer;
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;