@beclab/olaresid 0.1.12 → 0.2.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 (182) hide show
  1. package/CLI-TREE.md +107 -0
  2. package/CLI.md +122 -1329
  3. package/README.md +30 -12
  4. package/SDK-TREE.md +151 -0
  5. package/TAG.md +95 -41
  6. package/config.json +6 -4
  7. package/dist/abi/TerminusDIDQueryABI.d.ts +397 -0
  8. package/dist/abi/TerminusDIDQueryABI.d.ts.map +1 -0
  9. package/dist/abi/TerminusDIDQueryABI.js +519 -0
  10. package/dist/abi/TerminusDIDQueryABI.js.map +1 -0
  11. package/dist/business/index.d.ts +1 -1
  12. package/dist/business/index.d.ts.map +1 -1
  13. package/dist/business/index.js +11 -24
  14. package/dist/business/index.js.map +1 -1
  15. package/dist/business/tag-context.d.ts +1 -0
  16. package/dist/business/tag-context.d.ts.map +1 -1
  17. package/dist/business/tag-context.js +13 -7
  18. package/dist/business/tag-context.js.map +1 -1
  19. package/dist/cli.js +238 -107
  20. package/dist/cli.js.map +1 -1
  21. package/dist/config/index.d.ts +16 -4
  22. package/dist/config/index.d.ts.map +1 -1
  23. package/dist/config/index.js +28 -14
  24. package/dist/config/index.js.map +1 -1
  25. package/dist/domain/core.d.ts +65 -0
  26. package/dist/domain/core.d.ts.map +1 -0
  27. package/dist/domain/core.js +317 -0
  28. package/dist/domain/core.js.map +1 -0
  29. package/dist/domain/index.d.ts +104 -57
  30. package/dist/domain/index.d.ts.map +1 -1
  31. package/dist/domain/index.js +188 -428
  32. package/dist/domain/index.js.map +1 -1
  33. package/dist/domain/types.d.ts +56 -0
  34. package/dist/domain/types.d.ts.map +1 -0
  35. package/dist/domain/types.js +3 -0
  36. package/dist/domain/types.js.map +1 -0
  37. package/dist/index.d.ts +81 -24
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +153 -143
  40. package/dist/index.js.map +1 -1
  41. package/dist/utils/crypto-utils.d.ts +124 -0
  42. package/dist/utils/crypto-utils.d.ts.map +1 -1
  43. package/dist/utils/crypto-utils.js +156 -8
  44. package/dist/utils/crypto-utils.js.map +1 -1
  45. package/dist/utils/error-parser.d.ts.map +1 -1
  46. package/dist/utils/error-parser.js +2 -1
  47. package/dist/utils/error-parser.js.map +1 -1
  48. package/dist/utils/event-parser.d.ts +161 -0
  49. package/dist/utils/event-parser.d.ts.map +1 -0
  50. package/dist/utils/event-parser.js +140 -0
  51. package/dist/utils/event-parser.js.map +1 -0
  52. package/dist/utils/tag-type-builder.d.ts +43 -0
  53. package/dist/utils/tag-type-builder.d.ts.map +1 -1
  54. package/dist/utils/tag-type-builder.js +122 -0
  55. package/dist/utils/tag-type-builder.js.map +1 -1
  56. package/dist/utils/tag-type-parser.d.ts +70 -0
  57. package/dist/utils/tag-type-parser.d.ts.map +1 -0
  58. package/dist/utils/tag-type-parser.js +190 -0
  59. package/dist/utils/tag-type-parser.js.map +1 -0
  60. package/examples/create-with-rpc-demo.ts +142 -0
  61. package/examples/fetch-all-flat-demo.ts +159 -0
  62. package/examples/fetch-by-indices-demo.ts +235 -0
  63. package/examples/fetch-domain-demo.ts +137 -0
  64. package/examples/fetch-domains-demo.ts +221 -0
  65. package/examples/frontend-demo/index.html +2 -2
  66. package/examples/frontend-demo/package-lock.json +4 -1
  67. package/examples/index.ts +3 -5
  68. package/jest.config.js +25 -0
  69. package/package.json +6 -2
  70. package/src/abi/TerminusDIDQueryABI.ts +516 -0
  71. package/src/business/index.ts +10 -33
  72. package/src/business/tag-context.ts +35 -7
  73. package/src/cli.ts +344 -121
  74. package/src/config/index.ts +34 -19
  75. package/src/domain/core.ts +382 -0
  76. package/src/domain/index.ts +271 -641
  77. package/src/domain/types.ts +59 -0
  78. package/src/index.ts +222 -207
  79. package/src/utils/crypto-utils.ts +239 -2
  80. package/src/utils/error-parser.ts +2 -1
  81. package/src/utils/event-parser.ts +353 -0
  82. package/src/utils/tag-type-builder.ts +138 -0
  83. package/src/utils/tag-type-parser.ts +246 -0
  84. package/tests/unit/crypto-utils.test.ts +338 -0
  85. package/tests/unit/ed25519-jwk.test.ts +201 -0
  86. package/tests/unit/event-parser.test.ts +690 -0
  87. package/tests/unit/generate-mnemonic.test.ts +268 -0
  88. package/tests/unit/olares-id-format.test.ts +321 -0
  89. package/tests/unit/tag-type-parser.test.ts +802 -0
  90. package/tests/unit/tag-types.test.ts +821 -0
  91. package/tsconfig.json +3 -2
  92. package/dist/abi/ABITypeABI.d.ts +0 -88
  93. package/dist/abi/ABITypeABI.d.ts.map +0 -1
  94. package/dist/abi/ABITypeABI.js +0 -382
  95. package/dist/abi/ABITypeABI.js.map +0 -1
  96. package/dist/abi/RegistryABI.d.ts +0 -77
  97. package/dist/abi/RegistryABI.d.ts.map +0 -1
  98. package/dist/abi/RegistryABI.js +0 -462
  99. package/dist/abi/RegistryABI.js.map +0 -1
  100. package/dist/tag/address.d.ts +0 -11
  101. package/dist/tag/address.d.ts.map +0 -1
  102. package/dist/tag/address.js +0 -44
  103. package/dist/tag/address.js.map +0 -1
  104. package/dist/tag/array.d.ts +0 -14
  105. package/dist/tag/array.d.ts.map +0 -1
  106. package/dist/tag/array.js +0 -72
  107. package/dist/tag/array.js.map +0 -1
  108. package/dist/tag/bool.d.ts +0 -11
  109. package/dist/tag/bool.d.ts.map +0 -1
  110. package/dist/tag/bool.js +0 -43
  111. package/dist/tag/bool.js.map +0 -1
  112. package/dist/tag/bytes.d.ts +0 -11
  113. package/dist/tag/bytes.d.ts.map +0 -1
  114. package/dist/tag/bytes.js +0 -37
  115. package/dist/tag/bytes.js.map +0 -1
  116. package/dist/tag/flarray.d.ts +0 -15
  117. package/dist/tag/flarray.d.ts.map +0 -1
  118. package/dist/tag/flarray.js +0 -81
  119. package/dist/tag/flarray.js.map +0 -1
  120. package/dist/tag/flbytes.d.ts +0 -11
  121. package/dist/tag/flbytes.d.ts.map +0 -1
  122. package/dist/tag/flbytes.js +0 -47
  123. package/dist/tag/flbytes.js.map +0 -1
  124. package/dist/tag/index.d.ts +0 -32
  125. package/dist/tag/index.d.ts.map +0 -1
  126. package/dist/tag/index.js +0 -121
  127. package/dist/tag/index.js.map +0 -1
  128. package/dist/tag/int.d.ts +0 -12
  129. package/dist/tag/int.d.ts.map +0 -1
  130. package/dist/tag/int.js +0 -49
  131. package/dist/tag/int.js.map +0 -1
  132. package/dist/tag/string.d.ts +0 -11
  133. package/dist/tag/string.d.ts.map +0 -1
  134. package/dist/tag/string.js +0 -37
  135. package/dist/tag/string.js.map +0 -1
  136. package/dist/tag/tag.d.ts +0 -67
  137. package/dist/tag/tag.d.ts.map +0 -1
  138. package/dist/tag/tag.js +0 -157
  139. package/dist/tag/tag.js.map +0 -1
  140. package/dist/tag/tuple.d.ts +0 -17
  141. package/dist/tag/tuple.d.ts.map +0 -1
  142. package/dist/tag/tuple.js +0 -162
  143. package/dist/tag/tuple.js.map +0 -1
  144. package/dist/tag/uint.d.ts +0 -12
  145. package/dist/tag/uint.d.ts.map +0 -1
  146. package/dist/tag/uint.js +0 -49
  147. package/dist/tag/uint.js.map +0 -1
  148. package/dist/test/did.d.ts +0 -2
  149. package/dist/test/did.d.ts.map +0 -1
  150. package/dist/test/did.js +0 -177
  151. package/dist/test/did.js.map +0 -1
  152. package/dist/utils/tag-abi-codec.d.ts +0 -69
  153. package/dist/utils/tag-abi-codec.d.ts.map +0 -1
  154. package/dist/utils/tag-abi-codec.js +0 -144
  155. package/dist/utils/tag-abi-codec.js.map +0 -1
  156. package/examples/crypto-utilities.ts +0 -140
  157. package/examples/ed25519-jwk.ts +0 -73
  158. package/examples/generate-mnemonic.ts +0 -149
  159. package/examples/legacy.ts +0 -33
  160. package/examples/olares-id-format.ts +0 -197
  161. package/examples/tag-builder.ts +0 -235
  162. package/examples/tag-nested-tuple.ts +0 -190
  163. package/examples/tag-simple.ts +0 -149
  164. package/examples/tag-tagger.ts +0 -217
  165. package/examples/test-nested-tuple-conversion.ts +0 -143
  166. package/examples/test-type-bytes-parser.ts +0 -70
  167. package/src/abi/ABITypeABI.ts +0 -379
  168. package/src/abi/RegistryABI.ts +0 -459
  169. package/src/tag/address.ts +0 -48
  170. package/src/tag/array.ts +0 -80
  171. package/src/tag/bool.ts +0 -43
  172. package/src/tag/bytes.ts +0 -38
  173. package/src/tag/flarray.ts +0 -99
  174. package/src/tag/flbytes.ts +0 -48
  175. package/src/tag/index.ts +0 -170
  176. package/src/tag/int.ts +0 -51
  177. package/src/tag/string.ts +0 -38
  178. package/src/tag/tag.ts +0 -229
  179. package/src/tag/tuple.ts +0 -193
  180. package/src/tag/uint.ts +0 -51
  181. package/src/test/did.ts +0 -346
  182. package/src/utils/tag-abi-codec.ts +0 -158
