@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
package/src/lib/binary.ts CHANGED
@@ -184,28 +184,21 @@ export function verifyChecksum(parsed: IParsedPluginFile): boolean {
184
184
  * Build a .opnet binary file
185
185
  *
186
186
  * @param options - Build options
187
- * @returns The assembled binary
187
+ * @returns The assembled binary and the checksum that was signed
188
188
  */
189
189
  export function buildOpnetBinary(options: {
190
190
  mldsaLevel: CLIMldsaLevel;
191
191
  publicKey: Buffer;
192
- signature: Buffer;
193
192
  metadata: IPluginMetadata;
194
193
  bytecode: Buffer;
195
194
  proto?: Buffer;
196
- }): Buffer {
197
- const {
198
- mldsaLevel,
199
- publicKey,
200
- signature,
201
- metadata,
202
- bytecode,
203
- proto = Buffer.alloc(0),
204
- } = options;
195
+ signFn?: (checksum: Buffer) => Buffer;
196
+ }): { binary: Buffer; checksum: Buffer } {
197
+ const { mldsaLevel, publicKey, metadata, bytecode, proto = Buffer.alloc(0), signFn } = options;
205
198
 
206
199
  const sdkLevel = cliLevelToMLDSALevel(mldsaLevel);
207
200
 
208
- // Validate sizes
201
+ // Validate public key size
209
202
  const expectedPkSize = MLDSA_PUBLIC_KEY_SIZES[sdkLevel];
210
203
  const expectedSigSize = MLDSA_SIGNATURE_SIZES[sdkLevel];
211
204
 
@@ -215,19 +208,28 @@ export function buildOpnetBinary(options: {
215
208
  );
216
209
  }
217
210
 
211
+ // First pass: compute checksum without the checksum field set
212
+ const tempMetadata = { ...metadata, checksum: '' };
213
+ const tempMetadataBytes = Buffer.from(JSON.stringify(tempMetadata), 'utf-8');
214
+ const checksum = computeChecksum(tempMetadataBytes, bytecode, proto);
215
+ const checksumHex = `sha256:${checksum.toString('hex')}`;
216
+
217
+ // Second pass: serialize metadata with checksum included
218
+ const finalMetadata = { ...metadata, checksum: checksumHex };
219
+ const metadataBytes = Buffer.from(JSON.stringify(finalMetadata), 'utf-8');
220
+
221
+ // Recompute checksum with the final metadata (includes checksum field)
222
+ const finalChecksum = computeChecksum(metadataBytes, bytecode, proto);
223
+
224
+ // Sign the final checksum (this is what gets verified)
225
+ const signature = signFn ? signFn(finalChecksum) : Buffer.alloc(expectedSigSize);
226
+
218
227
  if (signature.length !== expectedSigSize) {
219
228
  throw new Error(
220
229
  `Signature size mismatch: expected ${expectedSigSize}, got ${signature.length}`,
221
230
  );
222
231
  }
223
232
 
224
- // Serialize metadata
225
- const metadataStr = JSON.stringify(metadata);
226
- const metadataBytes = Buffer.from(metadataStr, 'utf-8');
227
-
228
- // Compute checksum
229
- const checksum = computeChecksum(metadataBytes, bytecode, proto);
230
-
231
233
  // Calculate total size
232
234
  const totalSize =
233
235
  8 + // magic
@@ -291,10 +293,10 @@ export function buildOpnetBinary(options: {
291
293
  proto.copy(buffer, offset);
292
294
  offset += proto.length;
293
295
 
294
- // Checksum
295
- checksum.copy(buffer, offset);
296
+ // Checksum (use finalChecksum which was computed with metadata containing checksum hex)
297
+ finalChecksum.copy(buffer, offset);
296
298
 
297
- return buffer;
299
+ return { binary: buffer, checksum: finalChecksum };
298
300
  }
299
301
 
300
302
  /**
package/src/lib/config.ts CHANGED
@@ -10,7 +10,6 @@ import * as fs from 'fs';
10
10
  import * as path from 'path';
11
11
  import * as os from 'os';
12
12
  import { CLIConfig, CLIMldsaLevel, NetworkName } from '../types/index.js';
13
- import { Address } from '@btc-vision/transaction';
14
13
 
15
14
  /** Default configuration directory */
16
15
  const CONFIG_DIR = path.join(os.homedir(), '.opnet');
@@ -38,9 +37,9 @@ const DEFAULT_CONFIG: CLIConfig = {
38
37
  ipfsPinningApiKey: '',
39
38
  ipfsPinningAuthHeader: 'Authorization',
40
39
  registryAddresses: {
41
- mainnet: Address.dead().toHex(), // TODO: Set once deployed
42
- testnet: Address.dead().toHex(), // TODO: Set once deployed
43
- regtest: Address.dead().toHex(), // TODO: Set once deployed
40
+ mainnet: '', // TODO: Set once deployed
41
+ testnet: '', // TODO: Set once deployed
42
+ regtest: '', // TODO: Set once deployed
44
43
  },
45
44
  defaultMldsaLevel: 44,
46
45
  indexerUrl: 'https://indexer.opnet.org',
package/src/lib/ipfs.ts CHANGED
@@ -243,7 +243,6 @@ export async function fetchFromIPFS(cid: string): Promise<FetchResult> {
243
243
  } catch (error) {
244
244
  lastError = error instanceof Error ? error : new Error(String(error));
245
245
  // Try next gateway
246
- continue;
247
246
  }
248
247
  }
249
248
 
@@ -89,6 +89,10 @@ export function validatePermissions(permissions: IPluginPermissions): string[] {
89
89
  /**
90
90
  * Load and validate a plugin manifest from file
91
91
  *
92
+ * Note: This performs basic validation suitable for source manifests.
93
+ * The SDK's strict validation requires fields like 'checksum' which
94
+ * are only computed during compilation, not in source plugin.json.
95
+ *
92
96
  * @param manifestPath - Path to plugin.json
93
97
  * @returns The loaded manifest or throws with validation errors
94
98
  */
@@ -107,13 +111,33 @@ export function loadManifest(manifestPath: string): IPluginMetadata {
107
111
  throw new Error(`Failed to parse manifest: ${e instanceof Error ? e.message : String(e)}`);
108
112
  }
109
113
 
110
- const result = validateManifest(manifest);
111
- if (!result.valid) {
112
- const errorList = result.errors.map((e) => ` - ${e.path}: ${e.message}`).join('\n');
113
- throw new Error(`Invalid manifest:\n${errorList}`);
114
+ // Basic validation for source manifests (checksum is computed during compilation)
115
+ const errors: string[] = [];
116
+ if (!manifest.name || typeof manifest.name !== 'string') {
117
+ errors.push('name is required');
118
+ }
119
+ if (!manifest.version || typeof manifest.version !== 'string') {
120
+ errors.push('version is required');
121
+ }
122
+ if (!manifest.author || typeof manifest.author !== 'object') {
123
+ errors.push('author is required');
124
+ }
125
+ if (!manifest.pluginType || !['standalone', 'library'].includes(manifest.pluginType)) {
126
+ errors.push('pluginType must be "standalone" or "library"');
127
+ }
128
+
129
+ if (errors.length > 0) {
130
+ throw new Error(`Invalid manifest:\n${errors.map((e) => ` - ${e}`).join('\n')}`);
131
+ }
132
+
133
+ // Set default checksum for compilation (will be computed)
134
+ // Cast to mutable to allow setting checksum
135
+ const result = manifest as { -readonly [K in keyof IPluginMetadata]: IPluginMetadata[K] };
136
+ if (!result.checksum) {
137
+ result.checksum = '';
114
138
  }
115
139
 
116
- return manifest as IPluginMetadata;
140
+ return result as IPluginMetadata;
117
141
  }
118
142
 
119
143
  /**
@@ -139,15 +163,14 @@ export function createManifest(options: {
139
163
  email?: string;
140
164
  description?: string;
141
165
  pluginType: 'standalone' | 'library';
142
- }): IPluginMetadata {
166
+ }): Omit<IPluginMetadata, 'checksum'> {
143
167
  return {
144
168
  name: options.name,
145
169
  version: '1.0.0',
146
- opnetVersion: '^1.0.0',
170
+ opnetVersion: '>=0.0.1',
147
171
  main: 'dist/index.jsc',
148
172
  target: 'bytenode',
149
173
  type: 'plugin',
150
- checksum: '',
151
174
  author: {
152
175
  name: options.author,
153
176
  email: options.email,