@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.
- package/package.json +4 -1
- package/.gitattributes +0 -2
- package/.github/dependabot.yml +0 -9
- package/.github/workflows/ci.yml +0 -48
- package/.prettierrc.json +0 -12
- package/CONTRIBUTING.md +0 -56
- package/NOTICE +0 -17
- package/SECURITY.md +0 -35
- package/eslint.config.js +0 -41
- package/gulpfile.js +0 -41
- package/src/commands/AcceptCommand.ts +0 -224
- package/src/commands/BaseCommand.ts +0 -59
- package/src/commands/CompileCommand.ts +0 -195
- package/src/commands/ConfigCommand.ts +0 -117
- package/src/commands/DeprecateCommand.ts +0 -193
- package/src/commands/InfoCommand.ts +0 -293
- package/src/commands/InitCommand.ts +0 -541
- package/src/commands/InstallCommand.ts +0 -179
- package/src/commands/KeygenCommand.ts +0 -157
- package/src/commands/ListCommand.ts +0 -169
- package/src/commands/LoginCommand.ts +0 -197
- package/src/commands/LogoutCommand.ts +0 -76
- package/src/commands/PublishCommand.ts +0 -340
- package/src/commands/ScopeRegisterCommand.ts +0 -164
- package/src/commands/SearchCommand.ts +0 -140
- package/src/commands/SignCommand.ts +0 -110
- package/src/commands/TransferCommand.ts +0 -363
- package/src/commands/UndeprecateCommand.ts +0 -167
- package/src/commands/UpdateCommand.ts +0 -200
- package/src/commands/VerifyCommand.ts +0 -228
- package/src/commands/WhoamiCommand.ts +0 -113
- package/src/index.ts +0 -88
- package/src/lib/PackageRegistry.abi.json +0 -765
- package/src/lib/PackageRegistry.abi.ts +0 -365
- package/src/lib/binary.ts +0 -338
- package/src/lib/config.ts +0 -265
- package/src/lib/credentials.ts +0 -176
- package/src/lib/ipfs.ts +0 -382
- package/src/lib/manifest.ts +0 -195
- package/src/lib/provider.ts +0 -121
- package/src/lib/registry.ts +0 -467
- package/src/lib/transaction.ts +0 -205
- package/src/lib/wallet.ts +0 -262
- package/src/types/PackageRegistry.ts +0 -344
- package/src/types/index.ts +0 -147
- package/tsconfig.json +0 -25
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Update command - Update installed plugins
|
|
3
|
-
*
|
|
4
|
-
* @module commands/UpdateCommand
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import { BaseCommand } from './BaseCommand.js';
|
|
10
|
-
import { parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
|
|
11
|
-
import { getPackage, getVersion } from '../lib/registry.js';
|
|
12
|
-
import { fetchFromIPFS } from '../lib/ipfs.js';
|
|
13
|
-
import { CLIWallet } from '../lib/wallet.js';
|
|
14
|
-
import { NetworkName } from '../types/index.js';
|
|
15
|
-
|
|
16
|
-
interface UpdateOptions {
|
|
17
|
-
dir?: string;
|
|
18
|
-
network: string;
|
|
19
|
-
skipVerify?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface UpdateInfo {
|
|
23
|
-
file: string;
|
|
24
|
-
name: string;
|
|
25
|
-
currentVersion: string;
|
|
26
|
-
latestVersion: string;
|
|
27
|
-
cid: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export class UpdateCommand extends BaseCommand {
|
|
31
|
-
constructor() {
|
|
32
|
-
super('update', 'Update installed plugins to latest versions');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
protected configure(): void {
|
|
36
|
-
this.command
|
|
37
|
-
.argument('[package]', 'Specific package to update (default: all)')
|
|
38
|
-
.option('-d, --dir <path>', 'Plugins directory (default: ./plugins/)')
|
|
39
|
-
.option('-n, --network <network>', 'Network', 'mainnet')
|
|
40
|
-
.option('--skip-verify', 'Skip signature verification')
|
|
41
|
-
.action((packageName?: string, options?: UpdateOptions) =>
|
|
42
|
-
this.execute(packageName, options || { network: 'mainnet' }),
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private async execute(packageName?: string, options?: UpdateOptions): Promise<void> {
|
|
47
|
-
try {
|
|
48
|
-
const pluginsDir = options?.dir || path.join(process.cwd(), 'plugins');
|
|
49
|
-
|
|
50
|
-
if (!fs.existsSync(pluginsDir)) {
|
|
51
|
-
this.logger.warn('No plugins directory found.');
|
|
52
|
-
this.logger.log(`Expected: ${pluginsDir}`);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Find all .opnet files
|
|
57
|
-
const files = fs.readdirSync(pluginsDir).filter((f) => f.endsWith('.opnet'));
|
|
58
|
-
|
|
59
|
-
if (files.length === 0) {
|
|
60
|
-
this.logger.warn('No plugins installed.');
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const network = (options?.network || 'mainnet') as NetworkName;
|
|
65
|
-
const updates: UpdateInfo[] = [];
|
|
66
|
-
|
|
67
|
-
// Check for updates
|
|
68
|
-
this.logger.info('\nChecking for updates...\n');
|
|
69
|
-
|
|
70
|
-
for (const file of files) {
|
|
71
|
-
const filePath = path.join(pluginsDir, file);
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const data = fs.readFileSync(filePath);
|
|
75
|
-
const parsed = parseOpnetBinary(data);
|
|
76
|
-
const name = parsed.metadata.name;
|
|
77
|
-
|
|
78
|
-
// Filter by package name if specified
|
|
79
|
-
if (packageName && name !== packageName) {
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.logger.info(`Checking ${name}...`);
|
|
84
|
-
|
|
85
|
-
const packageInfo = await getPackage(name, network);
|
|
86
|
-
if (!packageInfo) {
|
|
87
|
-
this.logger.info(`${name}: not found in registry`);
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const currentVersion = parsed.metadata.version;
|
|
92
|
-
const latestVersion = packageInfo.latestVersion;
|
|
93
|
-
|
|
94
|
-
if (currentVersion === latestVersion) {
|
|
95
|
-
this.logger.success(`${name}@${currentVersion}: up to date`);
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Get latest version info
|
|
100
|
-
const versionInfo = await getVersion(name, latestVersion, network);
|
|
101
|
-
if (!versionInfo) {
|
|
102
|
-
this.logger.warn(`${name}: latest version info unavailable`);
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
this.logger.info(`${name}: ${currentVersion} -> ${latestVersion}`);
|
|
107
|
-
updates.push({
|
|
108
|
-
file,
|
|
109
|
-
name,
|
|
110
|
-
currentVersion,
|
|
111
|
-
latestVersion,
|
|
112
|
-
cid: versionInfo.ipfsCid,
|
|
113
|
-
});
|
|
114
|
-
} catch {
|
|
115
|
-
this.logger.warn(`${file}: failed to parse`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (updates.length === 0) {
|
|
120
|
-
this.logger.log('');
|
|
121
|
-
this.logger.success('All plugins are up to date!');
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Display updates
|
|
126
|
-
this.logger.log('');
|
|
127
|
-
this.logger.info('Available Updates:');
|
|
128
|
-
this.logger.log('─'.repeat(60));
|
|
129
|
-
for (const update of updates) {
|
|
130
|
-
this.logger.log(
|
|
131
|
-
` ${update.name}: ${update.currentVersion} -> ${update.latestVersion}`,
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
this.logger.log('');
|
|
135
|
-
|
|
136
|
-
// Perform updates
|
|
137
|
-
for (const update of updates) {
|
|
138
|
-
this.logger.info(`Updating ${update.name}...`);
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
// Download from IPFS
|
|
142
|
-
const result = await fetchFromIPFS(update.cid);
|
|
143
|
-
|
|
144
|
-
// Verify
|
|
145
|
-
const parsed = parseOpnetBinary(result.data);
|
|
146
|
-
|
|
147
|
-
if (!verifyChecksum(parsed)) {
|
|
148
|
-
this.logger.fail(`${update.name}: checksum failed`);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (!options?.skipVerify) {
|
|
153
|
-
const isUnsigned = parsed.publicKey.every((b) => b === 0);
|
|
154
|
-
if (!isUnsigned) {
|
|
155
|
-
const mldsaLevel = ([44, 65, 87] as const)[parsed.mldsaLevel];
|
|
156
|
-
const signatureValid = CLIWallet.verifyMLDSA(
|
|
157
|
-
parsed.checksum,
|
|
158
|
-
parsed.signature,
|
|
159
|
-
parsed.publicKey,
|
|
160
|
-
mldsaLevel,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
if (!signatureValid) {
|
|
164
|
-
this.logger.fail(`${update.name}: signature invalid`);
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Save updated plugin
|
|
171
|
-
const newFileName = `${update.name.replace(/^@/, '').replace(/\//g, '-')}-${update.latestVersion}.opnet`;
|
|
172
|
-
const newFilePath = path.join(pluginsDir, newFileName);
|
|
173
|
-
|
|
174
|
-
fs.writeFileSync(newFilePath, result.data);
|
|
175
|
-
|
|
176
|
-
// Remove old file if different
|
|
177
|
-
const oldFilePath = path.join(pluginsDir, update.file);
|
|
178
|
-
if (oldFilePath !== newFilePath && fs.existsSync(oldFilePath)) {
|
|
179
|
-
fs.unlinkSync(oldFilePath);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
this.logger.success(`${update.name}: updated to ${update.latestVersion}`);
|
|
183
|
-
} catch (error) {
|
|
184
|
-
this.logger.fail(
|
|
185
|
-
`${update.name}: ${error instanceof Error ? error.message : String(error)}`,
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
this.logger.log('');
|
|
191
|
-
this.logger.success('Update complete!');
|
|
192
|
-
this.logger.log('');
|
|
193
|
-
} catch (error) {
|
|
194
|
-
this.logger.fail('Update failed');
|
|
195
|
-
this.exitWithError(this.formatError(error));
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export const updateCommand = new UpdateCommand().getCommand();
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Verify command - Verify .opnet binary signature
|
|
3
|
-
*
|
|
4
|
-
* @module commands/VerifyCommand
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as crypto from 'crypto';
|
|
9
|
-
import { BaseCommand } from './BaseCommand.js';
|
|
10
|
-
import { formatFileSize, parseOpnetBinary, verifyChecksum } from '../lib/binary.js';
|
|
11
|
-
import { CLIWallet } from '../lib/wallet.js';
|
|
12
|
-
import { CLIMldsaLevel } from '../types/index.js';
|
|
13
|
-
|
|
14
|
-
interface VerifyOptions {
|
|
15
|
-
verbose?: boolean;
|
|
16
|
-
json?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class VerifyCommand extends BaseCommand {
|
|
20
|
-
constructor() {
|
|
21
|
-
super('verify', 'Verify a .opnet binary signature and integrity');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
protected configure(): void {
|
|
25
|
-
this.command
|
|
26
|
-
.argument('<file>', 'Path to .opnet file')
|
|
27
|
-
.option('-v, --verbose', 'Show detailed information')
|
|
28
|
-
.option('--json', 'Output as JSON')
|
|
29
|
-
.action((file: string, options: VerifyOptions) => this.execute(file, options));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private execute(file: string, options: VerifyOptions): void {
|
|
33
|
-
try {
|
|
34
|
-
if (!fs.existsSync(file)) {
|
|
35
|
-
if (options.json) {
|
|
36
|
-
this.logger.log(
|
|
37
|
-
JSON.stringify({ valid: false, error: `File not found: ${file}` }),
|
|
38
|
-
);
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
this.exitWithError(`File not found: ${file}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const data = fs.readFileSync(file);
|
|
45
|
-
const fileSize = data.length;
|
|
46
|
-
|
|
47
|
-
// Parse binary
|
|
48
|
-
let parsed;
|
|
49
|
-
try {
|
|
50
|
-
parsed = parseOpnetBinary(data);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
if (options.json) {
|
|
53
|
-
this.logger.log(
|
|
54
|
-
JSON.stringify({
|
|
55
|
-
valid: false,
|
|
56
|
-
error: `Parse error: ${error instanceof Error ? error.message : String(error)}`,
|
|
57
|
-
}),
|
|
58
|
-
);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
this.exitWithError(
|
|
62
|
-
`Parse error: ${error instanceof Error ? error.message : String(error)}`,
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Get MLDSA level from binary
|
|
67
|
-
const mldsaLevel = ([44, 65, 87] as const)[parsed.mldsaLevel] as CLIMldsaLevel;
|
|
68
|
-
|
|
69
|
-
// Verify checksum
|
|
70
|
-
const checksumValid = verifyChecksum(parsed);
|
|
71
|
-
|
|
72
|
-
// Verify signature
|
|
73
|
-
let signatureValid = false;
|
|
74
|
-
let signatureError: string | undefined;
|
|
75
|
-
|
|
76
|
-
// Check if public key is all zeros (unsigned)
|
|
77
|
-
const isUnsigned = parsed.publicKey.every((b) => b === 0);
|
|
78
|
-
|
|
79
|
-
if (isUnsigned) {
|
|
80
|
-
signatureError = 'Binary is unsigned (public key is empty)';
|
|
81
|
-
} else {
|
|
82
|
-
try {
|
|
83
|
-
signatureValid = CLIWallet.verifyMLDSA(
|
|
84
|
-
parsed.checksum,
|
|
85
|
-
parsed.signature,
|
|
86
|
-
parsed.publicKey,
|
|
87
|
-
mldsaLevel,
|
|
88
|
-
);
|
|
89
|
-
} catch (error) {
|
|
90
|
-
signatureError = error instanceof Error ? error.message : String(error);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const isValid = checksumValid && signatureValid;
|
|
95
|
-
|
|
96
|
-
if (options.json) {
|
|
97
|
-
const output = {
|
|
98
|
-
valid: isValid,
|
|
99
|
-
file,
|
|
100
|
-
fileSize,
|
|
101
|
-
formatVersion: parsed.formatVersion,
|
|
102
|
-
mldsaLevel,
|
|
103
|
-
checksumValid,
|
|
104
|
-
signatureValid,
|
|
105
|
-
signatureError,
|
|
106
|
-
isUnsigned,
|
|
107
|
-
metadata: parsed.metadata,
|
|
108
|
-
publicKeyHash: crypto
|
|
109
|
-
.createHash('sha256')
|
|
110
|
-
.update(parsed.publicKey)
|
|
111
|
-
.digest('hex'),
|
|
112
|
-
bytecodeSize: parsed.bytecode.length,
|
|
113
|
-
protoSize: parsed.proto?.length ?? 0,
|
|
114
|
-
};
|
|
115
|
-
this.logger.log(JSON.stringify(output, null, 2));
|
|
116
|
-
process.exit(isValid ? 0 : 1);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Display results
|
|
120
|
-
this.logger.info('\nOPNet Binary Verification\n');
|
|
121
|
-
this.logger.log('─'.repeat(60));
|
|
122
|
-
|
|
123
|
-
// File info
|
|
124
|
-
this.logger.log(`File: ${file}`);
|
|
125
|
-
this.logger.log(`Size: ${formatFileSize(fileSize)}`);
|
|
126
|
-
this.logger.log(`Format Version: ${parsed.formatVersion}`);
|
|
127
|
-
this.logger.log('');
|
|
128
|
-
|
|
129
|
-
// Plugin info
|
|
130
|
-
this.logger.log('Plugin:');
|
|
131
|
-
this.logger.log(` Name: ${parsed.metadata.name}`);
|
|
132
|
-
this.logger.log(` Version: ${parsed.metadata.version}`);
|
|
133
|
-
this.logger.log(` Type: ${parsed.metadata.pluginType}`);
|
|
134
|
-
this.logger.log(` OPNet Version: ${parsed.metadata.opnetVersion}`);
|
|
135
|
-
this.logger.log('');
|
|
136
|
-
|
|
137
|
-
// Cryptographic info
|
|
138
|
-
this.logger.log('Cryptography:');
|
|
139
|
-
this.logger.log(` MLDSA Level: MLDSA-${mldsaLevel}`);
|
|
140
|
-
this.logger.log(` Public Key: ${formatFileSize(parsed.publicKey.length)}`);
|
|
141
|
-
this.logger.log(` Signature: ${formatFileSize(parsed.signature.length)}`);
|
|
142
|
-
|
|
143
|
-
if (!isUnsigned) {
|
|
144
|
-
const pkHash = crypto.createHash('sha256').update(parsed.publicKey).digest('hex');
|
|
145
|
-
this.logger.log(` PubKey Hash: ${pkHash.substring(0, 16)}...`);
|
|
146
|
-
}
|
|
147
|
-
this.logger.log('');
|
|
148
|
-
|
|
149
|
-
// Verification results
|
|
150
|
-
this.logger.log('Verification:');
|
|
151
|
-
this.logger.log(` Checksum: ${checksumValid ? 'VALID' : 'INVALID'}`);
|
|
152
|
-
|
|
153
|
-
if (isUnsigned) {
|
|
154
|
-
this.logger.log(` Signature: UNSIGNED`);
|
|
155
|
-
} else if (signatureError) {
|
|
156
|
-
this.logger.log(` Signature: ERROR - ${signatureError}`);
|
|
157
|
-
} else {
|
|
158
|
-
this.logger.log(` Signature: ${signatureValid ? 'VALID' : 'INVALID'}`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
this.logger.log('');
|
|
162
|
-
this.logger.log('─'.repeat(60));
|
|
163
|
-
|
|
164
|
-
if (isUnsigned) {
|
|
165
|
-
this.logger.warn('WARNING: This binary is unsigned and cannot be published.');
|
|
166
|
-
this.logger.warn('Use `opnet sign` to sign it.');
|
|
167
|
-
} else if (isValid) {
|
|
168
|
-
this.logger.success('VERIFIED: Binary is valid and properly signed.');
|
|
169
|
-
} else {
|
|
170
|
-
this.logger.fail('FAILED: Binary verification failed.');
|
|
171
|
-
if (!checksumValid) {
|
|
172
|
-
this.logger.error(' - Checksum mismatch (binary may be corrupted)');
|
|
173
|
-
}
|
|
174
|
-
if (!signatureValid && !signatureError) {
|
|
175
|
-
this.logger.error(' - Signature invalid (binary may be tampered)');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
this.logger.log('');
|
|
179
|
-
|
|
180
|
-
// Verbose output
|
|
181
|
-
if (options.verbose) {
|
|
182
|
-
this.logger.log('Sizes:');
|
|
183
|
-
this.logger.log(` Metadata: ${formatFileSize(parsed.rawMetadata.length)}`);
|
|
184
|
-
this.logger.log(` Bytecode: ${formatFileSize(parsed.bytecode.length)}`);
|
|
185
|
-
this.logger.log(` Proto: ${formatFileSize(parsed.proto?.length ?? 0)}`);
|
|
186
|
-
this.logger.log('');
|
|
187
|
-
|
|
188
|
-
this.logger.log('Checksums:');
|
|
189
|
-
this.logger.log(` Stored: ${parsed.checksum.toString('hex')}`);
|
|
190
|
-
this.logger.log('');
|
|
191
|
-
|
|
192
|
-
this.logger.log('Author:');
|
|
193
|
-
this.logger.log(` Name: ${parsed.metadata.author.name}`);
|
|
194
|
-
if (parsed.metadata.author.email) {
|
|
195
|
-
this.logger.log(` Email: ${parsed.metadata.author.email}`);
|
|
196
|
-
}
|
|
197
|
-
this.logger.log('');
|
|
198
|
-
|
|
199
|
-
this.logger.log('Permissions:');
|
|
200
|
-
const perms = parsed.metadata.permissions;
|
|
201
|
-
if (perms) {
|
|
202
|
-
this.logger.log(` Database: ${perms.database?.enabled ? 'Yes' : 'No'}`);
|
|
203
|
-
this.logger.log(
|
|
204
|
-
` Block Hooks: ${perms.blocks?.preProcess || perms.blocks?.postProcess || perms.blocks?.onChange ? 'Yes' : 'No'}`,
|
|
205
|
-
);
|
|
206
|
-
this.logger.log(
|
|
207
|
-
` Epoch Hooks: ${perms.epochs?.onChange || perms.epochs?.onFinalized ? 'Yes' : 'No'}`,
|
|
208
|
-
);
|
|
209
|
-
this.logger.log(` Mempool Feed: ${perms.mempool?.txFeed ? 'Yes' : 'No'}`);
|
|
210
|
-
this.logger.log(` API Endpoints: ${perms.api?.addEndpoints ? 'Yes' : 'No'}`);
|
|
211
|
-
this.logger.log(` Websocket: ${perms.api?.addWebsocket ? 'Yes' : 'No'}`);
|
|
212
|
-
this.logger.log(
|
|
213
|
-
` Filesystem: ${perms.filesystem?.configDir || perms.filesystem?.tempDir ? 'Yes' : 'No'}`,
|
|
214
|
-
);
|
|
215
|
-
} else {
|
|
216
|
-
this.logger.log(' (none configured)');
|
|
217
|
-
}
|
|
218
|
-
this.logger.log('');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
process.exit(isValid ? 0 : 1);
|
|
222
|
-
} catch (error) {
|
|
223
|
-
this.exitWithError(this.formatError(error));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export const verifyCommand = new VerifyCommand().getCommand();
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Whoami command - Display current identity
|
|
3
|
-
*
|
|
4
|
-
* @module commands/WhoamiCommand
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { BaseCommand } from './BaseCommand.js';
|
|
8
|
-
import {
|
|
9
|
-
getCredentialSource,
|
|
10
|
-
hasCredentials,
|
|
11
|
-
loadCredentials,
|
|
12
|
-
maskSensitive,
|
|
13
|
-
} from '../lib/credentials.js';
|
|
14
|
-
import { CLIWallet } from '../lib/wallet.js';
|
|
15
|
-
|
|
16
|
-
interface WhoamiOptions {
|
|
17
|
-
verbose?: boolean;
|
|
18
|
-
publicKey?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class WhoamiCommand extends BaseCommand {
|
|
22
|
-
constructor() {
|
|
23
|
-
super('whoami', 'Display current wallet identity and configuration');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
protected configure(): void {
|
|
27
|
-
this.command
|
|
28
|
-
.option('-v, --verbose', 'Show detailed information')
|
|
29
|
-
.option('--public-key', 'Show full MLDSA public key')
|
|
30
|
-
.action((options: WhoamiOptions) => this.execute(options));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private execute(options: WhoamiOptions): void {
|
|
34
|
-
try {
|
|
35
|
-
if (!hasCredentials()) {
|
|
36
|
-
this.logger.warn('Not logged in.');
|
|
37
|
-
this.logger.info('Run `opnet login` to configure your wallet.');
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const credentials = loadCredentials();
|
|
42
|
-
if (!credentials) {
|
|
43
|
-
this.logger.warn('No credentials found.');
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const source = getCredentialSource();
|
|
48
|
-
|
|
49
|
-
this.logger.info('\nOPNet Identity\n');
|
|
50
|
-
this.logger.log('─'.repeat(50));
|
|
51
|
-
|
|
52
|
-
this.logger.log(`Network: ${credentials.network}`);
|
|
53
|
-
this.logger.log(`MLDSA Level: ${credentials.mldsaLevel}`);
|
|
54
|
-
this.logger.log(`Auth Source: ${source}`);
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
const wallet = CLIWallet.fromCredentials(credentials);
|
|
58
|
-
|
|
59
|
-
this.logger.log('');
|
|
60
|
-
this.logger.log(`P2TR Address: ${wallet.p2trAddress}`);
|
|
61
|
-
this.logger.log(`MLDSA PubKey Hash: ${wallet.mldsaPublicKeyHash}`);
|
|
62
|
-
|
|
63
|
-
if (options.publicKey) {
|
|
64
|
-
this.logger.log('');
|
|
65
|
-
this.logger.log('MLDSA Public Key:');
|
|
66
|
-
this.logger.log(wallet.mldsaPublicKey.toString('hex'));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (options.verbose) {
|
|
70
|
-
this.logger.log('');
|
|
71
|
-
this.logger.log('─'.repeat(50));
|
|
72
|
-
this.logger.log('Details:');
|
|
73
|
-
this.logger.log(` Security Level: MLDSA-${credentials.mldsaLevel}`);
|
|
74
|
-
this.logger.log(` Public Key Size: ${wallet.mldsaPublicKey.length} bytes`);
|
|
75
|
-
|
|
76
|
-
if (credentials.mnemonic) {
|
|
77
|
-
this.logger.log(' Auth Method: BIP-39 Mnemonic');
|
|
78
|
-
this.logger.log(` Mnemonic: ${maskSensitive(credentials.mnemonic, 8)}`);
|
|
79
|
-
} else {
|
|
80
|
-
this.logger.log(' Auth Method: WIF + MLDSA Keys');
|
|
81
|
-
if (credentials.wif) {
|
|
82
|
-
this.logger.log(` WIF: ${maskSensitive(credentials.wif, 4)}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
} catch (error) {
|
|
87
|
-
this.logger.log('');
|
|
88
|
-
this.logger.warn('Could not load wallet details.');
|
|
89
|
-
if (options.verbose) {
|
|
90
|
-
this.logger.debug(` Error: ${this.formatError(error)}`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.logger.log('');
|
|
94
|
-
if (credentials.mnemonic) {
|
|
95
|
-
this.logger.log(`Auth Method: BIP-39 Mnemonic`);
|
|
96
|
-
if (options.verbose) {
|
|
97
|
-
this.logger.log(
|
|
98
|
-
`Mnemonic: ${maskSensitive(credentials.mnemonic, 8)}`,
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
this.logger.log(`Auth Method: WIF + MLDSA Keys`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
this.logger.log('');
|
|
107
|
-
} catch (error) {
|
|
108
|
-
this.exitWithError(this.formatError(error));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export const whoamiCommand = new WhoamiCommand().getCommand();
|
package/src/index.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* OPNet CLI - Command Line Interface for OPNet Plugin Ecosystem
|
|
4
|
-
*
|
|
5
|
-
* @module @btc-vision/cli
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Command } from 'commander';
|
|
9
|
-
import { Logger } from '@btc-vision/logger';
|
|
10
|
-
|
|
11
|
-
// Commands
|
|
12
|
-
import { configCommand } from './commands/ConfigCommand.js';
|
|
13
|
-
import { loginCommand } from './commands/LoginCommand.js';
|
|
14
|
-
import { logoutCommand } from './commands/LogoutCommand.js';
|
|
15
|
-
import { whoamiCommand } from './commands/WhoamiCommand.js';
|
|
16
|
-
import { keygenCommand } from './commands/KeygenCommand.js';
|
|
17
|
-
import { initCommand } from './commands/InitCommand.js';
|
|
18
|
-
import { compileCommand } from './commands/CompileCommand.js';
|
|
19
|
-
import { verifyCommand } from './commands/VerifyCommand.js';
|
|
20
|
-
import { infoCommand } from './commands/InfoCommand.js';
|
|
21
|
-
import { signCommand } from './commands/SignCommand.js';
|
|
22
|
-
import { publishCommand } from './commands/PublishCommand.js';
|
|
23
|
-
import { deprecateCommand } from './commands/DeprecateCommand.js';
|
|
24
|
-
import { undeprecateCommand } from './commands/UndeprecateCommand.js';
|
|
25
|
-
import { transferCommand } from './commands/TransferCommand.js';
|
|
26
|
-
import { acceptCommand } from './commands/AcceptCommand.js';
|
|
27
|
-
import { scopeRegisterCommand } from './commands/ScopeRegisterCommand.js';
|
|
28
|
-
import { installCommand } from './commands/InstallCommand.js';
|
|
29
|
-
import { updateCommand } from './commands/UpdateCommand.js';
|
|
30
|
-
import { listCommand } from './commands/ListCommand.js';
|
|
31
|
-
import { searchCommand } from './commands/SearchCommand.js';
|
|
32
|
-
|
|
33
|
-
const logger = new Logger();
|
|
34
|
-
const program = new Command();
|
|
35
|
-
|
|
36
|
-
program
|
|
37
|
-
.name('opnet')
|
|
38
|
-
.description('OPNet CLI - Build, sign, and publish plugins for the OPNet ecosystem')
|
|
39
|
-
.version('1.0.0');
|
|
40
|
-
|
|
41
|
-
// Configuration commands
|
|
42
|
-
program.addCommand(configCommand);
|
|
43
|
-
program.addCommand(loginCommand);
|
|
44
|
-
program.addCommand(logoutCommand);
|
|
45
|
-
program.addCommand(whoamiCommand);
|
|
46
|
-
program.addCommand(keygenCommand);
|
|
47
|
-
|
|
48
|
-
// Plugin development commands
|
|
49
|
-
program.addCommand(initCommand);
|
|
50
|
-
program.addCommand(compileCommand);
|
|
51
|
-
program.addCommand(verifyCommand);
|
|
52
|
-
program.addCommand(infoCommand);
|
|
53
|
-
program.addCommand(signCommand);
|
|
54
|
-
|
|
55
|
-
// Registry commands
|
|
56
|
-
program.addCommand(publishCommand);
|
|
57
|
-
program.addCommand(deprecateCommand);
|
|
58
|
-
program.addCommand(undeprecateCommand);
|
|
59
|
-
program.addCommand(transferCommand);
|
|
60
|
-
program.addCommand(acceptCommand);
|
|
61
|
-
program.addCommand(scopeRegisterCommand);
|
|
62
|
-
program.addCommand(installCommand);
|
|
63
|
-
program.addCommand(updateCommand);
|
|
64
|
-
program.addCommand(listCommand);
|
|
65
|
-
program.addCommand(searchCommand);
|
|
66
|
-
|
|
67
|
-
// Error handling
|
|
68
|
-
program.showHelpAfterError();
|
|
69
|
-
program.showSuggestionAfterError();
|
|
70
|
-
|
|
71
|
-
// Custom error handling
|
|
72
|
-
program.exitOverride((err) => {
|
|
73
|
-
if (err.code === 'commander.help') {
|
|
74
|
-
process.exit(0);
|
|
75
|
-
}
|
|
76
|
-
if (err.code === 'commander.version') {
|
|
77
|
-
process.exit(0);
|
|
78
|
-
}
|
|
79
|
-
logger.error(`Error: ${err.message}`);
|
|
80
|
-
process.exit(1);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Parse command line arguments
|
|
84
|
-
program.parseAsync(process.argv).catch((error: unknown) => {
|
|
85
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
86
|
-
logger.error(`Error: ${message}`);
|
|
87
|
-
process.exit(1);
|
|
88
|
-
});
|