@beclab/olaresid 0.1.2 → 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.
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Example: Testing Olares ID Format Support
3
+ *
4
+ * This example demonstrates the new Olares ID format support.
5
+ * Olares ID uses @ instead of the first dot, making it look like an email address.
6
+ *
7
+ * Format conversion:
8
+ * - Standard domain: alice.example.com
9
+ * - Olares ID format: alice@example.com
10
+ *
11
+ * Both formats should work identically in the SDK and CLI.
12
+ */
13
+
14
+ import OlaresID from '../src/index';
15
+ import { normalizeToDomain, normalizeToOlaresId } from '../src/utils/olares-id';
16
+
17
+ async function main() {
18
+ console.log('='.repeat(80));
19
+ console.log('Testing Olares ID Format Support');
20
+ console.log('='.repeat(80));
21
+
22
+ // Test 1: Utility Functions
23
+ console.log('\nšŸ“ Test 1: Olares ID Utility Functions');
24
+ console.log('-'.repeat(80));
25
+
26
+ const testCases = [
27
+ { input: 'alice@example.com', expected: 'alice.example.com' },
28
+ { input: 'bob@sub.example.com', expected: 'bob.sub.example.com' },
29
+ { input: 'charlie.example.com', expected: 'charlie.example.com' },
30
+ { input: 'user@olares.com', expected: 'user.olares.com' }
31
+ ];
32
+
33
+ console.log('Testing normalizeToDomain():');
34
+ for (const test of testCases) {
35
+ const result = normalizeToDomain(test.input);
36
+ const status = result === test.expected ? 'āœ…' : 'āŒ';
37
+ console.log(
38
+ ` ${status} normalizeToDomain('${test.input}') => '${result}' (expected: '${test.expected}')`
39
+ );
40
+ }
41
+
42
+ console.log('\nTesting normalizeToOlaresId():');
43
+ const domainToOlaresIdTests = [
44
+ { input: 'alice.example.com', expected: 'alice@example.com' },
45
+ { input: 'bob.sub.example.com', expected: 'bob@sub.example.com' }
46
+ ];
47
+
48
+ for (const test of domainToOlaresIdTests) {
49
+ const result = normalizeToOlaresId(test.input);
50
+ const status = result === test.expected ? 'āœ…' : 'āŒ';
51
+ console.log(
52
+ ` ${status} normalizeToOlaresId('${test.input}') => '${result}' (expected: '${test.expected}')`
53
+ );
54
+ }
55
+
56
+ // Test 2: SDK with Olares ID Format
57
+ console.log('\nšŸ”§ Test 2: SDK with Olares ID Format');
58
+ console.log('-'.repeat(80));
59
+
60
+ const didConsole = OlaresID.createTestnet();
61
+
62
+ // Use a real test domain (1.com is a common test domain on testnet)
63
+ const testDomainStandard = '1.com';
64
+ const testDomainOlaresId = '1@com'; // Olares ID format
65
+
66
+ console.log('\nTesting with standard domain format:', testDomainStandard);
67
+ try {
68
+ const domainStandard = didConsole.domain(testDomainStandard);
69
+ const metaStandard = await domainStandard.getMetaInfo();
70
+ console.log('āœ… Standard format works:');
71
+ console.log(' Name:', metaStandard.name);
72
+ console.log(' DID:', metaStandard.did);
73
+ console.log(' Owner:', await domainStandard.getOwner());
74
+ } catch (error) {
75
+ console.error('āŒ Standard format failed:', error);
76
+ }
77
+
78
+ console.log('\nTesting with Olares ID format:', testDomainOlaresId);
79
+ try {
80
+ const domainOlaresId = didConsole.domain(testDomainOlaresId);
81
+ const metaOlaresId = await domainOlaresId.getMetaInfo();
82
+ console.log('āœ… Olares ID format works:');
83
+ console.log(' Name:', metaOlaresId.name);
84
+ console.log(' DID:', metaOlaresId.did);
85
+ console.log(' Owner:', await domainOlaresId.getOwner());
86
+ } catch (error) {
87
+ console.error('āŒ Olares ID format failed:', error);
88
+ }
89
+
90
+ // Test 3: Verify Both Formats Return Same Data
91
+ console.log('\nšŸ” Test 3: Verify Both Formats Return Same Data');
92
+ console.log('-'.repeat(80));
93
+
94
+ try {
95
+ const domainStandard = didConsole.domain(testDomainStandard);
96
+ const domainOlaresId = didConsole.domain(testDomainOlaresId);
97
+
98
+ const [metaStandard, metaOlaresId] = await Promise.all([
99
+ domainStandard.getMetaInfo(),
100
+ domainOlaresId.getMetaInfo()
101
+ ]);
102
+
103
+ const ownerStandard = await domainStandard.getOwner();
104
+ const ownerOlaresId = await domainOlaresId.getOwner();
105
+
106
+ console.log('Comparing results:');
107
+ console.log(
108
+ ` Name match: ${
109
+ metaStandard.name === metaOlaresId.name ? 'āœ…' : 'āŒ'
110
+ } (${metaStandard.name} vs ${metaOlaresId.name})`
111
+ );
112
+ console.log(
113
+ ` DID match: ${
114
+ metaStandard.did === metaOlaresId.did ? 'āœ…' : 'āŒ'
115
+ }`
116
+ );
117
+ console.log(
118
+ ` Owner match: ${
119
+ ownerStandard === ownerOlaresId ? 'āœ…' : 'āŒ'
120
+ } (${ownerStandard} vs ${ownerOlaresId})`
121
+ );
122
+ console.log(
123
+ ` TokenId match: ${
124
+ domainStandard.getTokenId() === domainOlaresId.getTokenId()
125
+ ? 'āœ…'
126
+ : 'āŒ'
127
+ }`
128
+ );
129
+ } catch (error) {
130
+ console.error('āŒ Comparison failed:', error);
131
+ }
132
+
133
+ // Test 4: Multi-level Domain Support
134
+ console.log('\n🌳 Test 4: Multi-level Domain Support');
135
+ console.log('-'.repeat(80));
136
+
137
+ const multiLevelTests = [
138
+ { standard: 'alice.example.com', olaresId: 'alice@example.com' },
139
+ { standard: 'bob.sub.example.com', olaresId: 'bob@sub.example.com' },
140
+ {
141
+ standard: 'user.deep.nested.domain.com',
142
+ olaresId: 'user@deep.nested.domain.com'
143
+ }
144
+ ];
145
+
146
+ for (const test of multiLevelTests) {
147
+ const normalized = normalizeToDomain(test.olaresId);
148
+ const matches = normalized === test.standard;
149
+ console.log(
150
+ ` ${matches ? 'āœ…' : 'āŒ'} ${
151
+ test.olaresId
152
+ } => ${normalized} (expected: ${test.standard})`
153
+ );
154
+ }
155
+
156
+ // Test 5: Edge Cases
157
+ console.log('\nāš ļø Test 5: Edge Cases');
158
+ console.log('-'.repeat(80));
159
+
160
+ const edgeCases = [
161
+ { input: '', description: 'Empty string' },
162
+ { input: 'nodot', description: 'No dot or @' },
163
+ {
164
+ input: 'multiple@at@signs.com',
165
+ description: 'Multiple @ signs (only first is converted)'
166
+ },
167
+ { input: '.startswithdot', description: 'Starts with dot' },
168
+ { input: '@startswithat', description: 'Starts with @' }
169
+ ];
170
+
171
+ for (const test of edgeCases) {
172
+ try {
173
+ const result = normalizeToDomain(test.input);
174
+ console.log(
175
+ ` ā„¹ļø ${test.description}: '${test.input}' => '${result}'`
176
+ );
177
+ } catch (error) {
178
+ console.log(` ā„¹ļø ${test.description}: Error - ${error}`);
179
+ }
180
+ }
181
+
182
+ console.log('\n' + '='.repeat(80));
183
+ console.log('āœ… All Olares ID format tests completed!');
184
+ console.log('='.repeat(80));
185
+ console.log('\nšŸ’” Key Takeaways:');
186
+ console.log(
187
+ ' • Both standard domain and Olares ID formats work identically'
188
+ );
189
+ console.log(
190
+ ' • Use alice@example.com instead of alice.example.com for a more intuitive format'
191
+ );
192
+ console.log(' • The conversion happens automatically in the SDK and CLI');
193
+ console.log(' • Only the first dot/@ is affected by the conversion');
194
+ console.log('='.repeat(80));
195
+ }
196
+
197
+ main().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beclab/olaresid",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "DID Contract SDK with CLI tool",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -3,6 +3,7 @@ import { ethers } from 'ethers';
3
3
  import { parseContractError } from '../utils/error-parser';
