@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/TAG.md ADDED
@@ -0,0 +1,589 @@
1
+ # Tag System Documentation
2
+
3
+ The Tag system is a powerful key-value storage mechanism for Olares domains. Each domain can have multiple tags with defined types, allowing structured metadata storage on the blockchain.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Core Concepts](#core-concepts)
9
+ - [Supported Tag Types](#supported-tag-types)
10
+ - [SDK Usage](#sdk-usage)
11
+ - [CLI Usage](#cli-usage)
12
+ - [Permission Management](#permission-management)
13
+ - [Best Practices](#best-practices)
14
+ - [Examples](#examples)
15
+
16
+ ---
17
+
18
+ ## Overview
19
+
20
+ Tags are key-value pairs associated with a domain. Each tag has:
21
+
22
+ - **Name**: A unique identifier (string)
23
+ - **Type**: Defined using ABI types (e.g., `string`, `uint8`, `address[]`)
24
+ - **Value**: The actual data, encoded according to the type
25
+ - **Tagger**: An authorized address that can set/modify the tag value
26
+
27
+ ---
28
+
29
+ ## Core Concepts
30
+
31
+ ### 1. Tag Definition
32
+
33
+ Before you can use a tag, you must **define** its type:
34
+
35
+ ```typescript
36
+ import { TagTypeBuilder } from '@beclab/olaresid';
37
+
38
+ // Define a simple string tag
39
+ const emailType = TagTypeBuilder.string();
40
+ await tagCtx.defineTag('email', emailType);
41
+
42
+ // Define a uint8 tag
43
+ const ageType = TagTypeBuilder.uint(8);
44
+ await tagCtx.defineTag('age', ageType);
45
+
46
+ // Define an array tag
47
+ const linksType = TagTypeBuilder.array(TagTypeBuilder.string());
48
+ await tagCtx.defineTag('socialLinks', linksType);
49
+ ```
50
+
51
+ ### 2. Tagger Authorization
52
+
53
+ Each tag has a **tagger** - an Ethereum address authorized to set its value:
54
+
55
+ ```typescript
56
+ // Set yourself as the tagger
57
+ const signerAddress = await signer.getAddress();
58
+ await domainCtx.setTagger('email', signerAddress);
59
+ ```
60
+
61
+ **Important:** You must set a tagger before you can set a tag's value. Only the tagger can modify the tag.
62
+
63
+ ### 3. Tag Value Operations
64
+
65
+ Once defined and authorized, you can:
66
+
67
+ - **Set** a tag value
68
+ - **Get** a tag value (anyone can read)
69
+ - **Remove** a tag value (keeps the definition)
70
+
71
+ ```typescript
72
+ // Set value
73
+ await tagCtx.setTag('example.com', 'email', 'user@example.com');
74
+
75
+ // Get value
76
+ const email = await tagCtx.getTag('example.com', 'email');
77
+
78
+ // Remove value (definition remains)
79
+ await tagCtx.removeTag('example.com', 'email');
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Supported Tag Types
85
+
86
+ ### Simple Types
87
+
88
+ | Type | Description | Example |
89
+ | ------------------- | ----------------- | ----------------- |
90
+ | `string` | UTF-8 text | `"Hello World"` |
91
+ | `uint8` - `uint256` | Unsigned integers | `42`, `255` |
92
+ | `int8` - `int256` | Signed integers | `-10`, `100` |
93
+ | `bool` | Boolean | `true`, `false` |
94
+ | `address` | Ethereum address | `"0x1234..."` |
95
+ | `bytes` | Dynamic bytes | `"0xabcd..."` |
96
+ | `bytes32` | Fixed 32 bytes | `"0x1234...abcd"` |
97
+
98
+ ### Array Types
99
+
100
+ Any simple type can be made into a dynamic array:
101
+
102
+ ```typescript
103
+ // String array
104
+ TagTypeBuilder.array(TagTypeBuilder.string());
105
+
106
+ // Address array
107
+ TagTypeBuilder.array(TagTypeBuilder.address());
108
+
109
+ // Uint8 array
110
+ TagTypeBuilder.array(TagTypeBuilder.uint(8));
111
+ ```
112
+
113
+ ### Complex Tuple Types
114
+
115
+ For structured data, use tuples:
116
+
117
+ ```typescript
118
+ const userInfoType = TagTypeBuilder.tuple([
119
+ ['name', TagTypeBuilder.string()],
120
+ ['age', TagTypeBuilder.uint(8)],
121
+ ['wallets', TagTypeBuilder.array(TagTypeBuilder.address())],
122
+ ['verified', TagTypeBuilder.bool()]
123
+ ]);
124
+
125
+ await tagCtx.defineTag('userInfo', userInfoType);
126
+
127
+ // Set tuple value (automatic conversion!)
128
+ await tagCtx.setTag('example.com', 'userInfo', {
129
+ name: 'Alice',
130
+ age: 30,
131
+ wallets: ['0x1111...', '0x2222...'],
132
+ verified: true
133
+ });
134
+ ```
135
+
136
+ #### Nested Tuples
137
+
138
+ ```typescript
139
+ // Define nested tuple
140
+ const profileType = TagTypeBuilder.tuple({
141
+ name: TagTypeBuilder.string(),
142
+ details: TagTypeBuilder.tuple({
143
+ age: TagTypeBuilder.uint8(),
144
+ verified: TagTypeBuilder.bool()
145
+ }),
146
+ contact: TagTypeBuilder.tuple({
147
+ email: TagTypeBuilder.string(),
148
+ phone: TagTypeBuilder.string()
149
+ })
150
+ });
151
+
152
+ await tagCtx.defineTag('profile', profileType);
153
+
154
+ // Set nested tuple (automatic conversion!)
155
+ await tagCtx.setTag('example.com', 'profile', {
156
+ name: 'Alice',
157
+ details: {
158
+ age: 30,
159
+ verified: true
160
+ },
161
+ contact: {
162
+ email: 'alice@example.com',
163
+ phone: '+1-555-0123'
164
+ }
165
+ });
166
+ ```
167
+
168
+ ---
169
+
170
+ ## SDK Usage
171
+
172
+ ### Installation
173
+
174
+ ```bash
175
+ npm install @beclab/olaresid
176
+ ```
177
+
178
+ ### Basic Setup
179
+
180
+ ```typescript
181
+ import OlaresID, { TagTypeBuilder } from '@beclab/olaresid';
182
+
183
+ // Initialize
184
+ const olaresId = OlaresID.createTestnet(); // or createMainnet()
185
+ await olaresId.setSigner(privateKeyOrMnemonic);
186
+
187
+ // Get domain and tag contexts
188
+ const domain = olaresId.domain('example.com');
189
+ const tagCtx = domain.tag();
190
+ ```
191
+
192
+ ### Complete Workflow
193
+
194
+ ```typescript
195
+ // 1. Define tag type
196
+ const bioType = TagTypeBuilder.string();
197
+ await tagCtx.defineTag('bio', bioType);
198
+
199
+ // 2. Set tagger (authorize yourself)
200
+ const signerAddress = await olaresId.signer.getAddress();
201
+ await domain.setTagger('bio', signerAddress);
202
+
203
+ // 3. Set tag value
204
+ await tagCtx.setTag('example.com', 'bio', 'Web3 developer');
205
+
206
+ // 4. Read tag value (anyone can read)
207
+ const bio = await tagCtx.getTag('example.com', 'bio');
208
+ console.log(bio); // "Web3 developer"
209
+
210
+ // 5. List all tags
211
+ const allTags = await domain.getAllTags();
212
+ console.log(allTags); // [{ name: 'bio', value: 'Web3 developer' }, ...]
213
+
214
+ // 6. List defined tag types
215
+ const definedTags = await domain.getDefinedTags();
216
+ console.log(definedTags); // ['bio', 'email', 'age', ...]
217
+ ```
218
+
219
+ ### High-Level API (Simplified)
220
+
221
+ For common operations, use the high-level API:
222
+
223
+ ```typescript
224
+ const domain = olaresId.domain('example.com');
225
+
226
+ // Define and set in one step (using simplified API)
227
+ await domain.defineSimpleTag('email', 'string');
228
+ await domain.setTag('email', 'user@example.com');
229
+
230
+ // Get value
231
+ const email = await domain.getTag('email');
232
+
233
+ // Remove value
234
+ await domain.removeTag('email');
235
+ ```
236
+
237
+ ### Array Operations
238
+
239
+ ```typescript
240
+ // Define array type
241
+ const linksType = TagTypeBuilder.array(TagTypeBuilder.string());
242
+ await tagCtx.defineTag('socialLinks', linksType);
243
+ await domain.setTagger('socialLinks', signerAddress);
244
+
245
+ // Set array value
246
+ await tagCtx.setTag('example.com', 'socialLinks', [
247
+ 'https://twitter.com/user',
248
+ 'https://github.com/user'
249
+ ]);
250
+
251
+ // Get array value
252
+ const links = await tagCtx.getTag('example.com', 'socialLinks');
253
+ console.log(links); // ['https://twitter.com/user', 'https://github.com/user']
254
+ ```
255
+
256
+ ### Error Handling
257
+
258
+ ```typescript
259
+ try {
260
+ await tagCtx.defineTag('email', emailType);
261
+ } catch (error) {
262
+ if (error.message.includes('already been defined')) {
263
+ console.log('Tag already exists, skipping definition');
264
+ } else {
265
+ throw error;
266
+ }
267
+ }
268
+ ```
269
+
270
+ ---
271
+
272
+ ## CLI Usage
273
+
274
+ The CLI provides simple commands for basic tag operations. For advanced usage (complex types, tuple operations), use the SDK.
275
+
276
+ ### Define Tag Type
277
+
278
+ ```bash
279
+ # Simple types
280
+ npx ts-node src/cli.ts tag define example.com email string
281
+ npx ts-node src/cli.ts tag define example.com age uint8
282
+ npx ts-node src/cli.ts tag define example.com verified bool
283
+
284
+ # Array types (must be quoted!)
285
+ npx ts-node src/cli.ts tag define example.com wallets "address[]"
286
+ npx ts-node src/cli.ts tag define example.com links "string[]"
287
+ ```
288
+
289
+ ### Set Tagger
290
+
291
+ ```bash
292
+ # Set tagger address
293
+ npx ts-node src/cli.ts tag set-tagger example.com email 0xYOUR_ADDRESS
294
+ ```
295
+
296
+ ### Set Tag Value
297
+
298
+ ```bash
299
+ # String value
300
+ npx ts-node src/cli.ts tag set example.com email "user@example.com"
301
+
302
+ # Number value
303
+ npx ts-node src/cli.ts tag set example.com age 30
304
+
305
+ # Boolean value
306
+ npx ts-node src/cli.ts tag set example.com verified true
307
+
308
+ # Array value (use JSON, must be quoted!)
309
+ npx ts-node src/cli.ts tag set example.com links '["https://twitter.com","https://github.com"]'
310
+ ```
311
+
312
+ ### Get Tag Value
313
+
314
+ ```bash
315
+ # Read-only, no authentication required
316
+ npx ts-node src/cli.ts tag get example.com email
317
+ ```
318
+
319
+ ### List Tags
320
+
321
+ ```bash
322
+ # List all tags with values
323
+ npx ts-node src/cli.ts tag list example.com
324
+
325
+ # List all defined tag types
326
+ npx ts-node src/cli.ts tag list-defined example.com
327
+ ```
328
+
329
+ ### Remove Tag Value
330
+
331
+ ```bash
332
+ # Remove value (definition remains)
333
+ npx ts-node src/cli.ts tag remove example.com email
334
+ ```
335
+
336
+ ### Environment Variables
337
+
338
+ Write operations require authentication:
339
+
340
+ ```bash
341
+ export PRIVATE_KEY_OR_MNEMONIC="0xYOUR_PRIVATE_KEY"
342
+ # OR
343
+ export PRIVATE_KEY_OR_MNEMONIC="your twelve word mnemonic phrase here"
344
+ ```
345
+
346
+ ---
347
+
348
+ ## Permission Management
349
+
350
+ ### Tagger Role
351
+
352
+ The **tagger** is the only address authorized to set/modify a tag's value. The domain owner can set or change the tagger at any time.
353
+
354
+ ```typescript
355
+ // Set tagger (only domain owner can do this)
356
+ await domain.setTagger('email', '0xTAGGER_ADDRESS');
357
+
358
+ // Get current tagger
359
+ const tagger = await tagCtx.getTagger('email');
360
+ console.log(tagger); // "0xTAGGER_ADDRESS"
361
+ ```
362
+
363
+ ### Authorization Flow
364
+
365
+ 1. **Domain Owner** defines tag type → calls `defineTag()`
366
+ 2. **Domain Owner** sets tagger → calls `setTagger(tagName, taggerAddress)`
367
+ 3. **Tagger** can now set/modify values → calls `setTag()`, `removeTag()`
368
+ 4. **Anyone** can read values → calls `getTag()`
369
+
370
+ ### Common Patterns
371
+
372
+ **Pattern 1: Owner manages their own tags**
373
+
374
+ ```typescript
375
+ const ownerAddress = await signer.getAddress();
376
+ await domain.setTagger('bio', ownerAddress);
377
+ await tagCtx.setTag('example.com', 'bio', 'My biography');
378
+ ```
379
+
380
+ **Pattern 2: Delegate to a contract**
381
+
382
+ Delegating tagger permissions to a smart contract allows for more complex logic and automation:
383
+
384
+ ```typescript
385
+ const CONTRACT_ADDRESS = '0x1234...'; // Your smart contract address
386
+ await domain.setTagger('reputation', CONTRACT_ADDRESS);
387
+ // Now the contract can update the reputation tag with custom logic
388
+ ```
389
+
390
+ **Benefits of using contracts as taggers:**
391
+
392
+ - Implement complex authorization logic (multi-sig, time-locks, etc.)
393
+ - Enable automated tag updates based on on-chain events
394
+ - Create composable tag management systems
395
+ - Enforce business rules programmatically
396
+
397
+ **Reference Implementations:**
398
+
399
+ For real-world examples, see the [did-contracts/src/taggers](../../did-contracts/src/taggers/) directory, which contains production tagger contracts currently in use.
400
+
401
+ ---
402
+
403
+ ## Best Practices
404
+
405
+ ### 1. Handle RedefinedTag Errors
406
+
407
+ Tags can only be defined once. Always check if a tag exists:
408
+
409
+ ```typescript
410
+ try {
411
+ await tagCtx.defineTag('email', emailType);
412
+ } catch (error) {
413
+ if (error.message.includes('already been defined')) {
414
+ console.log('Tag already exists, skipping');
415
+ } else {
416
+ throw error;
417
+ }
418
+ }
419
+ ```
420
+
421
+ ### 2. Always Set Tagger After Defining
422
+
423
+ ```typescript
424
+ // ✅ Good
425
+ await tagCtx.defineTag('email', emailType);
426
+ await domain.setTagger('email', signerAddress);
427
+ await tagCtx.setTag('example.com', 'email', 'user@example.com');
428
+
429
+ // ❌ Bad - will fail with "Unauthorized"
430
+ await tagCtx.defineTag('email', emailType);
431
+ await tagCtx.setTag('example.com', 'email', 'user@example.com'); // No tagger set!
432
+ ```
433
+
434
+ ### 3. Wait for Blockchain Indexing
435
+
436
+ After write operations, allow time for nodes to index:
437
+
438
+ ```typescript
439
+ await tagCtx.setTag('example.com', 'email', 'user@example.com');
440
+ await new Promise(resolve => setTimeout(resolve, 3000)); // Wait 3 seconds
441
+ const email = await tagCtx.getTag('example.com', 'email');
442
+ ```
443
+
444
+ ### 4. Validate Input Types
445
+
446
+ The blockchain will reject invalid types:
447
+
448
+ ```typescript
449
+ // ❌ Wrong type
450
+ await tagCtx.setTag('example.com', 'age', 'thirty'); // Expected number
451
+
452
+ // ✅ Correct type
453
+ await tagCtx.setTag('example.com', 'age', 30);
454
+ ```
455
+
456
+ ---
457
+
458
+ ## Examples
459
+
460
+ ### Example 1: User Profile
461
+
462
+ ```typescript
463
+ // Define tags
464
+ await tagCtx.defineTag('bio', TagTypeBuilder.string());
465
+ await tagCtx.defineTag('followers', TagTypeBuilder.uint(256));
466
+ await tagCtx.defineTag('verified', TagTypeBuilder.bool());
467
+ await tagCtx.defineTag(
468
+ 'socialLinks',
469
+ TagTypeBuilder.array(TagTypeBuilder.string())
470
+ );
471
+
472
+ // Set tagger
473
+ const signer = await olaresId.signer.getAddress();
474
+ await domain.setTagger('bio', signer);
475
+ await domain.setTagger('followers', signer);
476
+ await domain.setTagger('verified', signer);
477
+ await domain.setTagger('socialLinks', signer);
478
+
479
+ // Set values
480
+ await tagCtx.setTag('alice.com', 'bio', 'Web3 enthusiast');
481
+ await tagCtx.setTag('alice.com', 'followers', 1350);
482
+ await tagCtx.setTag('alice.com', 'verified', true);
483
+ await tagCtx.setTag('alice.com', 'socialLinks', [
484
+ 'https://twitter.com/alice',
485
+ 'https://github.com/alice'
486
+ ]);
487
+
488
+ // Read all tags
489
+ const tags = await domain.getAllTags();
490
+ console.log(tags);
491
+ ```
492
+
493
+ ### Example 2: NFT Metadata
494
+
495
+ ```typescript
496
+ // Define NFT metadata tags
497
+ const nftType = TagTypeBuilder.tuple([
498
+ ['tokenId', TagTypeBuilder.uint(256)],
499
+ ['name', TagTypeBuilder.string()],
500
+ ['description', TagTypeBuilder.string()],
501
+ ['image', TagTypeBuilder.string()],
502
+ ['attributes', TagTypeBuilder.array(TagTypeBuilder.string())]
503
+ ]);
504
+
505
+ await tagCtx.defineTag('nftMetadata', nftType);
506
+ await domain.setTagger('nftMetadata', signerAddress);
507
+
508
+ // Set NFT metadata
509
+ await tagCtx.setTag('nft.com', 'nftMetadata', {
510
+ tokenId: 1,
511
+ name: 'Cool NFT #1',
512
+ description: 'A very cool NFT',
513
+ image: 'ipfs://QmXxx...',
514
+ attributes: ['rare', 'animated', 'special']
515
+ });
516
+ ```
517
+
518
+ ### Example 3: Service Configuration
519
+
520
+ ```typescript
521
+ // Define service config tags
522
+ await tagCtx.defineTag('apiEndpoint', TagTypeBuilder.string());
523
+ await tagCtx.defineTag(
524
+ 'rpcNodes',
525
+ TagTypeBuilder.array(TagTypeBuilder.string())
526
+ );
527
+ await tagCtx.defineTag('maxRetries', TagTypeBuilder.uint(8));
528
+ await tagCtx.defineTag('enabled', TagTypeBuilder.bool());
529
+
530
+ // Delegate tagger to service admin
531
+ const SERVICE_ADMIN = '0x1234...';
532
+ await domain.setTagger('apiEndpoint', SERVICE_ADMIN);
533
+ await domain.setTagger('rpcNodes', SERVICE_ADMIN);
534
+ await domain.setTagger('maxRetries', SERVICE_ADMIN);
535
+ await domain.setTagger('enabled', SERVICE_ADMIN);
536
+
537
+ // Service admin sets config
538
+ await tagCtx.setTag('service.com', 'apiEndpoint', 'https://api.example.com');
539
+ await tagCtx.setTag('service.com', 'rpcNodes', [
540
+ 'https://rpc1.example.com',
541
+ 'https://rpc2.example.com'
542
+ ]);
543
+ await tagCtx.setTag('service.com', 'maxRetries', 3);
544
+ await tagCtx.setTag('service.com', 'enabled', true);
545
+ ```
546
+
547
+ ---
548
+
549
+ ## See Also
550
+
551
+ - **[SDK Examples](./examples/)** - Complete code examples
552
+ - **[CLI Documentation](./CLI.md#tag-management-commands)** - Full CLI reference
553
+ - **[Main README](./README.md)** - General documentation
554
+
555
+ ---
556
+
557
+ ## Troubleshooting
558
+
559
+ ### Error: "Tag already exists"
560
+
561
+ **Solution:** Tag definitions are immutable. You cannot redefine a tag. Check if it exists first.
562
+
563
+ ### Error: "Unauthorized"
564
+
565
+ **Solution:** You haven't set a tagger, or you're not the tagger. Call `setTagger()` first.
566
+
567
+ ### Error: "Invalid tag operation"
568
+
569
+ **Solution:** You're trying to remove a tag that has no value, or performing an unsupported operation.
570
+
571
+ ### Error: "Tuple field count mismatch"
572
+
573
+ **Solution:** Ensure object keys match the tuple field definition order and count. Objects are automatically converted to arrays based on the ABI type structure.
574
+
575
+ ### Shell Error: "no matches found: address[]"
576
+
577
+ **Solution:** Quote array types in the shell: `"address[]"` instead of `address[]`.
578
+
579
+ ---
580
+
581
+ ## Contract Reference
582
+
583
+ Tag operations interact with the following contracts:
584
+
585
+ - **TerminusDID**: Tag definition, tagger management
586
+ - **TagRegistry**: Core tag storage and operations
587
+ - **RootResolver**: Legacy tag operations (compatibility)
588
+
589
+ For contract details, see the [did-contracts](../../did-contracts/) repository.
@@ -0,0 +1,54 @@
1
+ declare const _default: {
2
+ abi: ({
3
+ inputs: {
4
+ internalType: string;
5
+ name: string;
6
+ type: string;
7
+ }[];
8
+ name: string;
9
+ type: string;
10
+ outputs?: undefined;
11
+ stateMutability?: undefined;
12
+ } | {
13
+ inputs: ({
14
+ components: {
15
+ internalType: string;
16
+ name: string;
17
+ type: string;
18
+ }[];
19
+ internalType: string;
20
+ name: string;
21
+ type: string;
22
+ } | {
23
+ internalType: string;
24
+ name: string;
25
+ type: string;
26
+ components?: undefined;
27
+ })[];
28
+ name: string;
29
+ outputs: never[];
30
+ stateMutability: string;
31
+ type: string;
32
+ } | {
33
+ inputs: {
34
+ internalType: string;
35
+ name: string;
36
+ type: string;
37
+ }[];
38
+ name: string;
39
+ outputs: {
40
+ components: {
41
+ internalType: string;
42
+ name: string;
43
+ type: string;
44
+ }[];
45
+ internalType: string;
46
+ name: string;
47
+ type: string;
48
+ }[];
49
+ stateMutability: string;
50
+ type: string;
51
+ })[];
52
+ };
53
+ export default _default;
54
+ //# sourceMappingURL=RootResolver2ABI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootResolver2ABI.d.ts","sourceRoot":"","sources":["../../src/abi/RootResolver2ABI.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA4OE"}