package/dist/cli.js CHANGED
@@ -65,7 +65,8 @@ function parseArgs() {
65
65
  'is-owner',
66
66
  'transfer',
67
67
  'fetch',
68
- 'fetch-domain'
68
+ 'fetch-domain',
69
+ 'fetch-all'
69
70
  ];
70
71
  for (let i = 0; i < args.length; i++) {
71
72
  const arg = args[i];
@@ -79,6 +80,9 @@ function parseArgs() {
79
80
  else if (arg === '--network' || arg === '-n') {
80
81
  options.network = args[++i] || 'mainnet';
81
82
  }
83
+ else if (arg === '--from') {
84
+ options.from = args[++i];
85
+ }
82
86
  else if (arg === '--rpc') {
83
87
  options.rpc = args[++i];
84
88
  }
@@ -138,6 +142,18 @@ function parseArgs() {
138
142
  }
139
143
  return { command, subCommand, domain, value, options };
140
144
  }
145
+ function normalizeTagFromDomain(from, toDomain) {
146
+ if (!from) {
147
+ return toDomain;
148
+ }
149
+ const normalized = from.trim().toLowerCase();
150
+ if (normalized === 'root' ||
151
+ normalized === ':root' ||
152
+ normalized === '""') {
153
+ return '';
154
+ }
155
+ return (0, olares_id_1.normalizeToDomain)(from);
156
+ }
141
157
  function showHelp() {
142
158
  console.log(`
143
159
  DID CLI Tool v${CLI_VERSION}
@@ -191,15 +207,18 @@ COMMANDS:
191
207
  Define a new tag type (requires PRIVATE_KEY_OR_MNEMONIC)
192
208
  Supported types: string, uint8, uint256, int8, int256, bool, address, bytes, bytes32
193
209
  Array types: string[], uint8[], etc.
194
- tag set <domain> <tag-name> <value>
210
+ tag set <domain> <tag-name> <value> [--from <domain|root>]
195
211
  Set tag value (requires PRIVATE_KEY_OR_MNEMONIC)
196
- Value can be a string or JSON for arrays/objects
197
- tag get <domain> <tag-name>
212
+ Value can be a string or JSON for arrays/objects
213
+ --from specifies where tag type is defined (default: same as <domain>)
214
+ tag get <domain> <tag-name> [--from <domain|root>]
198
215
  Get tag value (read-only)
199
- tag remove <domain> <tag-name>
216
+ tag remove <domain> <tag-name> [--from <domain|root>]
200
217
  Remove tag value (requires PRIVATE_KEY_OR_MNEMONIC)
201
- tag list <domain> List all tags with values for domain (read-only)
202
- tag list-defined <domain> List all defined tag types for domain (read-only)
218
+ tag list <domain> [--from <domain|root>]
219
+ List all tags with values for domain (read-only)
220
+ tag list-defined [domain] List all tag types defined by the domain (read-only)
221
+ Omit domain to query tag types defined by root
203
222
  tag set-tagger <domain> <tag-name> <address>
204
223
  Set tagger address for a tag (requires PRIVATE_KEY_OR_MNEMONIC)
205
224
  tag get-tagger <domain> <tag-name>
@@ -222,16 +241,17 @@ COMMANDS:
222
241
  config set <key> <value> [--network <network>]
223
242
  Set configuration value (default network: mainnet)
224
243
  Keys: rpc, contractDid, contractRootResolver,
225
- contractAbiType, contractRootResolver2, supportSvcUrl
244
+ contractAbiType, contractRootResolver2,
245
+ supportSvcUrl, queryContract
226
246
 
227
247
  Crypto Utility Commands:
228
248
  crypto generate Generate a new mnemonic phrase (--words option)
229
249
  Saves to file, use --output to specify file path
230
- crypto address Get Ethereum address from mnemonic (requires MNEMONIC env var)
231
- crypto did Get DID from mnemonic (requires MNEMONIC env var)
232
- crypto privatekey Get EVM private key from mnemonic (requires MNEMONIC env var)
250
+ crypto address Get Ethereum address from private key or mnemonic (requires PRIVATE_KEY_OR_MNEMONIC)
251
+ crypto did Get DID from mnemonic (requires PRIVATE_KEY_OR_MNEMONIC with mnemonic)
252
+ crypto privatekey Get/save EVM private key (requires PRIVATE_KEY_OR_MNEMONIC)
233
253
  Saves to file, use --output to specify file path
234
- crypto derive Derive all keys from mnemonic (requires MNEMONIC env var)
254
+ crypto derive Derive all keys from mnemonic (requires PRIVATE_KEY_OR_MNEMONIC with mnemonic)
235
255
  Saves to file, use --output to specify file path
236
256
 
237
257
  Utility Commands:
@@ -242,12 +262,13 @@ COMMANDS:
242
262
 
243
263
  Legacy Commands:
244
264
  fetch <domain> Fetch domain information (alias: fetch-domain)
245
- fetch-all Fetch all domains from contract
246
- config Show network configurations
265
+ fetch-all Fetch all domains from contract and save to JSON file
266
+ Use --output to specify file path (default: domains-<network>-<date>.json)
247
267
  help Show this help message
248
268
 
249
269
  OPTIONS:
250
270
  -n, --network <network> Network to use (sepolia|mainnet) [default: mainnet]
271
+ --from <domain|root> Tag source domain for tag set/get/remove/list (default: target domain)
251
272
  --rpc <url> Custom RPC endpoint URL
252
273
  --contract-did <address> Custom DID contract address
253
274
  --contract-resolver <address> Custom RootResolver contract address
@@ -293,7 +314,6 @@ EXAMPLES:
293
314
  # Subdomain management (auto-generate mnemonic for subdomain owner)
294
315
  export PRIVATE_KEY_OR_MNEMONIC=0xYOUR_PRIVATE_KEY
295
316
  did-cli subdomain register parent.com child
296
- did-cli subdomain register parent.com child --words 24
297
317
 
298
318
  # Subdomain management (use existing mnemonic for subdomain owner)
299
319
  export SUBDOMAIN_OWNER_MNEMONIC="your twelve word mnemonic here"
@@ -305,7 +325,6 @@ EXAMPLES:
305
325
  # Transfer domain ownership (auto-generate mnemonic for new owner)
306
326
  export PRIVATE_KEY_OR_MNEMONIC=0xYOUR_PRIVATE_KEY
307
327
  did-cli transfer example.com
308
- did-cli transfer example.com --words 24
309
328
 
310
329
  # Transfer domain ownership (use existing mnemonic for new owner)
311
330
  export TO_MNEMONIC="your twelve word mnemonic here"
@@ -313,8 +332,8 @@ EXAMPLES:
313
332
 
314
333
  # Crypto utilities
315
334
  did-cli crypto generate --words 12
316
- did-cli crypto generate --words 24 --output ./custom-path.txt
317
- export MNEMONIC="your twelve word mnemonic here"
335
+ did-cli crypto generate --output ./custom-path.txt
336
+ export PRIVATE_KEY_OR_MNEMONIC="your twelve word mnemonic here"
318
337
  did-cli crypto address
319
338
  did-cli crypto did
320
339
  did-cli crypto privatekey --output ./my-private-key.txt
@@ -384,8 +403,15 @@ EXAMPLES:
384
403
  did-cli config list # List all networks
385
404
  did-cli config set rpc https://optimism.llamarpc.com # Set mainnet RPC
386
405
  did-cli config set contractDid 0x1234... --network sepolia # Set sepolia contract
406
+ did-cli config set queryContract 0x637197... --network sepolia # Set query contract
387
407
  did-cli config set rpc https://my-rpc.com --network custom_net # Create new network
388
408
 
409
+ # Fetch all domains
410
+ did-cli fetch-all # Fetch all mainnet domains (auto-named file)
411
+ did-cli fetch-all --network sepolia # Fetch all sepolia domains
412
+ did-cli fetch-all --output ./my-domains.json # Custom output file path
413
+ did-cli fetch-all --network sepolia --verbose # With progress details
414
+
389
415
  # Utilities
390
416
  did-cli convert pem-to-der ./public-key.pem
391
417
  did-cli convert ip-to-bytes 192.168.1.1
@@ -393,13 +419,12 @@ EXAMPLES:
393
419
 
394
420
  ENVIRONMENT VARIABLES:
395
421
  PRIVATE_KEY_OR_MNEMONIC Private key (0x...) or mnemonic phrase for signing transactions
396
- (required for write operations)
422
+ and crypto utility commands (required for write operations
423
+ and crypto address/did/privatekey/derive)
397
424
  SUBDOMAIN_OWNER_MNEMONIC Mnemonic phrase for generating subdomain owner identity
398
425
  (used in subdomain registration)
399
426
  TO_MNEMONIC Mnemonic phrase for generating new owner identity
400
427
  (used in domain transfer)
401
- MNEMONIC Mnemonic phrase for crypto utility commands
402
- (used in crypto address, did, privatekey, derive)
403
428
  EVM_PRIVATE_KEY EVM wallet private key for wallet management operations
404
429
  (required for wallet evm add/remove commands)
405
430
  SOLANA_PRIVATE_KEY Solana wallet private key for wallet management operations
@@ -414,27 +439,12 @@ async function fetchDomain(domain, options) {
414
439
  debug_1.debug.enable();
415
440
  debug_1.debug.setLevel(options.debugLevel);
416
441
  }
417
- // Get network configuration
418
- const config = (0, config_1.getNetworkConfig)(options.network);
419
- if (!config) {
420
- console.error(`āŒ Unknown network: ${options.network}`);
421
- console.error('Available networks:', (0, config_1.getAvailableNetworks)().join(', '));
422
- process.exit(1);
423
- }
424
- // Command line parameters take priority
425
- const finalConfig = {
426
- rpc: options.rpc || config.rpc,
427
- contractDid: options.contractDid || config.contractDid,
428
- contractRootResolver: options.contractResolver || config.contractRootResolver,
429
- contractAbiType: options.contractAbi || config.contractAbiType
430
- };
431
442
  if (debug_1.debug.isEnabled()) {
432
443
  debug_1.debug.info(`šŸ” Fetching domain: ${domain}`);
433
444
  debug_1.debug.info(`🌐 Network: ${options.network}`);
434
- debug_1.debug.info('Using configuration:', finalConfig);
435
445
  }
436
- // Create DID console instance
437
- const olaresId = index_1.default.createConsole(finalConfig.rpc, finalConfig.contractDid, finalConfig.contractRootResolver, finalConfig.contractAbiType);
446
+ // Use getConsole helper to create console instance
447
+ const olaresId = getConsole(options);
438
448
  // Fetch domain data
439
449
  const domainData = await olaresId.fetchDomain(domain);
440
450
  if (!domainData) {
@@ -451,6 +461,70 @@ async function fetchDomain(domain, options) {
451
461
  process.exit(1);
452
462
  }
453
463
  }
464
+ async function fetchAll(options) {
465
+ try {
466
+ // Set debug options
467
+ if (options.verbose || options.debug) {
468
+ debug_1.debug.enable();
469
+ debug_1.debug.setLevel(options.debugLevel);
470
+ }
471
+ if (debug_1.debug.isEnabled()) {
472
+ debug_1.debug.info('šŸ” Fetching all domains');
473
+ debug_1.debug.info(`🌐 Network: ${options.network}`);
474
+ }
475
+ // Use getConsole helper to create console instance
476
+ const olaresId = getConsole(options);
477
+ // Check if query contract is configured
478
+ if (!olaresId.queryContractAddress) {
479
+ console.error('āŒ Query contract address not configured for this network');
480
+ console.error(` Use: did-cli config set queryContract <address> --network ${options.network}`);
481
+ process.exit(1);
482
+ }
483
+ console.log('šŸ“” Fetching all domains from contract...');
484
+ console.log(` Network: ${options.network}`);
485
+ console.log(` Query Contract: ${olaresId.queryContractAddress}`);
486
+ console.log();
487
+ let totalDomains = 0;
488
+ const startTime = Date.now();
489
+ // Fetch all domains with progress
490
+ const domains = await olaresId.fetchAllFlat({
491
+ batchSize: 100,
492
+ onProgress: (current, total) => {
493
+ totalDomains = total;
494
+ const percent = ((current / total) * 100).toFixed(1);
495
+ process.stdout.write(`\rā³ Progress: ${current}/${total} (${percent}%)`);
496
+ }
497
+ });
498
+ const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
499
+ process.stdout.write('\r' + ' '.repeat(50) + '\r'); // Clear progress line
500
+ console.log(`āœ… Fetched ${totalDomains} domains in ${elapsed}s`);
501
+ console.log();
502
+ // Determine output file path
503
+ const timestamp = new Date()
504
+ .toISOString()
505
+ .replace(/[:.]/g, '-')
506
+ .split('T')[0];
507
+ const defaultFilename = `domains-${options.network}-${timestamp}.json`;
508
+ const outputPath = options.output || path.join(process.cwd(), defaultFilename);
509
+ // Save to file
510
+ const jsonContent = JSON.stringify(domains, null, 2);
511
+ fs.writeFileSync(outputPath, jsonContent, 'utf-8');
512
+ console.log(`šŸ’¾ Saved to: ${outputPath}`);
513
+ console.log(` File size: ${(jsonContent.length / 1024).toFixed(2)} KB`);
514
+ console.log(` Total domains: ${domains.length}`);
515
+ if (debug_1.debug.isEnabled()) {
516
+ debug_1.debug.info('Fetch all completed successfully');
517
+ debug_1.debug.info(`Output file: ${outputPath}`);
518
+ }
519
+ }
520
+ catch (error) {
521
+ console.error('āŒ Error fetching all domains:', error instanceof Error ? error.message : String(error));
522
+ if (debug_1.debug.isEnabled()) {
523
+ debug_1.debug.error('Full error details:', error);
524
+ }
525
+ process.exit(1);
526
+ }
527
+ }
454
528
  // ============================================================================
455
529
  // Helper Functions
456
530
  // ============================================================================
@@ -468,9 +542,10 @@ function getConsole(options) {
468
542
  contractAbiType: options.contractAbi || networkConfig.contractAbiType,
469
543
  contractRootResolver2: options.contractRootResolver2 ||
470
544
  networkConfig.contractRootResolver2,
471
- supportSvcUrl: options.supportSvcUrl || networkConfig.supportSvcUrl
545
+ supportSvcUrl: options.supportSvcUrl || networkConfig.supportSvcUrl,
546
+ queryContract: networkConfig.queryContract
472
547
  };
473
- return index_1.default.createConsole(config.rpc, config.contractDid, config.contractRootResolver, config.contractAbiType, config.contractRootResolver2, config.supportSvcUrl);
548
+ return index_1.default.createConsole(config.rpc, config.contractDid, config.contractRootResolver, config.contractAbiType, config.contractRootResolver2, config.supportSvcUrl, config.queryContract);
474
549
  }
475
550
  function getPrivateKeyOrMnemonic() {
476
551
  const key = process.env.PRIVATE_KEY_OR_MNEMONIC;
@@ -1125,7 +1200,7 @@ async function cryptoGenerate(options) {
1125
1200
  console.log(' • Delete the file after copying to a secure location');
1126
1201
  console.log(` • Command: rm ${outputFile}`);
1127
1202
  console.log('\nšŸ’” To use the mnemonic:');
1128
- console.log(` export MNEMONIC="$(cat ${outputFile})"`);
1203
+ console.log(` export PRIVATE_KEY_OR_MNEMONIC="$(cat ${outputFile})"`);
1129
1204
  }
1130
1205
  }
1131
1206
  catch (error) {
@@ -1137,26 +1212,37 @@ async function cryptoGenerate(options) {
1137
1212
  }
1138
1213
  }
1139
1214
  /**
1140
- * Get mnemonic from environment variable
1215
+ * Get private key or mnemonic from environment variable
1216
+ * Returns: { value: string, isMnemonic: boolean }
1141
1217
  */
1142
- function getMnemonic() {
1143
- const mnemonic = process.env.MNEMONIC;
1144
- if (!mnemonic) {
1145
- console.error('āŒ Error: MNEMONIC environment variable is required');
1146
- console.error('Please set MNEMONIC environment variable');
1147
- console.error('Example: export MNEMONIC="your twelve word mnemonic phrase here"');
1218
+ function getPrivateKeyOrMnemonicWithType() {
1219
+ const key = process.env.PRIVATE_KEY_OR_MNEMONIC;
1220
+ if (!key) {
1221
+ console.error('āŒ Error: Private key or mnemonic is required for this operation');
1222
+ console.error('Please set PRIVATE_KEY_OR_MNEMONIC environment variable');
1223
+ console.error('Example: export PRIVATE_KEY_OR_MNEMONIC=0xYOUR_PRIVATE_KEY');
1224
+ console.error('Or: export PRIVATE_KEY_OR_MNEMONIC="your twelve word mnemonic phrase here"');
1148
1225
  console.error('\nāš ļø Important: Always use quotes for mnemonic phrases!');
1149
1226
  process.exit(1);
1150
1227
  }
1151
- return mnemonic;
1228
+ const trimmed = key.trim();
1229
+ const wordCount = trimmed.split(/\s+/).length;
1230
+ const isMnemonic = wordCount >= 12 && wordCount <= 24;
1231
+ return { value: trimmed, isMnemonic };
1152
1232
  }
1153
1233
  /**
1154
- * Crypto utility: Get Ethereum address from mnemonic
1234
+ * Crypto utility: Get Ethereum address from private key or mnemonic
1155
1235
  */
1156
1236
  async function cryptoGetAddress(options) {
1157
1237
  try {
1158
- const mnemonic = getMnemonic();
1159
- const address = await (0, index_1.getEthereumAddressFromMnemonic)(mnemonic);
1238
+ const { value, isMnemonic } = getPrivateKeyOrMnemonicWithType();
1239
+ let address;
1240
+ if (isMnemonic) {
1241
+ address = await (0, index_1.getEthereumAddressFromMnemonic)(value);
1242
+ }
1243
+ else {
1244
+ address = (0, index_1.getEthereumAddressFromPrivateKey)(value);
1245
+ }
1160
1246
  if (options.json) {
1161
1247
  console.log(JSON.stringify({
1162
1248
  address: address
@@ -1176,12 +1262,18 @@ async function cryptoGetAddress(options) {
1176
1262
  }
1177
1263
  }
1178
1264
  /**
1179
- * Crypto utility: Get DID from mnemonic
1265
+ * Crypto utility: Get DID from mnemonic (only works with mnemonic)
1180
1266
  */
1181
1267
  async function cryptoGetDID(options) {
1182
1268
  try {
1183
- const mnemonic = getMnemonic();
1184
- const did = await (0, index_1.getDIDFromMnemonic)(mnemonic);
1269
+ const { value, isMnemonic } = getPrivateKeyOrMnemonicWithType();
1270
+ if (!isMnemonic) {
1271
+ console.error('āŒ Error: DID derivation requires a mnemonic phrase');
1272
+ console.error(' Private keys cannot be used to derive DID');
1273
+ console.error(' Please provide a mnemonic phrase in PRIVATE_KEY_OR_MNEMONIC');
1274
+ process.exit(1);
1275
+ }
1276
+ const did = await (0, index_1.getDIDFromMnemonic)(value);
1185
1277
  if (options.json) {
1186
1278
  console.log(JSON.stringify({
1187
1279
  did: did
@@ -1201,12 +1293,19 @@ async function cryptoGetDID(options) {
1201
1293
  }
1202
1294
  }
1203
1295
  /**
1204
- * Crypto utility: Get EVM private key from mnemonic
1296
+ * Crypto utility: Get/display EVM private key (from mnemonic or show existing private key)
1205
1297
  */
1206
1298
  async function cryptoGetPrivateKey(options) {
1207
1299
  try {
1208
- const mnemonic = getMnemonic();
1209
- const privateKey = await (0, index_1.getEVMPrivateKeyFromMnemonic)(mnemonic);
1300
+ const { value, isMnemonic } = getPrivateKeyOrMnemonicWithType();
1301
+ let privateKey;
1302
+ if (isMnemonic) {
1303
+ privateKey = await (0, index_1.getEVMPrivateKeyFromMnemonic)(value);
1304
+ }
1305
+ else {
1306
+ // Already a private key, just use it
1307
+ privateKey = value;
1308
+ }
1210
1309
  // Save private key to file
1211
1310
  const outputFile = options.output || './private-key.txt';
1212
1311
  fs.writeFileSync(outputFile, privateKey, 'utf-8');
@@ -1216,7 +1315,7 @@ async function cryptoGetPrivateKey(options) {
1216
1315
  }, null, 2));
1217
1316
  }
1218
1317
  else {
1219
- console.log('šŸ”‘ EVM Private Key generated');
1318
+ console.log('šŸ”‘ EVM Private Key');
1220
1319
  console.log(`šŸ“„ Private key saved to: ${outputFile}`);
1221
1320
  console.log('\nāš ļø SECURITY WARNING:');
1222
1321
  console.log(' • Keep this private key secure! Never share it!');
@@ -1233,13 +1332,20 @@ async function cryptoGetPrivateKey(options) {
1233
1332
  }
1234
1333
  }
1235
1334
  /**
1236
- * Crypto utility: Derive all keys from mnemonic
1335
+ * Crypto utility: Derive all keys from mnemonic (only works with mnemonic)
1237
1336
  */
1238
1337
  async function cryptoDerive(options) {
1239
1338
  try {
1240
- const mnemonic = getMnemonic();
1241
- const { owner, did } = await (0, index_1.deriveDIDFromMnemonic)(mnemonic);
1242
- const privateKey = await (0, index_1.getEVMPrivateKeyFromMnemonic)(mnemonic);
1339
+ const { value, isMnemonic } = getPrivateKeyOrMnemonicWithType();
1340
+ if (!isMnemonic) {
1341
+ console.error('āŒ Error: Key derivation requires a mnemonic phrase');
1342
+ console.error(' Private keys cannot be used to derive additional keys');
1343
+ console.error(' Please provide a mnemonic phrase in PRIVATE_KEY_OR_MNEMONIC');
1344
+ console.error(' Note: You can derive address from a private key using "crypto address"');
1345
+ process.exit(1);
1346
+ }
1347
+ const { owner, did } = await (0, index_1.deriveDIDFromMnemonic)(value);
1348
+ const privateKey = await (0, index_1.getEVMPrivateKeyFromMnemonic)(value);
1243
1349
  // Save all keys to file
1244
1350
  const outputFile = options.output || './derived-keys.txt';
1245
1351
  const fileContent = `Ethereum Address: ${owner}\nDID: ${did}\nPrivate Key: ${privateKey}`;
@@ -1520,6 +1626,7 @@ async function configShow(options) {
1520
1626
  console.log(` Contract ABIType: ${networkConfig.contractAbiType}`);
1521
1627
  console.log(` Contract RootResolver2: ${networkConfig.contractRootResolver2}`);
1522
1628
  console.log(` Support Service URL: ${networkConfig.supportSvcUrl}`);
1629
+ console.log(` Query Contract: ${networkConfig.queryContract || '(not set)'}`);
1523
1630
  console.log(`\nšŸ“„ Configuration file: ${(0, config_1.getConfigFilePath)()}`);
1524
1631
  }
1525
1632
  }
@@ -1576,7 +1683,8 @@ async function configSet(key, value, options) {
1576
1683
  'contractRootResolver',
1577
1684
  'contractAbiType',
1578
1685
  'contractRootResolver2',
1579
- 'supportSvcUrl'
1686
+ 'supportSvcUrl',
1687
+ 'queryContract'
1580
1688
  ];
1581
1689
  if (!validKeys.includes(key)) {
1582
1690
  console.error(`āŒ Invalid config key: ${key}`);
@@ -1697,14 +1805,17 @@ async function tagDefine(domain, tagName, typeString, options) {
1697
1805
  /**
1698
1806
  * Set tag value
1699
1807
  */
1700
- async function tagSet(domain, tagName, valueStr, options) {
1808
+ async function tagSet(toDomain, fromDomain, tagName, valueStr, options) {
1701
1809
  try {
1702
1810
  const didConsole = getConsole(options);
1703
1811
  const privateKeyOrMnemonic = getPrivateKeyOrMnemonic();
1704
1812
  await didConsole.setSigner(privateKeyOrMnemonic);
1705
- const domainContext = didConsole.domain(domain);
1813
+ const domainContext = didConsole.domain(fromDomain);
1706
1814
  const tagCtx = domainContext.tag();
1707
- console.log(`\nšŸ“ Setting tag "${tagName}" for domain: ${domain}`);
1815
+ const fromLabel = fromDomain === '' ? '(root)' : fromDomain;
1816
+ console.log(`\nšŸ“ Setting tag "${tagName}"`);
1817
+ console.log(` From: ${fromLabel}`);
1818
+ console.log(` To: ${toDomain}`);
1708
1819
  console.log(` Value: ${valueStr}`);
1709
1820
  // Try to parse value as JSON, otherwise use as string
1710
1821
  let value;
@@ -1714,12 +1825,13 @@ async function tagSet(domain, tagName, valueStr, options) {
1714
1825
  catch {
1715
1826
  value = valueStr;
1716
1827
  }
1717
- const result = await tagCtx.setTag(domain, tagName, value);
1828
+ const result = await tagCtx.setTag(toDomain, tagName, value);
1718
1829
  if (result.success) {
1719
1830
  if (options.json) {
1720
1831
  console.log(JSON.stringify({
1721
1832
  success: true,
1722
- domain,
1833
+ from: fromDomain,
1834
+ to: toDomain,
1723
1835
  tagName,
1724
1836
  value,
1725
1837
  transactionHash: result.transactionHash,
@@ -1749,18 +1861,22 @@ async function tagSet(domain, tagName, valueStr, options) {
1749
1861
  /**
1750
1862
  * Get tag value
1751
1863
  */
1752
- async function tagGet(domain, tagName, options) {
1864
+ async function tagGet(toDomain, fromDomain, tagName, options) {
1753
1865
  try {
1754
1866
  const didConsole = getConsole(options);
1755
- const domainContext = didConsole.domain(domain);
1867
+ const domainContext = didConsole.domain(fromDomain);
1756
1868
  const tagCtx = domainContext.tag();
1757
- console.log(`\nšŸ“– Getting tag "${tagName}" for domain: ${domain}`);
1758
- const value = await tagCtx.getTag(domain, tagName);
1869
+ const fromLabel = fromDomain === '' ? '(root)' : fromDomain;
1870
+ console.log(`\nšŸ“– Getting tag "${tagName}"`);
1871
+ console.log(` From: ${fromLabel}`);
1872
+ console.log(` To: ${toDomain}`);
1873
+ const value = await tagCtx.getTag(toDomain, tagName);
1759
1874
  if (value !== null && value !== undefined) {
1760
1875
  if (options.json) {
1761
1876
  console.log(JSON.stringify({
1762
1877
  success: true,
1763
- domain,
1878
+ from: fromDomain,
1879
+ to: toDomain,
1764
1880
  tagName,
1765
1881
  value
1766
1882
  }, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2));
@@ -1779,7 +1895,8 @@ async function tagGet(domain, tagName, options) {
1779
1895
  if (options.json) {
1780
1896
  console.log(JSON.stringify({
1781
1897
  success: true,
1782
- domain,
1898
+ from: fromDomain,
1899
+ to: toDomain,
1783
1900
  tagName,
1784
1901
  value: null
1785
1902
  }));
@@ -1797,20 +1914,24 @@ async function tagGet(domain, tagName, options) {
1797
1914
  /**
1798
1915
  * Remove tag value
1799
1916
  */
1800
- async function tagRemove(domain, tagName, options) {
1917
+ async function tagRemove(toDomain, fromDomain, tagName, options) {
1801
1918
  try {
1802
1919
  const didConsole = getConsole(options);
1803
1920
  const privateKeyOrMnemonic = getPrivateKeyOrMnemonic();
1804
1921
  await didConsole.setSigner(privateKeyOrMnemonic);
1805
- const domainContext = didConsole.domain(domain);
1922
+ const domainContext = didConsole.domain(fromDomain);
1806
1923
  const tagCtx = domainContext.tag();
1807
- console.log(`\nšŸ—‘ļø Removing tag "${tagName}" for domain: ${domain}`);
1808
- const result = await tagCtx.removeTag(domain, tagName);
1924
+ const fromLabel = fromDomain === '' ? '(root)' : fromDomain;
1925
+ console.log(`\nšŸ—‘ļø Removing tag "${tagName}"`);
1926
+ console.log(` From: ${fromLabel}`);
1927
+ console.log(` To: ${toDomain}`);
1928
+ const result = await tagCtx.removeTag(toDomain, tagName);
1809
1929
  if (result.success) {
1810
1930
  if (options.json) {
1811
1931
  console.log(JSON.stringify({
1812
1932
  success: true,
1813
- domain,
1933
+ from: fromDomain,
1934
+ to: toDomain,
1814
1935
  tagName,
1815
1936
  transactionHash: result.transactionHash,
1816
1937
  gasUsed: result.gasUsed?.toString(),
@@ -1839,16 +1960,21 @@ async function tagRemove(domain, tagName, options) {
1839
1960
  /**
1840
1961
  * List all tags for a domain
1841
1962
  */
1842
- async function tagList(domain, options) {
1963
+ async function tagList(toDomain, fromDomain, options) {
1843
1964
  try {
1844
1965
  const didConsole = getConsole(options);
1845
- const domainContext = didConsole.domain(domain);
1846
- console.log(`\nšŸ“‹ Listing all tags for domain: ${domain}`);
1847
- const tags = await domainContext.getAllTags();
1966
+ const domainContext = didConsole.domain(fromDomain);
1967
+ const tagCtx = domainContext.tag();
1968
+ const fromLabel = fromDomain === '' ? '(root)' : fromDomain;
1969
+ console.log(`\nšŸ“‹ Listing all tags`);
1970
+ console.log(` From: ${fromLabel}`);
1971
+ console.log(` To: ${toDomain}`);
1972
+ const tags = await tagCtx.getAllTags(toDomain);
1848
1973
  if (options.json) {
1849
1974
  console.log(JSON.stringify({
1850
1975
  success: true,
1851
- domain,
1976
+ from: fromDomain,
1977
+ to: toDomain,
1852
1978
  count: tags.length,
1853
1979
  tags
1854
1980
  }, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2));
@@ -1878,7 +2004,8 @@ async function tagListDefined(domain, options) {
1878
2004
  try {
1879
2005
  const didConsole = getConsole(options);
1880
2006
  const domainContext = didConsole.domain(domain);
1881
- console.log(`\nšŸ“‹ Listing defined tag types for domain: ${domain}`);
2007
+ const domainLabel = domain === '' ? '(root)' : domain;
2008
+ console.log(`\nšŸ“‹ Listing tag types defined by: ${domainLabel}`);
1882
2009
  const tags = await domainContext.getDefinedTags();
1883
2010
  if (options.json) {
1884
2011
  console.log(JSON.stringify({
@@ -2191,8 +2318,9 @@ async function main() {
2191
2318
  }
2192
2319
  else {
2193
2320
  console.error('āŒ Error: Usage: did-cli config set <key> <value> [--network <network>]');
2194
- console.error(' Valid keys: rpc, contractDid, contractRootResolver, contractAbiType, contractRootResolver2, supportSvcUrl');
2321
+ console.error(' Valid keys: rpc, contractDid, contractRootResolver, contractAbiType, contractRootResolver2, supportSvcUrl, queryContract');
2195
2322
  console.error('\n Example: did-cli config set rpc https://optimism.llamarpc.com --network mainnet');
2323
+ console.error(' Example: did-cli config set queryContract 0xAf0430AB9f2450c52E7401846C7CA702D53eCFC2 --network sepolia');
2196
2324
  process.exit(1);
2197
2325
  }
2198
2326
  break;
@@ -2341,7 +2469,7 @@ async function main() {
2341
2469
  case 'set':
2342
2470
  if (!domain || !value) {
2343
2471
  console.error('āŒ Error: tag set requires <domain>, <tag-name> and <value>');
2344
- console.error('Usage: did-cli tag set <domain> <tag-name> <value>');
2472
+ console.error('Usage: did-cli tag set <domain> <tag-name> <value> [--from <domain|root>]');
2345
2473
  console.error(' Value can be a string or JSON (e.g., \'["item1","item2"]\' for arrays)');
2346
2474
  console.error('\nNote: Set PRIVATE_KEY_OR_MNEMONIC environment variable first');
2347
2475
  process.exit(1);
@@ -2350,14 +2478,15 @@ async function main() {
2350
2478
  const args = process.argv.slice(2);
2351
2479
  const setIdx = args.indexOf('set');
2352
2480
  if (setIdx >= 0 && args.length > setIdx + 3) {
2353
- const actualDomain = args[setIdx + 1];
2481
+ const actualDomain = (0, olares_id_1.normalizeToDomain)(args[setIdx + 1]);
2482
+ const fromDomain = normalizeTagFromDomain(options.from, actualDomain);
2354
2483
  const tagName = args[setIdx + 2];
2355
2484
  const valueStr = args[setIdx + 3];
2356
- await tagSet(actualDomain, tagName, valueStr, options);
2485
+ await tagSet(actualDomain, fromDomain, tagName, valueStr, options);
2357
2486
  }
2358
2487
  else {
2359
2488
  console.error('āŒ Error: Missing arguments for tag set');
2360
- console.error('Usage: did-cli tag set <domain> <tag-name> <value>');
2489
+ console.error('Usage: did-cli tag set <domain> <tag-name> <value> [--from <domain|root>]');
2361
2490
  process.exit(1);
2362
2491
  }
2363
2492
  }
@@ -2365,20 +2494,21 @@ async function main() {
2365
2494
  case 'get':
2366
2495
  if (!domain) {
2367
2496
  console.error('āŒ Error: tag get requires <domain> and <tag-name>');
2368
- console.error('Usage: did-cli tag get <domain> <tag-name>');
2497
+ console.error('Usage: did-cli tag get <domain> <tag-name> [--from <domain|root>]');
2369
2498
  process.exit(1);
2370
2499
  }
2371
2500
  {
2372
2501
  const args = process.argv.slice(2);
2373
2502
  const getIdx = args.indexOf('get');
2374
2503
  if (getIdx >= 0 && args.length > getIdx + 2) {
2375
- const actualDomain = args[getIdx + 1];
2504
+ const actualDomain = (0, olares_id_1.normalizeToDomain)(args[getIdx + 1]);
2505
+ const fromDomain = normalizeTagFromDomain(options.from, actualDomain);
2376
2506
  const tagName = args[getIdx + 2];
2377
- await tagGet(actualDomain, tagName, options);
2507
+ await tagGet(actualDomain, fromDomain, tagName, options);
2378
2508
  }
2379
2509
  else {
2380
2510
  console.error('āŒ Error: Missing arguments for tag get');
2381
- console.error('Usage: did-cli tag get <domain> <tag-name>');
2511
+ console.error('Usage: did-cli tag get <domain> <tag-name> [--from <domain|root>]');
2382
2512
  process.exit(1);
2383
2513
  }
2384
2514
  }
@@ -2386,7 +2516,7 @@ async function main() {
2386
2516
  case 'remove':
2387
2517
  if (!domain) {
2388
2518
  console.error('āŒ Error: tag remove requires <domain> and <tag-name>');
2389
- console.error('Usage: did-cli tag remove <domain> <tag-name>');
2519
+ console.error('Usage: did-cli tag remove <domain> <tag-name> [--from <domain|root>]');
2390
2520
  console.error('\nNote: Set PRIVATE_KEY_OR_MNEMONIC environment variable first');
2391
2521
  process.exit(1);
2392
2522
  }
@@ -2394,13 +2524,14 @@ async function main() {
2394
2524
  const args = process.argv.slice(2);
2395
2525
  const removeIdx = args.indexOf('remove');
2396
2526
  if (removeIdx >= 0 && args.length > removeIdx + 2) {
2397
- const actualDomain = args[removeIdx + 1];
2527
+ const actualDomain = (0, olares_id_1.normalizeToDomain)(args[removeIdx + 1]);
2528
+ const fromDomain = normalizeTagFromDomain(options.from, actualDomain);
2398
2529
  const tagName = args[removeIdx + 2];
2399
- await tagRemove(actualDomain, tagName, options);
2530
+ await tagRemove(actualDomain, fromDomain, tagName, options);
2400
2531
  }
2401
2532
  else {
2402
2533
  console.error('āŒ Error: Missing arguments for tag remove');
2403
- console.error('Usage: did-cli tag remove <domain> <tag-name>');
2534
+ console.error('Usage: did-cli tag remove <domain> <tag-name> [--from <domain|root>]');
2404
2535
  process.exit(1);
2405
2536
  }
2406
2537
  }
@@ -2408,18 +2539,15 @@ async function main() {
2408
2539
  case 'list':
2409
2540
  if (!domain) {
2410
2541
  console.error('āŒ Error: Domain argument is required');
2411
- console.error('Usage: did-cli tag list <domain>');
2542
+ console.error('Usage: did-cli tag list <domain> [--from <domain|root>]');
2412
2543
  process.exit(1);
2413
2544
  }
2414
- await tagList(domain, options);
2545
+ const fromDomain = normalizeTagFromDomain(options.from, domain);
2546
+ await tagList(domain, fromDomain, options);
2415
2547
  break;
2416
2548
  case 'list-defined':
2417
- if (!domain) {
2418
- console.error('āŒ Error: Domain argument is required');
2419
- console.error('Usage: did-cli tag list-defined <domain>');
2420
- process.exit(1);
2421
- }
2422
- await tagListDefined(domain, options);
2549
+ // domain defaults to "" (root) when not provided
2550
+ await tagListDefined(domain ?? '', options);
2423
2551
  break;
2424
2552
  case 'set-tagger':
2425
2553
  if (!domain || !value) {
@@ -2483,6 +2611,9 @@ async function main() {
2483
2611
  }
2484
2612
  await fetchDomain(domain, options);
2485
2613
  break;
2614
+ case 'fetch-all':
2615
+ await fetchAll(options);
2616
+ break;
2486
2617
  default:
2487
2618
  console.error(`āŒ Unknown command: ${command}`);
2488
2619
  console.error('Run "did-cli help" for usage information');