neozip-cli 0.75.2-beta → 0.80.0

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 (31) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/DOCUMENTATION.md +9 -1
  3. package/README.md +22 -10
  4. package/dist/src/commands/mintTimestampProof.js +335 -0
  5. package/dist/src/commands/verifyEmail.js +146 -0
  6. package/dist/src/config/ConfigSetup.js +50 -20
  7. package/dist/src/config/ConfigStore.js +36 -3
  8. package/dist/src/index.js +1 -1
  9. package/dist/src/neolist.js +18 -10
  10. package/dist/src/neounzip.js +305 -60
  11. package/dist/src/neozip/blockchain.js +5 -5
  12. package/dist/src/neozip/createZip.js +207 -41
  13. package/dist/src/neozip/upgradeZip.js +182 -0
  14. package/dist/src/neozip.js +143 -8
  15. package/env.example +10 -0
  16. package/package.json +87 -81
  17. package/dist/neozipkit-bundles/blockchain.js +0 -13725
  18. package/dist/neozipkit-bundles/browser.js +0 -6186
  19. package/dist/neozipkit-bundles/core.js +0 -3839
  20. package/dist/neozipkit-bundles/node.js +0 -17730
  21. package/dist/neozipkit-wrappers/blockchain/core/contracts.js +0 -16
  22. package/dist/neozipkit-wrappers/blockchain/index.js +0 -2
  23. package/dist/neozipkit-wrappers/core/ZipDecompress.js +0 -2
  24. package/dist/neozipkit-wrappers/core/components/HashCalculator.js +0 -2
  25. package/dist/neozipkit-wrappers/core/components/Logger.js +0 -2
  26. package/dist/neozipkit-wrappers/core/constants/Errors.js +0 -2
  27. package/dist/neozipkit-wrappers/core/constants/Headers.js +0 -2
  28. package/dist/neozipkit-wrappers/core/encryption/ZipCrypto.js +0 -7
  29. package/dist/neozipkit-wrappers/core/index.js +0 -3
  30. package/dist/neozipkit-wrappers/index.js +0 -13
  31. package/dist/neozipkit-wrappers/node/index.js +0 -2
@@ -41,7 +41,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
41
41
  exports.ConfigSetup = void 0;
42
42
  const readline = __importStar(require("readline"));
43
43
  const ConfigStore_1 = require("./ConfigStore");