4
4
  import { TagContext } from './tag-context';
5
5
  import { TagTypeBuilder } from '../utils/tag-type-builder';
6
+ import { normalizeToDomain } from '../utils/olares-id';
6
7
 
7
8
  export interface TransactionResult<T = any> {
8
9
  // Basic transaction information
@@ -71,7 +72,8 @@ export class DomainContext {
71
72
  private tokenId?: string;
72
73
 
73
74
  constructor(domainName: string, console: DIDConsole) {
74
- this.domainName = domainName;
75
+ // Support Olares ID format (user@domain.com) by converting to standard domain format
76
+ this.domainName = normalizeToDomain(domainName);
75
77
  this.console = console;
76
78
  }
77
79
 
@@ -3,13 +3,17 @@ import { TransactionResult } from './index';
3
3
  import { parseContractError } from '../utils/error-parser';
4
4
  import { TagTypeBuilder } from '../utils/tag-type-builder';
5
5
  import { TagAbiCodec } from '../utils/tag-abi-codec';
6
+ import { normalizeToDomain } from '../utils/olares-id';
6
7
 
7
8
  /**
8
9
  * Tag Operation Context
9
10
  * Provides complete Tag management functionality
10
11
  */
11
12
  export class TagContext {
12
- constructor(private console: DIDConsole, private fromDomain: string) {}
13
+ constructor(private console: DIDConsole, private fromDomain: string) {
14
+ // Support Olares ID format (user@domain.com)
15
+ this.fromDomain = normalizeToDomain(fromDomain);
16
+ }
13
17
 
14
18
  // ========================================
15
19
  // 1. Tag Type Definition Management
@@ -214,6 +218,9 @@ export class TagContext {
214
218
  tagName: string,
215
219
  value: any
216
220
  ): Promise<TransactionResult> {
221
+ // Support Olares ID format
222
+ toDomain = normalizeToDomain(toDomain);
223
+
217
224
  const contract = this.console.getSignerContractDID();
218
225
 
219
226
  // Get tag type
@@ -285,6 +292,9 @@ export class TagContext {
285
292
  * @returns Tag value, or null if not found
286
293
  */
287
294
  async getTag(toDomain: string, tagName: string): Promise<any | null> {
295
+ // Support Olares ID format
296
+ toDomain = normalizeToDomain(toDomain);
297
+
288
298
  try {
289
299
  const contract = this.console.getContractDID();
290
300
 
@@ -332,6 +342,9 @@ export class TagContext {
332
342
  toDomain: string,
333
343
  tagName: string
334
344
  ): Promise<TransactionResult> {
345
+ // Support Olares ID format
346
+ toDomain = normalizeToDomain(toDomain);
347
+
335
348
  try {
336
349
  const contract = this.console.getSignerContractDID();
337
350
  const tx = await contract.removeTag(
@@ -363,6 +376,9 @@ export class TagContext {
363
376
  * @returns Whether the tag exists
364
377
  */
365
378
  async hasTag(toDomain: string, tagName: string): Promise<boolean> {
379
+ // Support Olares ID format
380
+ toDomain = normalizeToDomain(toDomain);
381
+
366
382
  const contract = this.console.getContractDID();
367
383
  return await contract.hasTag(this.fromDomain, toDomain, tagName);
368
384
  }
@@ -373,6 +389,9 @@ export class TagContext {
373
389
  * @returns Array of Tag names
374
390
  */
375
391
  async getTagNames(toDomain: string): Promise<string[]> {
392
+ // Support Olares ID format
393
+ toDomain = normalizeToDomain(toDomain);
394
+
376
395
  const contract = this.console.getContractDID();
377
396
  const count = await contract.getTagCount(this.fromDomain, toDomain);
378
397
  const names: string[] = [];
@@ -433,6 +452,9 @@ export class TagContext {
433
452
  value: any,
434
453
  elemPath: number[] = []
435
454
  ): Promise<TransactionResult> {
455
+ // Support Olares ID format
456
+ toDomain = normalizeToDomain(toDomain);
457
+
436
458
  const contract = this.console.getSignerContractDID();
437
459
 
438
460
  // Get tag type and encode element
@@ -490,6 +512,9 @@ export class TagContext {
490
512
  tagName: string,
491
513
  elemPath: number[] = []
492
514
  ): Promise<TransactionResult> {
515
+ // Support Olares ID format
516
+ toDomain = normalizeToDomain(toDomain);
517
+
493
518
  try {
494
519
  const contract = this.console.getSignerContractDID();
495
520
  const tx = await contract.popTagElem(
@@ -536,6 +561,9 @@ export class TagContext {
536
561
  elemPath: number[],
537
562
  value: any
538
563
  ): Promise<TransactionResult> {
564
+ // Support Olares ID format
565
+ toDomain = normalizeToDomain(toDomain);
566
+
539
567
  const contract = this.console.getSignerContractDID();
540
568
 
541
569
  const tagTypeInfo = await this.getTagType(tagName);
@@ -592,6 +620,9 @@ export class TagContext {
592
620
  tagName: string,
593
621
  elemPath: number[] = []
594
622
  ): Promise<number> {
623
+ // Support Olares ID format
624
+ toDomain = normalizeToDomain(toDomain);
625
+
595
626
  const contract = this.console.getContractDID();
596
627
  const length = await contract.getTagElemLength(
597
628
  this.fromDomain,
@@ -621,6 +652,9 @@ export class TagContext {
621
652
  tagName: string,
622
653
  elemPath: number[]
623
654
  ): Promise<any | null> {
655
+ // Support Olares ID format
656
+ toDomain = normalizeToDomain(toDomain);
657
+
624
658
  try {
625
659
  const contract = this.console.getContractDID();
626
660
 
package/src/cli.ts CHANGED
@@ -15,6 +15,7 @@ import OlaresID, {
15
15
  TagTypeBuilder
16
16
  } from './index';
17
17
  import { debug } from './debug';
18
+ import { normalizeToDomain } from './utils/olares-id';
18
19
  import * as fs from 'fs';
19
20
  import * as path from 'path';
20
21
 
@@ -155,6 +156,11 @@ DID CLI Tool v${CLI_VERSION}
155
156
  USAGE:
156
157
  did-cli <command> [subcommand] [arguments] [options]
157
158
 
159
+ NOTE:
160
+ Olares ID Format: You can use @ instead of the first dot in domain names.
161
+ Example: alice@example.com is equivalent to alice.example.com
162
+ Both formats work identically in all commands!
163
+
158
164
  COMMANDS:
159
165
  Query Commands:
160
166
  info <domain> Get domain metadata
@@ -261,6 +267,14 @@ EXAMPLES:
261
267
  export PRIVATE_KEY_OR_MNEMONIC=0xYOUR_PRIVATE_KEY
262
268
  did-cli is-owner example.olares.com
263
269
 
270
+ # Olares ID format (use @ instead of first dot - like email addresses!)
271
+ # Both formats work identically: alice.example.com = alice@example.com
272
+ did-cli info alice@example.com
273
+ did-cli owner bob@sub.example.com
274
+ did-cli rsa get user@domain.com
275
+ did-cli ip set alice@example.com 192.168.1.100
276
+ did-cli tag get alice@example.com email
277
+
264
278
  # RSA key management
265
279
  did-cli rsa generate --output ./my-key.pem --key-length 4096
266
280
  did-cli rsa get example.olares.com
@@ -2266,7 +2280,10 @@ async function tagGetTagger(
2266
2280
  }
2267
2281
 
2268
2282
  async function main(): Promise<void> {
2269
- const { command, subCommand, domain, value, options } = parseArgs();
2283
+ const parsed = parseArgs();
2284
+ const { command, subCommand, value, options } = parsed;
2285
+ // Support Olares ID format (user@domain.com) by converting to standard domain format
2286
+ const domain = parsed.domain ? normalizeToDomain(parsed.domain) : undefined;
2270
2287
 
2271
2288
  if (options.help || !command || command === 'help') {
2272
2289
  showHelp();
package/src/index.ts CHANGED
@@ -6,6 +6,7 @@ import RootResolverABI from './abi/RootResolverABI';
6
6
  import RootResolver2ABI from './abi/RootResolver2ABI';
7
7
  import { debug } from './debug';
8
8
  import { parseContractError } from './utils/error-parser';
9
+ import { normalizeToDomain } from './utils/olares-id';
9
10
 
10
11
  import {
11
12
  DomainContext,
@@ -289,13 +290,16 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
289
290
 
290
291
  fetchDomain = (name: string) =>
291
292
  new Promise<Domain | undefined>(async (resolve, reject) => {
293
+ // Support Olares ID format (user@domain.com)
294
+ const normalizedName = normalizeToDomain(name);
295
+
292
296
  debug.group('fetchDomain');
293
297
  const hasCache = this.allDomainCache.length > 0;
294
298
  debug.info('fetchDomain--->hasCache', hasCache);
295
299
 
296
300
  if (hasCache) {
297
301
  const domain = PackageDomain.findASubtree(
298
- name,
302
+ normalizedName,
299
303
  this.allDomainCache
300
304
  );
301
305
 
@@ -303,7 +307,7 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
303
307
  resolve(domain);
304
308
  } else {
305
309
  const domain = await PackageDomain.syncByName(
306
- name,
310
+ normalizedName,
307
311
  await this.getContractDID()
308
312
  );
309
313
 
@@ -314,8 +318,11 @@ export class DIDConsole implements DIDTag.ABITypeProviderHolder {
314
318
 
315
319
  updateDomain = (name: string) =>
316
320
  new Promise<Domain>(async (resolve, reject) => {
321
+ // Support Olares ID format (user@domain.com)
322
+ const normalizedName = normalizeToDomain(name);
323
+
317
324
  const domain = await PackageDomain.syncByName(
318
- name,
325
+ normalizedName,
319
326
  await this.getContractDID()
320
327
  );
321
328
 
@@ -585,4 +592,7 @@ export { debug } from './debug';
585
592
  // Export Tag utilities outside namespace
586
593
  export { TagTypeBuilder, TagAbiCodec };
587
594
 
595
+ // Export Olares ID utilities
596
+ export { normalizeToDomain, normalizeToOlaresId } from './utils/olares-id';
597
+
588
598
  export default OlaresID;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Olares ID Utilities
3
+ *
4
+ * Olares ID is a new format that looks like email addresses: user@domain.com
5
+ * It's essentially a domain name where the first dot (.) is replaced with an at sign (@)
6
+ *
7
+ * Examples:
8
+ * - alice.example.com → alice@example.com (Olares ID)
9
+ * - bob.sub.example.com → bob@sub.example.com (Olares ID)
10
+ */
11
+
12
+ /**
13
+ * Convert Olares ID format to standard domain format
14
+ * Replaces the first @ with a dot (.)
15
+ *
16
+ * @param input The input string (can be either Olares ID or domain format)
17
+ * @returns The normalized domain format
18
+ *
19
+ * @example
20
+ * normalizeToDomain('alice@example.com') // returns 'alice.example.com'
21
+ * normalizeToDomain('alice.example.com') // returns 'alice.example.com' (no change)
22
+ * normalizeToDomain('bob@sub.example.com') // returns 'bob.sub.example.com'
23
+ */
24
+ export function normalizeToDomain(input: string): string {
25
+ if (!input) {
26
+ return input;
27
+ }
28
+ // Replace the first @ with a dot
29
+ return input.replace('@', '.');
30
+ }
31
+
32
+ /**
33
+ * Convert standard domain format to Olares ID format
34
+ * Replaces the first dot (.) with an at sign (@)
35
+ *
36
+ * @param domain The domain name
37
+ * @returns The Olares ID format
38
+ *
39
+ * @example
40
+ * normalizeToOlaresId('alice.example.com') // returns 'alice@example.com'
41
+ * normalizeToOlaresId('bob.sub.example.com') // returns 'bob@sub.example.com'
42
+ */
43
+ export function normalizeToOlaresId(domain: string): string {
44
+ if (!domain) {
45
+ return domain;
46
+ }
47
+ // Replace the first dot with @
48
+ return domain.replace('.', '@');
49
+ }