@btc-vision/cli 1.0.5 → 1.0.6

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 (46) hide show
  1. package/package.json +4 -1
  2. package/.gitattributes +0 -2
  3. package/.github/dependabot.yml +0 -9
  4. package/.github/workflows/ci.yml +0 -48
  5. package/.prettierrc.json +0 -12
  6. package/CONTRIBUTING.md +0 -56
  7. package/NOTICE +0 -17
  8. package/SECURITY.md +0 -35
  9. package/eslint.config.js +0 -41
  10. package/gulpfile.js +0 -41
  11. package/src/commands/AcceptCommand.ts +0 -224
  12. package/src/commands/BaseCommand.ts +0 -59
  13. package/src/commands/CompileCommand.ts +0 -195
  14. package/src/commands/ConfigCommand.ts +0 -117
  15. package/src/commands/DeprecateCommand.ts +0 -193
  16. package/src/commands/InfoCommand.ts +0 -293
  17. package/src/commands/InitCommand.ts +0 -541
  18. package/src/commands/InstallCommand.ts +0 -179
  19. package/src/commands/KeygenCommand.ts +0 -157
  20. package/src/commands/ListCommand.ts +0 -169
  21. package/src/commands/LoginCommand.ts +0 -197
  22. package/src/commands/LogoutCommand.ts +0 -76
  23. package/src/commands/PublishCommand.ts +0 -340
  24. package/src/commands/ScopeRegisterCommand.ts +0 -164
  25. package/src/commands/SearchCommand.ts +0 -140
  26. package/src/commands/SignCommand.ts +0 -110
  27. package/src/commands/TransferCommand.ts +0 -363
  28. package/src/commands/UndeprecateCommand.ts +0 -167
  29. package/src/commands/UpdateCommand.ts +0 -200
  30. package/src/commands/VerifyCommand.ts +0 -228
  31. package/src/commands/WhoamiCommand.ts +0 -113
  32. package/src/index.ts +0 -88
  33. package/src/lib/PackageRegistry.abi.json +0 -765
  34. package/src/lib/PackageRegistry.abi.ts +0 -365
  35. package/src/lib/binary.ts +0 -338
  36. package/src/lib/config.ts +0 -265
  37. package/src/lib/credentials.ts +0 -176
  38. package/src/lib/ipfs.ts +0 -382
  39. package/src/lib/manifest.ts +0 -195
  40. package/src/lib/provider.ts +0 -121
  41. package/src/lib/registry.ts +0 -467
  42. package/src/lib/transaction.ts +0 -205
  43. package/src/lib/wallet.ts +0 -262
  44. package/src/types/PackageRegistry.ts +0 -344
  45. package/src/types/index.ts +0 -147
  46. package/tsconfig.json +0 -25
@@ -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();