@btc-vision/cli 1.0.5 → 1.0.7

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 (51) hide show
  1. package/build/index.js +3 -4
  2. package/build/lib/config.js +1 -6
  3. package/build/lib/ipfs.d.ts +0 -2
  4. package/build/lib/ipfs.js +29 -32
  5. package/build/lib/wallet.js +1 -1
  6. package/package.json +4 -1
  7. package/.gitattributes +0 -2
  8. package/.github/dependabot.yml +0 -9
  9. package/.github/workflows/ci.yml +0 -48
  10. package/.prettierrc.json +0 -12
  11. package/CONTRIBUTING.md +0 -56
  12. package/NOTICE +0 -17
  13. package/SECURITY.md +0 -35
  14. package/eslint.config.js +0 -41
  15. package/gulpfile.js +0 -41
  16. package/src/commands/AcceptCommand.ts +0 -224
  17. package/src/commands/BaseCommand.ts +0 -59
  18. package/src/commands/CompileCommand.ts +0 -195
  19. package/src/commands/ConfigCommand.ts +0 -117
  20. package/src/commands/DeprecateCommand.ts +0 -193
  21. package/src/commands/InfoCommand.ts +0 -293
  22. package/src/commands/InitCommand.ts +0 -541
  23. package/src/commands/InstallCommand.ts +0 -179
  24. package/src/commands/KeygenCommand.ts +0 -157
  25. package/src/commands/ListCommand.ts +0 -169
  26. package/src/commands/LoginCommand.ts +0 -197
  27. package/src/commands/LogoutCommand.ts +0 -76
  28. package/src/commands/PublishCommand.ts +0 -340
  29. package/src/commands/ScopeRegisterCommand.ts +0 -164
  30. package/src/commands/SearchCommand.ts +0 -140
  31. package/src/commands/SignCommand.ts +0 -110
  32. package/src/commands/TransferCommand.ts +0 -363
  33. package/src/commands/UndeprecateCommand.ts +0 -167
  34. package/src/commands/UpdateCommand.ts +0 -200
  35. package/src/commands/VerifyCommand.ts +0 -228
  36. package/src/commands/WhoamiCommand.ts +0 -113
  37. package/src/index.ts +0 -88
  38. package/src/lib/PackageRegistry.abi.json +0 -765
  39. package/src/lib/PackageRegistry.abi.ts +0 -365
  40. package/src/lib/binary.ts +0 -338
  41. package/src/lib/config.ts +0 -265
  42. package/src/lib/credentials.ts +0 -176
  43. package/src/lib/ipfs.ts +0 -382
  44. package/src/lib/manifest.ts +0 -195
  45. package/src/lib/provider.ts +0 -121
  46. package/src/lib/registry.ts +0 -467
  47. package/src/lib/transaction.ts +0 -205
  48. package/src/lib/wallet.ts +0 -262
  49. package/src/types/PackageRegistry.ts +0 -344
  50. package/src/types/index.ts +0 -147
  51. package/tsconfig.json +0 -25
