@beclab/olaresid 0.1.1 → 0.1.3

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 (93) hide show
  1. package/CLI.md +1300 -0
  2. package/README.md +40 -31
  3. package/TAG.md +589 -0
  4. package/dist/abi/RootResolver2ABI.d.ts +54 -0
  5. package/dist/abi/RootResolver2ABI.d.ts.map +1 -0
  6. package/dist/abi/RootResolver2ABI.js +240 -0
  7. package/dist/abi/RootResolver2ABI.js.map +1 -0
  8. package/dist/business/index.d.ts +302 -0
  9. package/dist/business/index.d.ts.map +1 -0
  10. package/dist/business/index.js +1211 -0
  11. package/dist/business/index.js.map +1 -0
  12. package/dist/business/tag-context.d.ts +219 -0
  13. package/dist/business/tag-context.d.ts.map +1 -0
  14. package/dist/business/tag-context.js +560 -0
  15. package/dist/business/tag-context.js.map +1 -0
  16. package/dist/cli.js +2102 -39
  17. package/dist/cli.js.map +1 -1
  18. package/dist/debug.d.ts.map +1 -1
  19. package/dist/debug.js +14 -2
  20. package/dist/debug.js.map +1 -1
  21. package/dist/index.d.ts +51 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +241 -12
  24. package/dist/index.js.map +1 -1
  25. package/dist/utils/crypto-utils.d.ts +130 -0
  26. package/dist/utils/crypto-utils.d.ts.map +1 -0
  27. package/dist/utils/crypto-utils.js +402 -0
  28. package/dist/utils/crypto-utils.js.map +1 -0
  29. package/dist/utils/error-parser.d.ts +35 -0
  30. package/dist/utils/error-parser.d.ts.map +1 -0
  31. package/dist/utils/error-parser.js +202 -0
  32. package/dist/utils/error-parser.js.map +1 -0
  33. package/dist/utils/olares-id.d.ts +36 -0
  34. package/dist/utils/olares-id.d.ts.map +1 -0
  35. package/dist/utils/olares-id.js +52 -0
  36. package/dist/utils/olares-id.js.map +1 -0
  37. package/dist/utils/tag-abi-codec.d.ts +69 -0
  38. package/dist/utils/tag-abi-codec.d.ts.map +1 -0
  39. package/dist/utils/tag-abi-codec.js +144 -0
  40. package/dist/utils/tag-abi-codec.js.map +1 -0
  41. package/dist/utils/tag-type-builder.d.ts +158 -0
  42. package/dist/utils/tag-type-builder.d.ts.map +1 -0
  43. package/dist/utils/tag-type-builder.js +410 -0
  44. package/dist/utils/tag-type-builder.js.map +1 -0
  45. package/examples/crypto-utilities.ts +140 -0
  46. package/examples/domain-context.ts +80 -0
  47. package/examples/generate-mnemonic.ts +149 -0
  48. package/examples/index.ts +1 -1
  49. package/examples/ip.ts +171 -0
  50. package/examples/legacy.ts +10 -10
  51. package/examples/list-wallets.ts +81 -0
  52. package/examples/olares-id-format.ts +197 -0
  53. package/examples/quasar-demo/.eslintrc.js +23 -0
  54. package/examples/quasar-demo/.quasar/app.js +43 -0
  55. package/examples/quasar-demo/.quasar/client-entry.js +38 -0
  56. package/examples/quasar-demo/.quasar/client-prefetch.js +130 -0
  57. package/examples/quasar-demo/.quasar/quasar-user-options.js +16 -0
  58. package/examples/quasar-demo/README.md +49 -0
  59. package/examples/quasar-demo/index.html +11 -0
  60. package/examples/quasar-demo/package-lock.json +6407 -0
  61. package/examples/quasar-demo/package.json +36 -0
  62. package/examples/quasar-demo/quasar.config.js +73 -0
  63. package/examples/quasar-demo/src/App.vue +13 -0
  64. package/examples/quasar-demo/src/css/app.scss +1 -0
  65. package/examples/quasar-demo/src/layouts/MainLayout.vue +21 -0
  66. package/examples/quasar-demo/src/pages/IndexPage.vue +905 -0
  67. package/examples/quasar-demo/src/router/index.ts +25 -0
  68. package/examples/quasar-demo/src/router/routes.ts +11 -0
  69. package/examples/quasar-demo/tsconfig.json +28 -0
  70. package/examples/register-subdomain.ts +152 -0
  71. package/examples/rsa-keypair.ts +148 -0
  72. package/examples/tag-builder.ts +235 -0
  73. package/examples/tag-management.ts +534 -0
  74. package/examples/tag-nested-tuple.ts +190 -0
  75. package/examples/tag-simple.ts +149 -0
  76. package/examples/tag-tagger.ts +217 -0
  77. package/examples/test-nested-tuple-conversion.ts +143 -0
  78. package/examples/test-type-bytes-parser.ts +70 -0
  79. package/examples/transfer-domain.ts +197 -0
  80. package/examples/wallet-management.ts +196 -0
  81. package/package.json +24 -15
  82. package/src/abi/RootResolver2ABI.ts +237 -0
  83. package/src/business/index.ts +1492 -0
  84. package/src/business/tag-context.ts +747 -0
  85. package/src/cli.ts +2772 -39
  86. package/src/debug.ts +17 -2
  87. package/src/index.ts +313 -17
  88. package/src/utils/crypto-utils.ts +459 -0
  89. package/src/utils/error-parser.ts +225 -0
  90. package/src/utils/olares-id.ts +49 -0
  91. package/src/utils/tag-abi-codec.ts +158 -0
  92. package/src/utils/tag-type-builder.ts +469 -0
  93. package/tsconfig.json +1 -1