44
- const blockchain_1 = require("neozipkit/blockchain");
44
+ const neozip_blockchain_1 = require("neozip-blockchain");
45
+ function resolveScriptPath(jsPath) {
46
+ if (typeof __filename !== 'undefined' && __filename.endsWith('.ts')) {
47
+ return jsPath.replace(/\.js$/, '.ts');
48
+ }
49
+ return jsPath;
50
+ }
45
51
  class ConfigSetup {
46
52
  constructor() {
47
53
  this.rl = readline.createInterface({
@@ -148,7 +154,7 @@ class ConfigSetup {
148
154
  // Dynamically build network options from CONTRACT_CONFIGS
149
155
  // CONTRACT_CONFIGS is already ordered correctly: Base (testnet/mainnet), Arbitrum (testnet/mainnet), Ethereum
150
156
  const networkOptions = [];
151
- const networkConfigs = Object.values(blockchain_1.CONTRACT_CONFIGS);
157
+ const networkConfigs = Object.values(neozip_blockchain_1.CONTRACT_CONFIGS);
152
158
  // Verify we're loading networks
153
159
  if (networkConfigs.length === 0) {
154
160
  console.error('❌ Error: No networks found in CONTRACT_CONFIGS');
@@ -160,7 +166,7 @@ class ConfigSetup {
160
166
  // Use the primary alias (first nameAlias) or network name as value
161
167
  const primaryAlias = config.nameAliases && config.nameAliases.length > 0
162
168
  ? config.nameAliases[0]
163
- : (0, blockchain_1.normalizeNetworkName)(config.network);
169
+ : (0, neozip_blockchain_1.normalizeNetworkName)(config.network);
164
170
  // Determine description based on network type
165
171
  const isTestnet = config.network.toLowerCase().includes('testnet') ||
166
172
  config.network.toLowerCase().includes('sepolia');
@@ -188,7 +194,7 @@ class ConfigSetup {
188
194
  }
189
195
  if (useCustomRpc === 'y') {
190
196
  // Get the selected network config to show default RPC
191
- const selectedNetworkConfig = (0, blockchain_1.getNetworkByName)(network);
197
+ const selectedNetworkConfig = (0, neozip_blockchain_1.getNetworkByName)(network);
192
198
  // Prompt for RPC URL for the selected network
193
199
  if (selectedNetworkConfig) {
194
200
  const defaultRpc = selectedNetworkConfig.rpcUrls && selectedNetworkConfig.rpcUrls.length > 0
@@ -197,12 +203,12 @@ class ConfigSetup {
197
203
  // Use primary alias as RPC key for consistency (or normalized network name as fallback)
198
204
  const rpcKey = (selectedNetworkConfig.nameAliases && selectedNetworkConfig.nameAliases.length > 0)
199
205
  ? selectedNetworkConfig.nameAliases[0]
200
- : (0, blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network);
206
+ : (0, neozip_blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network);
201
207
  // Check both new format and legacy format for backward compatibility
202
208
  const existingRpc = rpcConfig[rpcKey]
203
- || rpcConfig[(0, blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network).replace(/\s+/g, '')]
209
+ || rpcConfig[(0, neozip_blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network).replace(/\s+/g, '')]
204
210
  || existingConfig?.rpc?.[rpcKey]
205
- || existingConfig?.rpc?.[(0, blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network).replace(/\s+/g, '')];
211
+ || existingConfig?.rpc?.[(0, neozip_blockchain_1.normalizeNetworkName)(selectedNetworkConfig.network).replace(/\s+/g, '')];
206
212
  const customRpc = await this.prompt(` ${selectedNetworkConfig.network} RPC URL`, existingRpc || defaultRpc);
207
213
  if (customRpc) {
208
214
  rpcConfig[rpcKey] = customRpc;
@@ -218,21 +224,21 @@ class ConfigSetup {
218
224
  // Skip the already configured network
219
225
  const configAlias = config.nameAliases && config.nameAliases.length > 0
220
226
  ? config.nameAliases[0]
221
- : (0, blockchain_1.normalizeNetworkName)(config.network);
227
+ : (0, neozip_blockchain_1.normalizeNetworkName)(config.network);
222
228
  if (configAlias === network)
223
229
  continue;
224
230
  // Use primary alias as RPC key for consistency (or normalized network name as fallback)
225
231
  const rpcKey = (config.nameAliases && config.nameAliases.length > 0)
226
232
  ? config.nameAliases[0]
227
- : (0, blockchain_1.normalizeNetworkName)(config.network);
233
+ : (0, neozip_blockchain_1.normalizeNetworkName)(config.network);
228
234
  const defaultRpc = config.rpcUrls && config.rpcUrls.length > 0
229
235
  ? config.rpcUrls[0]
230
236
  : '';
231
237
  // Check both new format and legacy format for backward compatibility
232
238
  const existingRpc = rpcConfig[rpcKey]
233
- || rpcConfig[(0, blockchain_1.normalizeNetworkName)(config.network).replace(/\s+/g, '')]
239
+ || rpcConfig[(0, neozip_blockchain_1.normalizeNetworkName)(config.network).replace(/\s+/g, '')]
234
240
  || existingConfig?.rpc?.[rpcKey]
235
- || existingConfig?.rpc?.[(0, blockchain_1.normalizeNetworkName)(config.network).replace(/\s+/g, '')];
241
+ || existingConfig?.rpc?.[(0, neozip_blockchain_1.normalizeNetworkName)(config.network).replace(/\s+/g, '')];
236
242
  const customRpc = await this.prompt(` ${config.network} RPC URL`, existingRpc || defaultRpc);
237
243
  if (customRpc) {
238
244
  rpcConfig[rpcKey] = customRpc;
@@ -274,12 +280,29 @@ class ConfigSetup {
274
280
  verbose = verboseStr === 'y';
275
281
  debugEnabled = debugStr === 'y';
276
282
  }
277
- // Build configuration object
283
+ // 6. Zipstamp Email (optional - for timestamped ZIPs)
284
+ console.log('\n6️⃣ Zipstamp Email (optional)');
285
+ const configureZipstamp = await this.promptSelection('Configure email for Zipstamp timestamping?', [
286
+ { value: 'n', label: 'No', description: 'Skip - run neozip verify-email later if needed' },
287
+ { value: 'y', label: 'Yes', description: 'Set email (must verify with neozip verify-email)' }
288
+ ], 'n');
289
+ let zipstampEmail;
290
+ if (configureZipstamp === 'y') {
291
+ zipstampEmail = await this.prompt(' Zipstamp timestamp email', existingConfig?.zipstamp?.timestampEmail || '');
292
+ if (zipstampEmail) {
293
+ console.log(' 💡 Run "neozip verify-email" to verify this email before creating timestamped ZIPs.');
294
+ }
295
+ }
296
+ // Build configuration object (preserve existing zipstamp if not configuring)
297
+ const zipstampConfig = zipstampEmail !== undefined
298
+ ? (zipstampEmail ? { timestampEmail: zipstampEmail } : undefined)
299
+ : existingConfig?.zipstamp;
278
300
  const config = {
279
301
  wallet: {
280
302
  privateKey,
281
303
  network,
282
304
  },
305
+ zipstamp: zipstampConfig,
283
306
  rpc: Object.keys(rpcConfig).length > 0 ? rpcConfig : undefined,
284
307
  gas: gasMultiplier || maxGasPrice ? {
285
308
  multiplier: gasMultiplier,
@@ -343,16 +366,17 @@ class ConfigSetup {
343
366
  const hasPrivateKey = config.walletKey !== null;
344
367
  console.log('What would you like to do?');
345
368
  console.log(' 1. Modify configuration (update settings)');
369
+ console.log(' 2. Verify Zipstamp email (for timestamped ZIPs)');
346
370
  if (hasPrivateKey) {
347
- console.log(' 2. Delete private key (remove wallet key from configuration)');
348
- console.log(' 3. Reset to defaults (delete entire configuration)');
349
- console.log(' 4. Exit');
371
+ console.log(' 3. Delete private key (remove wallet key from configuration)');
372
+ console.log(' 4. Reset to defaults (delete entire configuration)');
373
+ console.log(' 5. Exit');
350
374
  }
351
375
  else {
352
- console.log(' 2. Reset to defaults (delete entire configuration)');
353
- console.log(' 3. Exit');
376
+ console.log(' 3. Reset to defaults (delete entire configuration)');
377
+ console.log(' 4. Exit');
354
378
  }
355
- const maxChoice = hasPrivateKey ? 4 : 3;
379
+ const maxChoice = hasPrivateKey ? 5 : 4;
356
380
  rl.question(`\nEnter choice (1-${maxChoice}): `, async (answer) => {
357
381
  const choice = parseInt(answer);
358
382
  switch (choice) {
@@ -363,6 +387,12 @@ class ConfigSetup {
363
387
  process.exit(success ? 0 : 1);
364
388
  break;
365
389
  case 2:
390
+ rl.close();
391
+ const { runVerifyEmail } = await import(resolveScriptPath('../commands/verifyEmail.js'));
392
+ const verifySuccess = await runVerifyEmail();
393
+ process.exit(verifySuccess ? 0 : 1);
394
+ break;
395
+ case 3:
366
396
  if (hasPrivateKey) {
367
397
  // Delete private key only
368
398
  rl.question('\n⚠️ Are you sure you want to delete your private key? (y/n): ', (confirm) => {
@@ -403,7 +433,7 @@ class ConfigSetup {
403
433
  });
404
434
  }
405
435
  break;
406
- case 3:
436
+ case 4:
407
437
  if (hasPrivateKey) {
408
438
  // Reset entire config
409
439
  rl.question('\n⚠️ Are you sure you want to delete your wallet configuration? (y/n): ', (confirm) => {
@@ -429,7 +459,7 @@ class ConfigSetup {
429
459
  process.exit(0);
430
460
  }
431
461
  break;
432
- case 4:
462
+ case 5:
433
463
  if (hasPrivateKey) {
434
464
  // Exit
435
465
  console.log('');
@@ -42,9 +42,10 @@ exports.ConfigStore = void 0;
42
42
  const fs = __importStar(require("fs"));
43
43
  const path = __importStar(require("path"));
44
44
  const os = __importStar(require("os"));
45
- const blockchain_1 = require("neozipkit/blockchain");
45
+ const neozip_blockchain_1 = require("neozip-blockchain");
46
46
  const DEFAULTS = {
47
47
  network: 'base-sepolia',
48
+ timestampEmail: null,
48
49
  rpcUrls: {
49
50
  baseSepolia: 'https://sepolia.base.org',
50
51
  baseMainnet: 'https://mainnet.base.org',
@@ -148,6 +149,10 @@ class ConfigStore {
148
149
  const network = process.env.NEOZIP_NETWORK ||
149
150
  jsonConfig?.wallet?.network ||
150
151
  DEFAULTS.network;
152
+ // Timestamp email precedence: ENV > wallet.json > default (for Zipstamp)
153
+ const timestampEmail = process.env.NEOZIP_TIMESTAMP_EMAIL ||
154
+ jsonConfig?.zipstamp?.timestampEmail ||
155
+ null;
151
156
  // RPC URLs precedence: ENV > wallet.json > default
152
157
  const rpcUrls = {
153
158
  baseSepolia: process.env.NEOZIP_BASE_SEPOLIA_RPC_URL ||
@@ -180,6 +185,7 @@ class ConfigStore {
180
185
  return {
181
186
  walletKey,
182
187
  network,
188
+ timestampEmail,
183
189
  rpcUrls,
184
190
  gas,
185
191
  debug,
@@ -198,7 +204,7 @@ class ConfigStore {
198
204
  * Validate network name (uses nameAliases from CONTRACT_CONFIGS)
199
205
  */
200
206
  static validateNetwork(network) {
201
- return (0, blockchain_1.getChainIdByName)(network) !== null;
207
+ return (0, neozip_blockchain_1.getChainIdByName)(network) !== null;
202
208
  }
203
209
  /**
204
210
  * Update a specific configuration value
@@ -213,6 +219,17 @@ class ConfigStore {
213
219
  // Parse the key path (e.g., "wallet.privateKey", "gas.multiplier")
214
220
  const parts = key.split('.');
215
221
  switch (parts[0]) {
222
+ case 'zipstamp':
223
+ if (!config.zipstamp)
224
+ config.zipstamp = {};
225
+ if (parts[1] === 'timestampEmail') {
226
+ config.zipstamp.timestampEmail = value;
227
+ }
228
+ else {
229
+ console.error(`❌ Unknown zipstamp key: ${parts[1]}`);
230
+ return false;
231
+ }
232
+ break;
216
233
  case 'wallet':
217
234
  if (parts[1] === 'privateKey') {
218
235
  if (!this.validatePrivateKey(value)) {
@@ -223,7 +240,7 @@ class ConfigStore {
223
240
  }
224
241
  else if (parts[1] === 'network') {
225
242
  if (!this.validateNetwork(value)) {
226
- const supportedNetworks = (0, blockchain_1.getSupportedNetworkNames)();
243
+ const supportedNetworks = (0, neozip_blockchain_1.getSupportedNetworkNames)();
227
244
  console.error(`❌ Invalid network: "${value}"`);
228
245
  console.error(`Supported networks: ${supportedNetworks.join(', ')}`);
229
246
  return false;
@@ -284,6 +301,19 @@ class ConfigStore {
284
301
  // Parse the key path (e.g., "wallet.privateKey", "gas.multiplier")
285
302
  const parts = key.split('.');
286
303
  switch (parts[0]) {
304
+ case 'zipstamp':
305
+ if (!config.zipstamp) {
306
+ console.error('❌ No Zipstamp configuration found');
307
+ return false;
308
+ }
309
+ if (parts[1] === 'timestampEmail') {
310
+ delete config.zipstamp.timestampEmail;
311
+ }
312
+ else {
313
+ console.error(`❌ Unknown zipstamp key: ${parts[1]}`);
314
+ return false;
315
+ }
316
+ break;
287
317
  case 'wallet':
288
318
  if (parts[1] === 'privateKey') {
289
319
  delete config.wallet.privateKey;
@@ -360,6 +390,9 @@ class ConfigStore {
360
390
  '(not set)',
361
391
  network: config.network,
362
392
  },
393
+ zipstamp: {
394
+ timestampEmail: config.timestampEmail || '(not set)',
395
+ },
363
396
  rpc: config.rpcUrls,
364
397
  gas: config.gas,
365
398
  debug: config.debug,
package/dist/src/index.js CHANGED
@@ -78,7 +78,7 @@ function showHelp() {
78
78
  console.log(chalk_1.default.gray(' # Compress files'));
79
79
  console.log(' neozip output.nzip file1.txt file2.txt folder/\n');
80
80
  console.log(chalk_1.default.gray(' # Extract files'));
81
- console.log(' neounzip output.nzip extracted/\n');
81
+ console.log(' neounzip output.nzip tests/extracted/\n');
82
82
  console.log(chalk_1.default.gray(' # List archive contents'));
83
83
  console.log(' neolist output.nzip\n');
84
84
  console.log(chalk_1.default.yellow.bold('For detailed help on each command:'));
@@ -46,8 +46,10 @@ exports.parseArgs = parseArgs;
46
46
  exports.showHelp = showHelp;
47
47
  exports.showExtendedHelp = showExtendedHelp;
48
48
  const fs = __importStar(require("fs"));
49
- const neozipkit_1 = require("neozipkit");
50
49
  const node_1 = __importDefault(require("neozipkit/node"));
50
+ const neozip_blockchain_1 = require("neozip-blockchain");
51
+ const ots_1 = require("neozip-blockchain/ots");
52
+ const zipstamp_server_1 = require("neozip-blockchain/zipstamp-server");
51
53
  const chalk_1 = __importDefault(require("chalk"));
52
54
  const ora_1 = __importDefault(require("ora"));
53
55
  const version_1 = require("./version");
@@ -248,14 +250,20 @@ function getActualCompressedSize(entry) {
248
250
  * Format entry name for display (handles blockchain metadata)
249
251
  */
250
252
  function formatEntryName(entry) {
251
- if (entry.filename === neozipkit_1.TOKENIZED_METADATA) {
252
- return `${neozipkit_1.TOKENIZED_METADATA} (NFT Token)`;
253
+ if (entry.filename === neozip_blockchain_1.TOKENIZED_METADATA) {
254
+ return `${neozip_blockchain_1.TOKENIZED_METADATA} (NFT Token)`;
253
255
  }
254
- if (entry.filename === neozipkit_1.TIMESTAMP_METADATA) {
255
- return `${neozipkit_1.TIMESTAMP_METADATA} (Timestamp Metadata)`;
256
+ if (entry.filename === ots_1.TIMESTAMP_METADATA) {
257
+ return `${ots_1.TIMESTAMP_METADATA} (OTS Timestamp)`;
256
258
  }
257
- if (entry.filename === neozipkit_1.TIMESTAMP_SUBMITTED) {
258
- return `${neozipkit_1.TIMESTAMP_SUBMITTED} (Timestamp Submitted)`;
259
+ if (entry.filename === ots_1.TIMESTAMP_SUBMITTED) {
260
+ return `${ots_1.TIMESTAMP_SUBMITTED} (OTS Pending)`;
261
+ }
262
+ if (entry.filename === zipstamp_server_1.SUBMIT_METADATA) {
263
+ return `${zipstamp_server_1.SUBMIT_METADATA} (Zipstamp Pending)`;
264
+ }
265
+ if (entry.filename === zipstamp_server_1.TIMESTAMP_METADATA) {
266
+ return `${zipstamp_server_1.TIMESTAMP_METADATA} (Zipstamp Timestamp)`;
259
267
  }
260
268
  return entry.filename;
261
269
  }
@@ -955,9 +963,9 @@ Arguments:
955
963
  <archive> ZIP file to list
956
964
 
957
965
  Examples:
958
- neolist output/calgary.nzip
959
- neolist -b output/calgary.nzip
960
- neolist -u output/calgary.nzip
966
+ neolist tests/output/calgary.nzip
967
+ neolist -b tests/output/calgary.nzip
968
+ neolist -u tests/output/calgary.nzip
961
969
  `);
962
970
  }
963
971
  /**