@@ -1,59 +0,0 @@
1
- /**
2
- * Base command class for OPNet CLI
3
- *
4
- * @module commands/BaseCommand
5
- */
6
-
7
- import { Command } from 'commander';
8
- import { Logger } from '@btc-vision/logger';
9
-
10
- /**
11
- * Abstract base class for all CLI commands
12
- */
13
- export abstract class BaseCommand {
14
- protected readonly logger: Logger;
15
- protected readonly command: Command;
16
-
17
- constructor(name: string, description: string) {
18
- this.logger = new Logger();
19
- this.command = new Command(name).description(description);
20
- this.configure();
21
- }
22
-
23
- /**
24
- * Get the configured command instance
25
- */
26
- public getCommand(): Command {
27
- return this.command;
28
- }
29
-
30
- /**
31
- * Configure the command with options and action
32
- */
33
- protected abstract configure(): void;
34
-
35
- /**
36
- * Format an error message for display
37
- */
38
- protected formatError(error: unknown): string {
39
- if (error instanceof Error) {
40
- return error.message;
41
- }
42
- return String(error);
43
- }
44
-
45
- /**
46
- * Exit with error
47
- */
48
- protected exitWithError(message: string, code: number = 1): never {
49
- this.logger.error(message);
50
- process.exit(code);
51
- }
52
-
53
- /**
54
- * Check if user cancelled (for inquirer)
55
- */
56
- protected isUserCancelled(error: unknown): boolean {
57
- return error instanceof Error && error.message.includes('User force closed');
58
- }
59
- }
@@ -1,195 +0,0 @@
1
- /**
2
- * Compile command - Build plugin to .opnet binary
3
- *
4
- * @module commands/CompileCommand
5
- */
6
-
7
- import * as fs from 'fs';
8
- import * as path from 'path';
9
- import * as esbuild from 'esbuild';
10
- import bytenode from 'bytenode';
11
- import { BaseCommand } from './BaseCommand.js';
12
- import { getManifestPath, loadManifest } from '../lib/manifest.js';
13
- import { buildOpnetBinary, formatFileSize } from '../lib/binary.js';
14
- import { CLIWallet } from '../lib/wallet.js';
15
- import { canSign, loadCredentials } from '../lib/credentials.js';
16
- import { CLIMldsaLevel } from '../types/index.js';
17
-
18
- interface CompileOptions {
19
- output?: string;
20
- dir?: string;
21
- sign: boolean;
22
- minify: boolean;
23
- sourcemap: boolean;
24
- }
25
-
26
- export class CompileCommand extends BaseCommand {
27
- constructor() {
28
- super('compile', 'Compile plugin to .opnet binary format');
29
- }
30
-
31
- protected configure(): void {
32
- this.command
33
- .option('-o, --output <path>', 'Output file path')
34
- .option('-d, --dir <path>', 'Plugin directory (default: current)')
35
- .option('--no-sign', 'Skip signing (produce unsigned binary)')
36
- .option('--minify', 'Minify the bundled code', true)
37
- .option('--sourcemap', 'Generate source maps', false)
38
- .action((options: CompileOptions) => this.execute(options));
39
- }
40
-
41
- private async execute(options: CompileOptions): Promise<void> {
42
- try {
43
- const projectDir = options.dir ? path.resolve(options.dir) : process.cwd();
44
- const manifestPath = getManifestPath(projectDir);
45
-
46
- // Load and validate manifest
47
- this.logger.info('Loading plugin manifest...');
48
- const manifest = loadManifest(manifestPath);
49
- this.logger.success(`Loaded manifest: ${manifest.name}@${manifest.version}`);
50
-
51
- // Check for source files
52
- const srcDir = path.join(projectDir, 'src');
53
- const entryPoint = path.join(srcDir, 'index.ts');
54
-
55
- if (!fs.existsSync(entryPoint)) {
56
- this.exitWithError(`Entry point not found: ${entryPoint}`);
57
- }
58
-
59
- // Bundle with esbuild
60
- this.logger.info('Bundling TypeScript...');
61
- const bundleDir = path.join(projectDir, 'build', '.bundle');
62
- fs.mkdirSync(bundleDir, { recursive: true });
63
-
64
- const bundlePath = path.join(bundleDir, 'bundle.js');
65
-
66
- await esbuild.build({
67
- entryPoints: [entryPoint],
68
- bundle: true,
69
- platform: 'node',
70
- target: 'es2022',
71
- format: 'cjs', // bytenode requires CommonJS
72
- outfile: bundlePath,
73
- minify: options.minify,
74
- sourcemap: options.sourcemap,
75
- treeShaking: true,
76
- external: [
77
- '@btc-vision/plugin-sdk',
78
- '@btc-vision/transaction',
79
- '@btc-vision/bitcoin',
80
- 'opnet',
81
- ],
82
- });
83
- this.logger.success('TypeScript bundled');
84
-
85
- // Compile to V8 bytecode
86
- this.logger.info('Compiling to V8 bytecode...');
87
- const bytecodePath = path.join(bundleDir, 'bundle.jsc');
88
-
89
- await bytenode.compileFile({
90
- filename: bundlePath,
91
- output: bytecodePath,
92
- electron: false,
93
- });
94
-
95
- const bytecode = fs.readFileSync(bytecodePath);
96
- this.logger.success(`V8 bytecode generated (${formatFileSize(bytecode.length)})`);
97
-
98
- // Check for proto file
99
- let proto = Buffer.alloc(0);
100
- const protoPath = path.join(projectDir, 'plugin.proto');
101
- if (fs.existsSync(protoPath)) {
102
- proto = fs.readFileSync(protoPath);
103
- this.logger.info(`Found proto file (${formatFileSize(proto.length)})`);
104
- }
105
-
106
- // Prepare signing
107
- let publicKey: Buffer;
108
- let mldsaLevel: CLIMldsaLevel;
109
- let signFn: ((checksum: Buffer) => Buffer) | undefined;
110
-
111
- if (options.sign) {
112
- this.logger.info('Loading wallet for signing...');
113
- const credentials = loadCredentials();
114
-
115
- if (!credentials || !canSign(credentials)) {
116
- this.logger.fail('No credentials configured');
117
- this.logger.warn('To sign plugins, run: opnet login');
118
- this.logger.warn('Or use --no-sign to skip signing.');
119
- process.exit(1);
120
- }
121
-
122
- const wallet = CLIWallet.fromCredentials(credentials);
123
- mldsaLevel = wallet.securityLevel;
124
- publicKey = wallet.mldsaPublicKey;
125
-
126
- this.logger.success(`Wallet loaded (MLDSA-${mldsaLevel})`);
127
-
128
- // Create signing function that will be called with the final checksum
129
- signFn = (checksum: Buffer) => wallet.signMLDSA(checksum);
130
- } else {
131
- this.logger.warn('Skipping signing (--no-sign)');
132
- // Use dummy values for unsigned binary
133
- mldsaLevel = 44;
134
- publicKey = Buffer.alloc(1312); // MLDSA-44 public key size
135
- }
136
-
137
- // Build .opnet binary
138
- this.logger.info('Assembling .opnet binary...');
139
- const { binary, checksum } = buildOpnetBinary({
140
- mldsaLevel,
141
- publicKey,
142
- metadata: manifest,
143
- bytecode,
144
- proto,
145
- signFn,
146
- });
147
-
148
- if (options.sign) {
149
- this.logger.success(
150
- `Plugin signed (checksum: sha256:${checksum.toString('hex').substring(0, 16)}...)`,
151
- );
152
- }
153
- this.logger.success(`Binary assembled (${formatFileSize(binary.length)})`);
154
-
155
- // Write output
156
- const outputPath =
157
- options.output ||
158
- path.join(
159
- projectDir,
160
- 'build',
161
- `${manifest.name.replace(/^@/, '').replace(/\//g, '-')}.opnet`,
162
- );
163
- const outputDir = path.dirname(outputPath);
164
- fs.mkdirSync(outputDir, { recursive: true });
165
- fs.writeFileSync(outputPath, binary);
166
-
167
- // Clean up bundle directory
168
- fs.rmSync(bundleDir, { recursive: true, force: true });
169
-
170
- // Summary
171
- this.logger.log('');
172
- this.logger.success('Compilation successful!');
173
- this.logger.log('');
174
- this.logger.log(`Output: ${outputPath}`);
175
- this.logger.log(`Size: ${formatFileSize(binary.length)}`);
176
- this.logger.log(`Plugin: ${manifest.name}@${manifest.version}`);
177
- this.logger.log(`Type: ${manifest.pluginType}`);
178
- this.logger.log(`MLDSA Level: ${mldsaLevel}`);
179
- this.logger.log(`Checksum: sha256:${checksum.toString('hex')}`);
180
- this.logger.log(`Signed: ${options.sign ? 'Yes' : 'No'}`);
181
- this.logger.log('');
182
-
183
- if (!options.sign) {
184
- this.logger.warn('Note: This binary is unsigned and cannot be published.');
185
- this.logger.warn('Use `opnet sign` to sign it, or compile with signing enabled.');
186
- this.logger.log('');
187
- }
188
- } catch (error) {
189
- this.logger.fail('Compilation failed');
190
- this.exitWithError(this.formatError(error));
191
- }
192
- }
193
- }
194
-
195
- export const compileCommand = new CompileCommand().getCommand();
@@ -1,117 +0,0 @@
1
- /**
2
- * Config command - Manage CLI configuration
3
- *
4
- * @module commands/ConfigCommand
5
- */
6
-
7
- import { Command } from 'commander';
8
- import * as os from 'os';
9
- import * as path from 'path';
10
- import { BaseCommand } from './BaseCommand.js';
11
- import { DEFAULT_CONFIG, displayConfig, getConfigValue, saveConfig, setConfigValue, } from '../lib/config.js';
12
-
13
- export class ConfigCommand extends BaseCommand {
14
- constructor() {
15
- super('config', 'Manage CLI configuration');
16
- }
17
-
18
- protected configure(): void {
19
- this.command
20
- .addCommand(this.createGetCommand())
21
- .addCommand(this.createSetCommand())
22
- .addCommand(this.createListCommand())
23
- .addCommand(this.createResetCommand())
24
- .addCommand(this.createPathCommand());
25
- }
26
-
27
- private createGetCommand(): Command {
28
- return new Command('get')
29
- .description('Get a configuration value')
30
- .argument('[key]', 'Configuration key (dot notation, e.g., rpcUrls.mainnet)')
31
- .action((key?: string) => {
32
- this.handleGet(key);
33
- });
34
- }
35
-
36
- private createSetCommand(): Command {
37
- return new Command('set')
38
- .description('Set a configuration value')
39
- .argument('<key>', 'Configuration key (dot notation)')
40
- .argument('<value>', 'Value to set')
41
- .action((key: string, value: string) => {
42
- this.handleSet(key, value);
43
- });
44
- }
45
-
46
- private createListCommand(): Command {
47
- return new Command('list').description('List all configuration values').action(() => {
48
- this.handleList();
49
- });
50
- }
51
-
52
- private createResetCommand(): Command {
53
- return new Command('reset')
54
- .description('Reset configuration to defaults')
55
- .option('-y, --yes', 'Skip confirmation')
56
- .action((options: { yes?: boolean }) => {
57
- this.handleReset(options.yes);
58
- });
59
- }
60
-
61
- private createPathCommand(): Command {
62
- return new Command('path').description('Show configuration file path').action(() => {
63
- this.handlePath();
64
- });
65
- }
66
-
67
- private handleGet(key?: string): void {
68
- if (!key) {
69
- this.logger.log(displayConfig());
70
- return;
71
- }
72
-
73
- const value = getConfigValue(key);
74
- if (value === undefined) {
75
- this.exitWithError(`Configuration key not found: ${key}`);
76
- }
77
-
78
- if (typeof value === 'object') {
79
- this.logger.log(JSON.stringify(value, null, 2));
80
- } else {
81
- this.logger.log(String(value));
82
- }
83
- }
84
-
85
- private handleSet(key: string, value: string): void {
86
- let parsedValue: unknown = value;
87
- try {
88
- parsedValue = JSON.parse(value);
89
- } catch {
90
- // Keep as string if not valid JSON
91
- }
92
-
93
- setConfigValue(key, parsedValue);
94
- this.logger.success(`Set ${key} = ${JSON.stringify(parsedValue)}`);
95
- }
96
-
97
- private handleList(): void {
98
- this.logger.log(displayConfig());
99
- }
100
-
101
- private handleReset(confirmed?: boolean): void {
102
- if (!confirmed) {
103
- this.logger.warn('This will reset all configuration to defaults.');
104
- this.logger.info('Use --yes to confirm.');
105
- return;
106
- }
107
-
108
- saveConfig(DEFAULT_CONFIG);
109
- this.logger.success('Configuration reset to defaults.');
110
- }
111
-
112
- private handlePath(): void {
113
- this.logger.log(path.join(os.homedir(), '.opnet', 'config.json'));
114
- }
115
- }
116
-
117
- export const configCommand = new ConfigCommand().getCommand();
@@ -1,193 +0,0 @@
1
- /**
2
- * Deprecate command - Mark a package version as deprecated
3
- *
4
- * @module commands/DeprecateCommand
5
- */
6
-
7
- import { confirm, input } from '@inquirer/prompts';
8
- import { BaseCommand } from './BaseCommand.js';
9
- import { getPackage, getRegistryContract, getVersion, isVersionImmutable } from '../lib/registry.js';
10
- import { canSign, loadCredentials } from '../lib/credentials.js';
11
- import { CLIWallet } from '../lib/wallet.js';
12
- import {
13
- buildTransactionParams,
14
- checkBalance,
15
- formatSats,
16
- getWalletAddress,
17
- } from '../lib/transaction.js';
18
- import { NetworkName } from '../types/index.js';
19
-
20
- interface DeprecateOptions {
21
- message?: string;
22
- network: string;
23
- yes?: boolean;
24
- }
25
-
26
- export class DeprecateCommand extends BaseCommand {
27
- constructor() {
28
- super('deprecate', 'Mark a package version as deprecated');
29
- }
30
-
31
- protected configure(): void {
32
- this.command
33
- .argument('<package>', 'Package name (e.g., @scope/name or name)')
34
- .argument('[version]', 'Version to deprecate (default: latest)')
35
- .option('-m, --message <message>', 'Deprecation reason/message')
36
- .option('-n, --network <network>', 'Network', 'mainnet')
37
- .option('-y, --yes', 'Skip confirmation')
38
- .action((packageName: string, version?: string, options?: DeprecateOptions) =>
39
- this.execute(packageName, version, options || { network: 'mainnet' }),
40
- );
41
- }
42
-
43
- private async execute(
44
- packageName: string,
45
- version?: string,
46
- options?: DeprecateOptions,
47
- ): Promise<void> {
48
- try {
49
- // Load credentials
50
- this.logger.info('Loading wallet...');
51
- const credentials = loadCredentials();
52
- if (!credentials || !canSign(credentials)) {
53
- this.logger.fail('No credentials configured');
54
- this.logger.warn('Run `opnet login` to configure your wallet.');
55
- process.exit(1);
56
- }
57
- const wallet = CLIWallet.fromCredentials(credentials);
58
- this.logger.success('Wallet loaded');
59
-
60
- // Get package info
61
- this.logger.info('Fetching package info...');
62
- const network = (options?.network || 'mainnet') as NetworkName;
63
- const packageInfo = await getPackage(packageName, network);
64
-
65
- if (!packageInfo) {
66
- this.logger.fail('Package not found');
67
- this.logger.error(`Package "${packageName}" does not exist.`);
68
- process.exit(1);
69
- }
70
-
71
- // Determine version
72
- const targetVersion = version || packageInfo.latestVersion;
73
- if (!targetVersion) {
74
- this.logger.fail('No version specified');
75
- this.logger.error('Package has no versions.');
76
- process.exit(1);
77
- }
78
-
79
- // Get version info
80
- const versionInfo = await getVersion(packageName, targetVersion, network);
81
- if (!versionInfo) {
82
- this.logger.fail('Version not found');
83
- this.logger.error(`Version "${targetVersion}" does not exist.`);
84
- process.exit(1);
85
- }
86
-
87
- if (versionInfo.deprecated) {
88
- this.logger.warn('Already deprecated');
89
- this.logger.log(`Version ${targetVersion} is already deprecated.`);
90
- return;
91
- }
92
-
93
- // Check if immutable
94
- const immutable = await isVersionImmutable(packageName, targetVersion, network);
95
- if (immutable) {
96
- this.logger.fail('Version is immutable');
97
- this.logger.error('This version is past the 72-hour mutability window.');
98
- this.logger.error('Immutable versions cannot be deprecated.');
99
- process.exit(1);
100
- }
101
-
102
- this.logger.success(`Found: ${packageName}@${targetVersion}`);
103
-
104
- // Get deprecation message
105
- let message = options?.message;
106
- if (!message && !options?.yes) {
107
- message = await input({
108
- message: 'Deprecation reason (optional):',
109
- default: '',
110
- });
111
- }
112
- message = message || 'No reason provided';
113
-
114
- // Display summary
115
- this.logger.log('');
116
- this.logger.info('Deprecation Summary');
117
- this.logger.log('─'.repeat(50));
118
- this.logger.log(`Package: ${packageName}`);
119
- this.logger.log(`Version: ${targetVersion}`);
120
- this.logger.log(`Reason: ${message}`);
121
- this.logger.log(`Network: ${options?.network}`);
122
- this.logger.log('');
123
-
124
- // Confirmation
125
- if (!options?.yes) {
126
- const confirmed = await confirm({
127
- message: `Deprecate ${packageName}@${targetVersion}?`,
128
- default: false,
129
- });
130
-
131
- if (!confirmed) {
132
- this.logger.warn('Deprecation cancelled.');
133
- return;
134
- }
135
- }
136
-
137
- // Check wallet balance
138
- this.logger.info('Checking wallet balance...');
139
- const { sufficient, balance } = await checkBalance(wallet, network);
140
- if (!sufficient) {
141
- this.logger.fail('Insufficient balance');
142
- this.logger.error(`Wallet balance: ${formatSats(balance)}`);
143
- this.logger.error('Please fund your wallet before deprecating.');
144
- process.exit(1);
145
- }
146
- this.logger.success(`Wallet balance: ${formatSats(balance)}`);
147
-
148
- // Execute deprecation
149
- this.logger.info('Deprecating version...');
150
-
151
- const sender = getWalletAddress(wallet);
152
- const contract = getRegistryContract(network, sender);
153
- const txParams = buildTransactionParams(wallet, network);
154
-
155
- const deprecateResult = await contract.deprecateVersion(
156
- packageName,
157
- targetVersion,
158
- message,
159
- );
160
-
161
- if (deprecateResult.revert) {
162
- this.logger.fail('Deprecation would fail');
163
- this.logger.error(`Reason: ${deprecateResult.revert}`);
164
- process.exit(1);
165
- }
166
-
167
- if (deprecateResult.estimatedGas) {
168
- this.logger.info(`Estimated gas: ${deprecateResult.estimatedGas} sats`);
169
- }
170
-
171
- const receipt = await deprecateResult.sendTransaction(txParams);
172
-
173
- this.logger.log('');
174
- this.logger.success('Version deprecated successfully!');
175
- this.logger.log('');
176
- this.logger.log(`Package: ${packageName}`);
177
- this.logger.log(`Version: ${targetVersion}`);
178
- this.logger.log(`Reason: ${message}`);
179
- this.logger.log(`Transaction ID: ${receipt.transactionId}`);
180
- this.logger.log(`Fees paid: ${formatSats(receipt.estimatedFees)}`);
181
- this.logger.log('');
182
- } catch (error) {
183
- this.logger.fail('Deprecation failed');
184
- if (this.isUserCancelled(error)) {
185
- this.logger.warn('Deprecation cancelled.');
186
- process.exit(0);
187
- }
188
- this.exitWithError(this.formatError(error));
189
- }
190
- }
191
- }
192
-
193
- export const deprecateCommand = new DeprecateCommand().getCommand();