package/src/debug.ts CHANGED
@@ -18,14 +18,29 @@ class DebugLogger {
18
18
  }
19
19
 
20
20
  private parseConfig(): DebugConfig {
21
- // Check environment variables
21
+ // Check if running in Node.js environment
22
+ const isNode =
23
+ typeof process !== 'undefined' &&
24
+ process.versions &&
25
+ process.versions.node;
26
+
27
+ // Default config for browser
28
+ if (!isNode) {
29
+ return {
30
+ enabled: false,
31
+ level: 'debug',
32
+ prefix: '[DID-DEBUG]'
33
+ };
34
+ }
35
+
36
+ // Check environment variables (Node.js only)
22
37
  const envDebug =
23
38
  process.env.DEBUG === 'true' || process.env.DEBUG === '1';
24
39
  const envLevel =
25
40
  (process.env.DEBUG_LEVEL as DebugConfig['level']) || 'debug';
26
41
  const envPrefix = process.env.DEBUG_PREFIX || '[DID-DEBUG]';
27
42
 
28
- // Check command line arguments
43
+ // Check command line arguments (Node.js only)
29
44
  const args = process.argv;
30
45
  const hasDebugFlag = args.includes('--debug') || args.includes('-d');
31
46
  const hasVerboseFlag =
package/src/index.ts CHANGED
@@ -3,7 +3,63 @@ import DIDTag from './tag/index';
3
3
  import { ethers } from 'ethers';
4
4
  import DID_ABI from './abi/TerminusDIDABI';
5
5
  import RootResolverABI from './abi/RootResolverABI';
6
+ import RootResolver2ABI from './abi/RootResolver2ABI';
6
7
  import { debug } from './debug';
8
+ import { parseContractError } from './utils/error-parser';
9
+ import { normalizeToDomain } from './utils/olares-id';
10
+
11
+ import {
12
+ DomainContext,
13
+ DomainMetaInfo,
14
+ DomainInfo,
15
+ TagInfo,
16
+ TransactionResult,
17
+ RSAPublicKeyData,
18
+ DIDKeyData,
19
+ UserType,
20
+ createRsaKeyPair,
21
+ pemToDer,
22
+ derToPem,
23
+ ipv4ToBytes4,
24
+ bytes4ToIpv4,
25
+ generateMnemonic,
26
+ getEthereumAddressFromMnemonic,
27
+ getEVMPrivateKeyFromMnemonic,
28
+ getDIDFromMnemonic,
29
+ generateDIDKeyData,
30
+ deriveDIDFromMnemonic
31
+ } from './business';
32
+ import { TagContext } from './business/tag-context';
33
+
34
+ // Import Tag utilities
35
+ import { TagTypeBuilder } from './utils/tag-type-builder';
36
+ import { TagAbiCodec } from './utils/tag-abi-codec';
37
+
38
+ export type {
39
+ DomainInfo,
40
+ DomainMetaInfo,
41
+ TagInfo,
42
+ TransactionResult,
43
+ RSAPublicKeyData,
44
+ DIDKeyData
45
+ } from './business';
46
+
47
+ export {
48
+ UserType,
49
+ DomainContext,
50
+ TagContext,
51
+ createRsaKeyPair,
52
+ pemToDer,
53
+ derToPem,
54
+ ipv4ToBytes4,
55
+ bytes4ToIpv4,
56
+ generateMnemonic,
57
+ getEthereumAddressFromMnemonic,
58
+ getEVMPrivateKeyFromMnemonic,
59
+ getDIDFromMnemonic,
60
+ generateDIDKeyData,
61
+ deriveDIDFromMnemonic
62
+ } from './business';
7
63
 
8
64
  type Domain = PackageDomain.Domain;
9
65
 
@@ -14,26 +70,117 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
14
70
  contractDid: string;
15
71
  contractRootResolver: string;
16
72
  contractAbiType: string;
73
+ contractRootResolver2?: string;
74
+ supportSvcUrl?: string;
75
+
76
+ signer?: ethers.Signer;
17
77
 
18
78
  allDomainCache: Domain[] = [];
19
79
  treesCache: Domain[] = [];
20
80
 
81
+ // caching contract instances
82
+ private _contractDID?: ethers.Contract;
83
+ private _signerContractDID?: ethers.Contract;
84
+ private _contractRootResolver?: ethers.Contract;
85
+ private _signerContractRootResolver?: ethers.Contract;
86
+ private _contractRootResolver2?: ethers.Contract;
87
+ private _signerContractRootResolver2?: ethers.Contract;
88
+
89
+ private _provider?: ethers.JsonRpcProvider;
90
+
21
91
  constructor(
22
92
  rpcNode: string,
23
93
  contractDid: string,
24
94
  contractRootResolver: string,
25
- contractAbiType: string
95
+ contractAbiType: string,
96
+ contractRootResolver2?: string,
97
+ supportSvcUrl?: string
26
98
  ) {
27
99
  this.rpcNode = rpcNode;
28
100
  this.contractDid = contractDid;
29
101
  this.contractRootResolver = contractRootResolver;
30
102
  this.contractAbiType = contractAbiType;
103
+ this.contractRootResolver2 = contractRootResolver2;
104
+ this.supportSvcUrl = supportSvcUrl;
31
105
  }
32
106
 
33
- getProvider = () => new ethers.JsonRpcProvider(this.rpcNode);
107
+ getProvider = (): ethers.JsonRpcProvider => {
108
+ if (!this._provider) {
109
+ this._provider = new ethers.JsonRpcProvider(this.rpcNode);
110
+ }
111
+ return this._provider;
112
+ };
113
+
114
+ setSigner = async (
115
+ signerOrPrivateKeyOrMnemonic: ethers.Signer | string
116
+ ) => {
117
+ if (typeof signerOrPrivateKeyOrMnemonic === 'string') {
118
+ // Check if it's a mnemonic (12-24 words) or private key (0x... hex)
119
+ const trimmed = signerOrPrivateKeyOrMnemonic.trim();
120
+ const wordCount = trimmed.split(/\s+/).length;
121
+
122
+ // If it's 12-24 words, treat it as a mnemonic
123
+ if (wordCount >= 12 && wordCount <= 24) {
124
+ // Import and use the mnemonic conversion function
125
+ const { getEVMPrivateKeyFromMnemonic } = await import(
126
+ './utils/crypto-utils'
127
+ );
128
+ const privateKey = await getEVMPrivateKeyFromMnemonic(trimmed);
129
+ this.signer = new ethers.Wallet(privateKey, this.getProvider());
130
+ } else {
131
+ // Treat as private key
132
+ this.signer = new ethers.Wallet(
133
+ signerOrPrivateKeyOrMnemonic,
134
+ this.getProvider()
135
+ );
136
+ }
137
+ } else {
138
+ this.signer = signerOrPrivateKeyOrMnemonic;
139
+ }
140
+
141
+ // reset cached signer contracts
142
+ this._signerContractDID = undefined;
143
+ this._signerContractRootResolver = undefined;
144
+ this._signerContractRootResolver2 = undefined;
145
+ };
146
+
147
+ getSigner = (): ethers.Signer => {
148
+ if (!this.signer) {
149
+ throw new Error('No signer available.');
150
+ }
151
+ return this.signer;
152
+ };
153
+
154
+ clearSigner = () => {
155
+ this.signer = undefined;
34
156
 
35
- getContractDID = () =>
36
- new ethers.Contract(this.contractDid, DID_ABI.abi, this.getProvider());
157
+ // reset cached signer contracts
158
+ this._signerContractDID = undefined;
159
+ this._signerContractRootResolver = undefined;
160
+ this._signerContractRootResolver2 = undefined;
161
+ };
162
+
163
+ getContractDID = (): ethers.Contract => {
164
+ if (!this._contractDID) {
165
+ this._contractDID = new ethers.Contract(
166
+ this.contractDid,
167
+ DID_ABI.abi,
168
+ this.getProvider()
169
+ );
170
+ }
171
+ return this._contractDID;
172
+ };
173
+
174
+ getSignerContractDID = (): ethers.Contract => {
175
+ if (!this._signerContractDID) {
176
+ this._signerContractDID = new ethers.Contract(
177
+ this.contractDid,
178
+ DID_ABI.abi,
179
+ this.getSigner()
180
+ );
181
+ }
182
+ return this._signerContractDID;
183
+ };
37
184
 
38
185
  getContractDIDByPrivateKey = (privateKey: string) => {
39
186
  const wallet = new ethers.Wallet(privateKey, this.getProvider());
@@ -55,12 +202,57 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
55
202
  await provider.getSigner()
56
203
  );
57
204
 
58
- getContractRootResolver = () =>
59
- new ethers.Contract(
60
- this.contractRootResolver,
61
- RootResolverABI.abi,
62
- this.getProvider()
63
- );
205
+ getContractRootResolver = (): ethers.Contract => {
206
+ if (!this._contractRootResolver) {
207
+ this._contractRootResolver = new ethers.Contract(
208
+ this.contractRootResolver,
209
+ RootResolverABI.abi,
210
+ this.getProvider()
211
+ );
212
+ }
213
+ return this._contractRootResolver;
214
+ };
215
+
216
+ getSignerContractRootResolver = (): ethers.Contract => {
217
+ if (!this._signerContractRootResolver) {
218
+ this._signerContractRootResolver = new ethers.Contract(
219
+ this.contractRootResolver,
220
+ RootResolverABI.abi,
221
+ this.getSigner()
222
+ );
223
+ }
224
+ return this._signerContractRootResolver;
225
+ };
226
+
227
+ getContractRootResolver2 = (): ethers.Contract => {
228
+ if (!this.contractRootResolver2) {
229
+ throw new Error('No contractRootResolver2 provided.');
230
+ }
231
+
232
+ if (!this._contractRootResolver2) {
233
+ this._contractRootResolver2 = new ethers.Contract(
234
+ this.contractRootResolver2,
235
+ RootResolver2ABI.abi,
236
+ this.getProvider()
237
+ );
238
+ }
239
+ return this._contractRootResolver2;
240
+ };
241
+
242
+ getSignerContractRootResolver2 = (): ethers.Contract => {
243
+ if (!this.contractRootResolver2) {
244
+ throw new Error('No contractRootResolver2 provided.');
245
+ }
246
+
247
+ if (!this._signerContractRootResolver2) {
248
+ this._signerContractRootResolver2 = new ethers.Contract(
249
+ this.contractRootResolver2,
250
+ RootResolver2ABI.abi,
251
+ this.getSigner()
252
+ );
253
+ }
254
+ return this._signerContractRootResolver2;
255
+ };
64
256
 
65
257
  getSignerContractRootResolverByProvider = async (
66
258
  provider: ethers.JsonRpcApiProvider
@@ -98,13 +290,16 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
98
290
 
99
291
  fetchDomain = (name: string) =>
100
292
  new Promise<Domain | undefined>(async (resolve, reject) => {
293
+ // Support Olares ID format (user@domain.com)
294
+ const normalizedName = normalizeToDomain(name);
295
+
101
296
  debug.group('fetchDomain');
102
297
  const hasCache = this.allDomainCache.length > 0;
103
298
  debug.info('fetchDomain--->hasCache', hasCache);
104
299
 
105
300
  if (hasCache) {
106
301
  const domain = PackageDomain.findASubtree(
107
- name,
302
+ normalizedName,
108
303
  this.allDomainCache
109
304
  );
110
305
 
@@ -112,7 +307,7 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
112
307
  resolve(domain);
113
308
  } else {
114
309
  const domain = await PackageDomain.syncByName(
115
- name,
310
+ normalizedName,
116
311
  await this.getContractDID()
117
312
  );
118
313
 
@@ -123,8 +318,11 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
123
318
 
124
319
  updateDomain = (name: string) =>
125
320
  new Promise<Domain>(async (resolve, reject) => {
321
+ // Support Olares ID format (user@domain.com)
322
+ const normalizedName = normalizeToDomain(name);
323
+
126
324
  const domain = await PackageDomain.syncByName(
127
- name,
325
+ normalizedName,
128
326
  await this.getContractDID()
129
327
  );
130
328
 
@@ -252,6 +450,89 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
252
450
 
253
451
  resolve(datas);
254
452
  });
453
+
454
+ /**
455
+ * Uses a chain-style operation design pattern, returning the operation context for the specified domain
456
+ * For example: await console.domain('developer.olares.com').setRSAPublicKey(rsaKey);
457
+ */
458
+ domain(name: string): DomainContext {
459
+ return new DomainContext(name, this);
460
+ }
461
+
462
+ /**
463
+ * Set the operator address (super admin)
464
+ * Only the contract owner can call this method
465
+ */
466
+ async setOperator(newOperator: string): Promise<TransactionResult> {
467
+ try {
468
+ const contract = this.getSignerContractDID();
469
+ const tx = await contract.setOperator(newOperator);
470
+ const receipt = await tx.wait();
471
+
472
+ return {
473
+ success: true,
474
+ transactionHash: receipt.hash,
475
+ gasUsed: receipt.gasUsed,
476
+ blockNumber: receipt.blockNumber
477
+ };
478
+ } catch (error) {
479
+ const parsedError = parseContractError(error);
480
+
481
+ // Always throw network errors
482
+ if (parsedError.isNetworkError) {
483
+ throw new Error(`Network error: ${parsedError.message}`);
484
+ }
485
+
486
+ // Return friendly contract error
487
+ return {
488
+ success: false,
489
+ transactionHash: '',
490
+ error: parsedError.message
491
+ };
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Get the current operator address (super admin)
497
+ * @returns The operator address
498
+ */
499
+ async getOperator(): Promise<string> {
500
+ try {
501
+ const contract = this.getContractDID();
502
+ return await contract.operator();
503
+ } catch (error) {
504
+ const parsedError = parseContractError(error);
505
+ throw new Error(parsedError.message);
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Get contract owner address
511
+ * @returns The contract owner address
512
+ */
513
+ async getOwner(): Promise<string> {
514
+ try {
515
+ const contract = this.getContractDID();
516
+ return await contract.owner();
517
+ } catch (error) {
518
+ const parsedError = parseContractError(error);
519
+ throw new Error(parsedError.message);
520
+ }
521
+ }
522
+
523
+ /**
524
+ * Get total supply of domains
525
+ * @returns The total number of registered domains
526
+ */
527
+ async getTotalSupply(): Promise<bigint> {
528
+ try {
529
+ const contract = this.getContractDID();
530
+ return await contract.totalSupply();
531
+ } catch (error) {
532
+ const parsedError = parseContractError(error);
533
+ throw new Error(parsedError.message);
534
+ }
535
+ }
255
536
  }
256
537
 
257
538
  namespace OlaresID {
@@ -259,13 +540,17 @@ namespace OlaresID {
259
540
  rpcNode: string,
260
541
  contractDid: string,
261
542
  contractRootResolver: string,
262
- contractAbiType: string
543
+ contractAbiType: string,
544
+ contractRootResolver2?: string,
545
+ supportSvcUrl?: string
263
546
  ): DIDConsole => {
264
547
  return new DIDConsole(
265
548
  rpcNode,
266
549
  contractDid,
267
550
  contractRootResolver,
268
- contractAbiType
551
+ contractAbiType,
552
+ contractRootResolver2,
553
+ supportSvcUrl
269
554
  );
270
555
  };
271
556
 
@@ -274,7 +559,9 @@ namespace OlaresID {
274
559
  'https://optimism-rpc.publicnode.com',
275
560
  '0x5DA4Fa8E567d86e52Ef8Da860de1be8f54cae97D',
276
561
  '0xE2EABA0979277A90511F8873ae1e8cA26B54E740',
277
- '0x9ae3F16bD99294Af1784beB1a0A5C84bf2636365'
562
+ '0x9ae3F16bD99294Af1784beB1a0A5C84bf2636365',
563
+ '0x7e7961aB771cA942CE4DB6e79579e016a33Dc95B',
564
+ 'https://api.olares.com/did/support'
278
565
  );
279
566
  };
280
567
 
@@ -283,7 +570,9 @@ namespace OlaresID {
283
570
  'https://sepolia.optimism.io',
284
571
  '0xe2D7c3a9013960E04d4E9F5F9B63fff37eEd97A8',
285
572
  '0xeF727cb066Fee98F88Db84555830063b4A24ddfc',
286
- '0x7386fCBae6Ad4CCE1499d9153D99bc950B589718'
573
+ '0x7386fCBae6Ad4CCE1499d9153D99bc950B589718',
574
+ '0xcbC02aa08c77a374eC0D5A0403E108b7573d96e8',
575
+ 'https://api-test.olares.com/did/support'
287
576
  );
288
577
  };
289
578
 
@@ -299,4 +588,11 @@ namespace OlaresID {
299
588
  }
300
589
 
301
590
  export { debug } from './debug';
591
+
592
+ // Export Tag utilities outside namespace
593
+ export { TagTypeBuilder, TagAbiCodec };
594
+
595
+ // Export Olares ID utilities
596
+ export { normalizeToDomain, normalizeToOlaresId } from './utils/olares-id';
597
+
302
598
  export default OlaresID;