@beclab/olaresid 0.1.1 → 0.1.2
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.
- package/CLI.md +1300 -0
- package/README.md +37 -31
- package/TAG.md +589 -0
- package/dist/abi/RootResolver2ABI.d.ts +54 -0
- package/dist/abi/RootResolver2ABI.d.ts.map +1 -0
- package/dist/abi/RootResolver2ABI.js +240 -0
- package/dist/abi/RootResolver2ABI.js.map +1 -0
- package/dist/business/index.d.ts +302 -0
- package/dist/business/index.d.ts.map +1 -0
- package/dist/business/index.js +1209 -0
- package/dist/business/index.js.map +1 -0
- package/dist/business/tag-context.d.ts +219 -0
- package/dist/business/tag-context.d.ts.map +1 -0
- package/dist/business/tag-context.js +537 -0
- package/dist/business/tag-context.js.map +1 -0
- package/dist/cli.js +2085 -39
- package/dist/cli.js.map +1 -1
- package/dist/debug.d.ts.map +1 -1
- package/dist/debug.js +14 -2
- package/dist/debug.js.map +1 -1
- package/dist/index.d.ts +50 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +229 -9
- package/dist/index.js.map +1 -1
- package/dist/utils/crypto-utils.d.ts +130 -0
- package/dist/utils/crypto-utils.d.ts.map +1 -0
- package/dist/utils/crypto-utils.js +402 -0
- package/dist/utils/crypto-utils.js.map +1 -0
- package/dist/utils/error-parser.d.ts +35 -0
- package/dist/utils/error-parser.d.ts.map +1 -0
- package/dist/utils/error-parser.js +202 -0
- package/dist/utils/error-parser.js.map +1 -0
- package/dist/utils/tag-abi-codec.d.ts +69 -0
- package/dist/utils/tag-abi-codec.d.ts.map +1 -0
- package/dist/utils/tag-abi-codec.js +144 -0
- package/dist/utils/tag-abi-codec.js.map +1 -0
- package/dist/utils/tag-type-builder.d.ts +158 -0
- package/dist/utils/tag-type-builder.d.ts.map +1 -0
- package/dist/utils/tag-type-builder.js +410 -0
- package/dist/utils/tag-type-builder.js.map +1 -0
- package/examples/crypto-utilities.ts +140 -0
- package/examples/domain-context.ts +80 -0
- package/examples/generate-mnemonic.ts +149 -0
- package/examples/index.ts +1 -1
- package/examples/ip.ts +171 -0
- package/examples/legacy.ts +10 -10
- package/examples/list-wallets.ts +81 -0
- package/examples/quasar-demo/.eslintrc.js +23 -0
- package/examples/quasar-demo/.quasar/app.js +43 -0
- package/examples/quasar-demo/.quasar/client-entry.js +38 -0
- package/examples/quasar-demo/.quasar/client-prefetch.js +130 -0
- package/examples/quasar-demo/.quasar/quasar-user-options.js +16 -0
- package/examples/quasar-demo/README.md +49 -0
- package/examples/quasar-demo/index.html +11 -0
- package/examples/quasar-demo/package-lock.json +6407 -0
- package/examples/quasar-demo/package.json +36 -0
- package/examples/quasar-demo/quasar.config.js +73 -0
- package/examples/quasar-demo/src/App.vue +13 -0
- package/examples/quasar-demo/src/css/app.scss +1 -0
- package/examples/quasar-demo/src/layouts/MainLayout.vue +21 -0
- package/examples/quasar-demo/src/pages/IndexPage.vue +905 -0
- package/examples/quasar-demo/src/router/index.ts +25 -0
- package/examples/quasar-demo/src/router/routes.ts +11 -0
- package/examples/quasar-demo/tsconfig.json +28 -0
- package/examples/register-subdomain.ts +152 -0
- package/examples/rsa-keypair.ts +148 -0
- package/examples/tag-builder.ts +235 -0
- package/examples/tag-management.ts +534 -0
- package/examples/tag-nested-tuple.ts +190 -0
- package/examples/tag-simple.ts +149 -0
- package/examples/tag-tagger.ts +217 -0
- package/examples/test-nested-tuple-conversion.ts +143 -0
- package/examples/test-type-bytes-parser.ts +70 -0
- package/examples/transfer-domain.ts +197 -0
- package/examples/wallet-management.ts +196 -0
- package/package.json +24 -15
- package/src/abi/RootResolver2ABI.ts +237 -0
- package/src/business/index.ts +1490 -0
- package/src/business/tag-context.ts +713 -0
- package/src/cli.ts +2755 -39
- package/src/debug.ts +17 -2
- package/src/index.ts +300 -14
- package/src/utils/crypto-utils.ts +459 -0
- package/src/utils/error-parser.ts +225 -0
- package/src/utils/tag-abi-codec.ts +158 -0
- package/src/utils/tag-type-builder.ts +469 -0
- package/tsconfig.json +1 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import OlaresID from '../src/index';
|
|
2
|
+
import { TagTypeBuilder } from '../src/utils/tag-type-builder';
|
|
3
|
+
|
|
4
|
+
// Helper function to wait for blockchain indexing
|
|
5
|
+
async function waitForIndexing(seconds: number = 3) {
|
|
6
|
+
console.log(`⏳ Waiting ${seconds} seconds for blockchain indexing...`);
|
|
7
|
+
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Example: Nested Tuple Tag Operations
|
|
12
|
+
* Demonstrates automatic object-to-array conversion for nested tuples
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
async function main() {
|
|
16
|
+
const domainName = process.argv[2];
|
|
17
|
+
if (!domainName) {
|
|
18
|
+
console.error(
|
|
19
|
+
'Usage: npx ts-node examples/tag-nested-tuple.ts <domain-name>'
|
|
20
|
+
);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const privateKeyOrMnemonic = process.env.PRIVATE_KEY_OR_MNEMONIC;
|
|
25
|
+
if (!privateKeyOrMnemonic) {
|
|
26
|
+
console.error(
|
|
27
|
+
'Error: PRIVATE_KEY_OR_MNEMONIC environment variable is required'
|
|
28
|
+
);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log('🚀 Nested Tuple Tag Example\n');
|
|
33
|
+
console.log(`Domain: ${domainName}\n`);
|
|
34
|
+
|
|
35
|
+
// Initialize
|
|
36
|
+
const olaresId = OlaresID.createTestnet();
|
|
37
|
+
await olaresId.setSigner(privateKeyOrMnemonic);
|
|
38
|
+
const domain = olaresId.domain(domainName);
|
|
39
|
+
const tagCtx = domain.tag();
|
|
40
|
+
const signerAddress = await olaresId.signer!.getAddress();
|
|
41
|
+
|
|
42
|
+
// ========================================
|
|
43
|
+
// Part 1: Define Nested Tuple Type
|
|
44
|
+
// ========================================
|
|
45
|
+
console.log('='.repeat(60));
|
|
46
|
+
console.log('Part 1: Define Nested Tuple Type');
|
|
47
|
+
console.log('='.repeat(60));
|
|
48
|
+
|
|
49
|
+
const profileType = TagTypeBuilder.tuple({
|
|
50
|
+
name: TagTypeBuilder.string(),
|
|
51
|
+
details: TagTypeBuilder.tuple({
|
|
52
|
+
age: TagTypeBuilder.uint8(),
|
|
53
|
+
verified: TagTypeBuilder.bool()
|
|
54
|
+
}),
|
|
55
|
+
contact: TagTypeBuilder.tuple({
|
|
56
|
+
email: TagTypeBuilder.string(),
|
|
57
|
+
phone: TagTypeBuilder.string()
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
await tagCtx.defineTag('profile', profileType);
|
|
63
|
+
console.log('✅ Defined "profile" nested tuple tag\n');
|
|
64
|
+
} catch (error: any) {
|
|
65
|
+
if (error.message.includes('already been defined')) {
|
|
66
|
+
console.log('⚠️ "profile" tag already defined, skipping...\n');
|
|
67
|
+
} else {
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Set tagger
|
|
73
|
+
await domain.setTagger('profile', signerAddress);
|
|
74
|
+
console.log(`✅ Set tagger for "profile" to ${signerAddress}\n`);
|
|
75
|
+
|
|
76
|
+
// ========================================
|
|
77
|
+
// Part 2: Set Nested Tuple using Object
|
|
78
|
+
// ========================================
|
|
79
|
+
console.log('='.repeat(60));
|
|
80
|
+
console.log('Part 2: Set Nested Tuple (Object Notation)');
|
|
81
|
+
console.log('='.repeat(60));
|
|
82
|
+
|
|
83
|
+
const profileValue = {
|
|
84
|
+
name: 'Alice Johnson',
|
|
85
|
+
details: {
|
|
86
|
+
age: 30,
|
|
87
|
+
verified: true
|
|
88
|
+
},
|
|
89
|
+
contact: {
|
|
90
|
+
email: 'alice@example.com',
|
|
91
|
+
phone: '+1-555-0123'
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
console.log('📝 Setting nested tuple with object notation:');
|
|
96
|
+
console.log(JSON.stringify(profileValue, null, 2));
|
|
97
|
+
|
|
98
|
+
await tagCtx.setTag(domainName, 'profile', profileValue);
|
|
99
|
+
console.log('\n✅ Nested tuple set successfully!\n');
|
|
100
|
+
await waitForIndexing(3);
|
|
101
|
+
|
|
102
|
+
// ========================================
|
|
103
|
+
// Part 3: Get and Display Nested Tuple
|
|
104
|
+
// ========================================
|
|
105
|
+
console.log('='.repeat(60));
|
|
106
|
+
console.log('Part 3: Read Nested Tuple');
|
|
107
|
+
console.log('='.repeat(60));
|
|
108
|
+
|
|
109
|
+
const profile = await tagCtx.getTag(domainName, 'profile');
|
|
110
|
+
console.log('📖 Retrieved profile (raw array):');
|
|
111
|
+
console.log(
|
|
112
|
+
JSON.stringify(profile, (_, v) =>
|
|
113
|
+
typeof v === 'bigint' ? v.toString() : v
|
|
114
|
+
)
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
console.log('\n📖 Retrieved profile (parsed):');
|
|
118
|
+
console.log(` name: ${profile[0]}`);
|
|
119
|
+
console.log(` details.age: ${profile[1][0]}`);
|
|
120
|
+
console.log(` details.verified: ${profile[1][1]}`);
|
|
121
|
+
console.log(` contact.email: ${profile[2][0]}`);
|
|
122
|
+
console.log(` contact.phone: ${profile[2][1]}\n`);
|
|
123
|
+
|
|
124
|
+
// ========================================
|
|
125
|
+
// Part 4: Update Nested Field
|
|
126
|
+
// ========================================
|
|
127
|
+
console.log('='.repeat(60));
|
|
128
|
+
console.log('Part 4: Update Nested Field');
|
|
129
|
+
console.log('='.repeat(60));
|
|
130
|
+
|
|
131
|
+
console.log('🔄 Updating details.age from 30 to 31...\n');
|
|
132
|
+
|
|
133
|
+
const updatedProfile = {
|
|
134
|
+
name: profile[0],
|
|
135
|
+
details: {
|
|
136
|
+
age: 31, // Updated
|
|
137
|
+
verified: profile[1][1]
|
|
138
|
+
},
|
|
139
|
+
contact: {
|
|
140
|
+
email: profile[2][0],
|
|
141
|
+
phone: profile[2][1]
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
await tagCtx.setTag(domainName, 'profile', updatedProfile);
|
|
146
|
+
console.log('✅ Updated nested field\n');
|
|
147
|
+
await waitForIndexing(3);
|
|
148
|
+
|
|
149
|
+
// Verify update
|
|
150
|
+
const updatedProfileRead = await tagCtx.getTag(domainName, 'profile');
|
|
151
|
+
console.log('📖 Verified update:');
|
|
152
|
+
console.log(
|
|
153
|
+
` details.age: ${updatedProfileRead[1][0]} (was 30, now 31)\n`
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// ========================================
|
|
157
|
+
// Part 5: Array Notation (Still Supported)
|
|
158
|
+
// ========================================
|
|
159
|
+
console.log('='.repeat(60));
|
|
160
|
+
console.log('Part 5: Array Notation (Alternative)');
|
|
161
|
+
console.log('='.repeat(60));
|
|
162
|
+
|
|
163
|
+
console.log('📝 Setting with array notation (for comparison):\n');
|
|
164
|
+
|
|
165
|
+
await tagCtx.setTag(domainName, 'profile', [
|
|
166
|
+
'Bob Smith', // name
|
|
167
|
+
[25, false], // details: {age: 25, verified: false}
|
|
168
|
+
['bob@example.com', '+1-555-9999'] // contact: {email, phone}
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
console.log('✅ Array notation also works!\n');
|
|
172
|
+
await waitForIndexing(3);
|
|
173
|
+
|
|
174
|
+
const profileArray = await tagCtx.getTag(domainName, 'profile');
|
|
175
|
+
console.log('📖 Retrieved (set via array notation):');
|
|
176
|
+
console.log(` name: ${profileArray[0]}`);
|
|
177
|
+
console.log(` details.age: ${profileArray[1][0]}`);
|
|
178
|
+
console.log(` details.verified: ${profileArray[1][1]}\n`);
|
|
179
|
+
|
|
180
|
+
console.log('='.repeat(60));
|
|
181
|
+
console.log('✅ All nested tuple operations completed!');
|
|
182
|
+
console.log('='.repeat(60));
|
|
183
|
+
console.log('\n💡 Key Takeaways:');
|
|
184
|
+
console.log(' • Objects are automatically converted to arrays');
|
|
185
|
+
console.log(' • Nested tuples work seamlessly');
|
|
186
|
+
console.log(' • No need to provide field names manually');
|
|
187
|
+
console.log(' • Array notation is still supported for flexibility\n');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Tag Example
|
|
3
|
+
*
|
|
4
|
+
* This example shows the simplest way to use Tags:
|
|
5
|
+
* - Define a few simple tags
|
|
6
|
+
* - Set and get values
|
|
7
|
+
* - No complex types or arrays
|
|
8
|
+
*
|
|
9
|
+
* Prerequisites:
|
|
10
|
+
* - Set PRIVATE_KEY_OR_MNEMONIC environment variable
|
|
11
|
+
* - You must own the domain you're operating on
|
|
12
|
+
*
|
|
13
|
+
* Run:
|
|
14
|
+
* export PRIVATE_KEY_OR_MNEMONIC="your private key or mnemonic"
|
|
15
|
+
* npx ts-node examples/tag-simple.ts <domain-name>
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import OlaresID from '../src/index';
|
|
19
|
+
|
|
20
|
+
async function main() {
|
|
21
|
+
// Initialize
|
|
22
|
+
const olaresId = OlaresID.createTestnet();
|
|
23
|
+
const privateKeyOrMnemonic = process.env.PRIVATE_KEY_OR_MNEMONIC;
|
|
24
|
+
|
|
25
|
+
if (!privateKeyOrMnemonic) {
|
|
26
|
+
console.error(
|
|
27
|
+
'❌ Error: PRIVATE_KEY_OR_MNEMONIC environment variable not set'
|
|
28
|
+
);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
await olaresId.setSigner(privateKeyOrMnemonic);
|
|
33
|
+
|
|
34
|
+
const domainName = process.argv[2];
|
|
35
|
+
if (!domainName) {
|
|
36
|
+
console.error('❌ Error: Please provide a domain name');
|
|
37
|
+
console.log('Usage: npx ts-node examples/tag-simple.ts <domain-name>');
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const domain = olaresId.domain(domainName);
|
|
42
|
+
const signerAddress = await olaresId.getSigner().getAddress();
|
|
43
|
+
console.log(`\n🏷️ Simple Tag Example for: ${domainName}`);
|
|
44
|
+
console.log(`👤 Signer: ${signerAddress}\n`);
|
|
45
|
+
|
|
46
|
+
// Step 1: Define tag types (skip if already defined)
|
|
47
|
+
console.log('1️⃣ Defining tag types...');
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
await domain.defineSimpleTag('bio', 'string');
|
|
51
|
+
console.log(' ✅ Defined "bio" (string)');
|
|
52
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
53
|
+
} catch (error: any) {
|
|
54
|
+
if (
|
|
55
|
+
error.message?.includes('RedefinedTag') ||
|
|
56
|
+
error.message?.includes('already been defined')
|
|
57
|
+
) {
|
|
58
|
+
console.log(' ⚠️ "bio" already defined, skipping...');
|
|
59
|
+
} else {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
await domain.defineSimpleTag('followers', 'uint32');
|
|
66
|
+
console.log(' ✅ Defined "followers" (uint32)');
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
68
|
+
} catch (error: any) {
|
|
69
|
+
if (
|
|
70
|
+
error.message?.includes('RedefinedTag') ||
|
|
71
|
+
error.message?.includes('already been defined')
|
|
72
|
+
) {
|
|
73
|
+
console.log(' ⚠️ "followers" already defined, skipping...');
|
|
74
|
+
} else {
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await domain.defineSimpleTag('premium', 'bool');
|
|
81
|
+
console.log(' ✅ Defined "premium" (bool)\n');
|
|
82
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
83
|
+
} catch (error: any) {
|
|
84
|
+
if (
|
|
85
|
+
error.message?.includes('RedefinedTag') ||
|
|
86
|
+
error.message?.includes('already been defined')
|
|
87
|
+
) {
|
|
88
|
+
console.log(' ⚠️ "premium" already defined, skipping...\n');
|
|
89
|
+
} else {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Step 2: Set taggers (IMPORTANT!)
|
|
95
|
+
console.log('2️⃣ Setting taggers (required before setting values)...');
|
|
96
|
+
await domain.setTagger('bio', signerAddress);
|
|
97
|
+
console.log(' ✅ Set tagger for "bio"');
|
|
98
|
+
|
|
99
|
+
await domain.setTagger('followers', signerAddress);
|
|
100
|
+
console.log(' ✅ Set tagger for "followers"');
|
|
101
|
+
|
|
102
|
+
await domain.setTagger('premium', signerAddress);
|
|
103
|
+
console.log(' ✅ Set tagger for "premium"\n');
|
|
104
|
+
|
|
105
|
+
// Wait for indexing
|
|
106
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
107
|
+
|
|
108
|
+
// Step 3: Set values
|
|
109
|
+
console.log('3️⃣ Setting tag values...');
|
|
110
|
+
await domain.setTag('bio', 'Web3 developer and blockchain enthusiast');
|
|
111
|
+
console.log(' ✅ Set "bio"');
|
|
112
|
+
|
|
113
|
+
await domain.setTag('followers', 1250);
|
|
114
|
+
console.log(' ✅ Set "followers"');
|
|
115
|
+
|
|
116
|
+
await domain.setTag('premium', true);
|
|
117
|
+
console.log(' ✅ Set "premium"\n');
|
|
118
|
+
|
|
119
|
+
// Wait for indexing
|
|
120
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
121
|
+
|
|
122
|
+
// Step 4: Get values
|
|
123
|
+
console.log('4️⃣ Reading tag values...');
|
|
124
|
+
const bio = await domain.getTag('bio');
|
|
125
|
+
const followers = await domain.getTag('followers');
|
|
126
|
+
const premium = await domain.getTag('premium');
|
|
127
|
+
|
|
128
|
+
console.log(` bio: "${bio}"`);
|
|
129
|
+
console.log(` followers: ${followers}`);
|
|
130
|
+
console.log(` premium: ${premium}\n`);
|
|
131
|
+
|
|
132
|
+
// Step 5: Update a value
|
|
133
|
+
console.log('5️⃣ Updating "followers" count...');
|
|
134
|
+
await domain.setTag('followers', 1350);
|
|
135
|
+
console.log(' ✅ Updated "followers"\n');
|
|
136
|
+
|
|
137
|
+
// Wait for indexing
|
|
138
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
139
|
+
|
|
140
|
+
const updatedFollowers = await domain.getTag('followers');
|
|
141
|
+
console.log(` New followers count: ${updatedFollowers}\n`);
|
|
142
|
+
|
|
143
|
+
console.log('✅ Simple Tag Example Completed!\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
main().catch((error) => {
|
|
147
|
+
console.error('❌ Error:', error.message);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
});
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag Tagger Management Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to set and get taggers (managers) for Tags.
|
|
5
|
+
* A tagger is an address that has permission to manage a specific Tag.
|
|
6
|
+
*
|
|
7
|
+
* Prerequisites:
|
|
8
|
+
* - Set PRIVATE_KEY_OR_MNEMONIC environment variable (domain owner)
|
|
9
|
+
* - You must own the domain you're operating on
|
|
10
|
+
*
|
|
11
|
+
* Run:
|
|
12
|
+
* export PRIVATE_KEY_OR_MNEMONIC="your private key or mnemonic"
|
|
13
|
+
* npx ts-node examples/tag-tagger.ts <domain-name>
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import OlaresID from '../src/index';
|
|
17
|
+
|
|
18
|
+
async function main() {
|
|
19
|
+
// Initialize OlaresID
|
|
20
|
+
const olaresId = OlaresID.createTestnet();
|
|
21
|
+
|
|
22
|
+
// Get private key or mnemonic from environment
|
|
23
|
+
const privateKeyOrMnemonic = process.env.PRIVATE_KEY_OR_MNEMONIC;
|
|
24
|
+
if (!privateKeyOrMnemonic) {
|
|
25
|
+
console.error(
|
|
26
|
+
'❌ Error: PRIVATE_KEY_OR_MNEMONIC environment variable not set'
|
|
27
|
+
);
|
|
28
|
+
console.log(
|
|
29
|
+
'Usage: export PRIVATE_KEY_OR_MNEMONIC="your private key or mnemonic"'
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await olaresId.setSigner(privateKeyOrMnemonic);
|
|
35
|
+
const signerAddress = await olaresId.getSigner().getAddress();
|
|
36
|
+
console.log(`✅ Signer address: ${signerAddress}\n`);
|
|
37
|
+
|
|
38
|
+
// Get domain name from command line
|
|
39
|
+
const domainName = process.argv[2];
|
|
40
|
+
if (!domainName) {
|
|
41
|
+
console.error('❌ Error: Please provide a domain name');
|
|
42
|
+
console.log('Usage: npx ts-node examples/tag-tagger.ts <domain-name>');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const domain = olaresId.domain(domainName);
|
|
47
|
+
console.log(`🏷️ Managing Taggers for domain: ${domainName}\n`);
|
|
48
|
+
|
|
49
|
+
// ========================================
|
|
50
|
+
// Part 1: Define a Tag
|
|
51
|
+
// ========================================
|
|
52
|
+
console.log('='.repeat(60));
|
|
53
|
+
console.log('Part 1: Define a Tag');
|
|
54
|
+
console.log('='.repeat(60));
|
|
55
|
+
|
|
56
|
+
const tagName = 'userStatus';
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
console.log(`📝 Defining "${tagName}" tag (type: string)...`);
|
|
60
|
+
await domain.defineSimpleTag(tagName, 'string');
|
|
61
|
+
console.log(`✅ "${tagName}" tag defined\n`);
|
|
62
|
+
|
|
63
|
+
// Wait for indexing
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
65
|
+
} catch (error: any) {
|
|
66
|
+
console.error(`❌ Error defining tag: ${error.message}\n`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ========================================
|
|
70
|
+
// Part 2: Check Initial Tagger
|
|
71
|
+
// ========================================
|
|
72
|
+
console.log('='.repeat(60));
|
|
73
|
+
console.log('Part 2: Check Initial Tagger');
|
|
74
|
+
console.log('='.repeat(60));
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const initialTagger = await domain.getTagger(tagName);
|
|
78
|
+
console.log(`📖 Current tagger: ${initialTagger}`);
|
|
79
|
+
|
|
80
|
+
if (initialTagger === '0x0000000000000000000000000000000000000000') {
|
|
81
|
+
console.log(' ℹ️ No specific tagger set (zero address)');
|
|
82
|
+
console.log(' ℹ️ No one can manage this tag (disabled)\n');
|
|
83
|
+
} else {
|
|
84
|
+
console.log(` ℹ️ Tagger is set to: ${initialTagger}\n`);
|
|
85
|
+
}
|
|
86
|
+
} catch (error: any) {
|
|
87
|
+
console.error(`❌ Error getting tagger: ${error.message}\n`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ========================================
|
|
91
|
+
// Part 3: Set a Specific Tagger
|
|
92
|
+
// ========================================
|
|
93
|
+
console.log('='.repeat(60));
|
|
94
|
+
console.log('Part 3: Set a Specific Tagger');
|
|
95
|
+
console.log('='.repeat(60));
|
|
96
|
+
|
|
97
|
+
// Example tagger address (replace with your own)
|
|
98
|
+
const taggerAddress = '0x1234567890123456789012345678901234567890';
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
console.log(`📝 Setting tagger to: ${taggerAddress}...`);
|
|
102
|
+
const result = await domain.setTagger(tagName, taggerAddress);
|
|
103
|
+
console.log(`✅ Tagger set successfully`);
|
|
104
|
+
console.log(` Transaction hash: ${result.transactionHash}\n`);
|
|
105
|
+
|
|
106
|
+
// Wait for indexing
|
|
107
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
108
|
+
|
|
109
|
+
// Verify the tagger was set
|
|
110
|
+
const newTagger = await domain.getTagger(tagName);
|
|
111
|
+
console.log(`📖 Verified tagger: ${newTagger}`);
|
|
112
|
+
|
|
113
|
+
if (newTagger.toLowerCase() === taggerAddress.toLowerCase()) {
|
|
114
|
+
console.log(' ✅ Tagger correctly set!\n');
|
|
115
|
+
} else {
|
|
116
|
+
console.log(' ⚠️ Tagger mismatch!\n');
|
|
117
|
+
}
|
|
118
|
+
} catch (error: any) {
|
|
119
|
+
console.error(`❌ Error setting tagger: ${error.message}\n`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ========================================
|
|
123
|
+
// Part 4: Set Tagger to Zero Address (Disable Tag Management)
|
|
124
|
+
// ========================================
|
|
125
|
+
console.log('='.repeat(60));
|
|
126
|
+
console.log('Part 4: Set Tagger to Zero Address (Disable Management)');
|
|
127
|
+
console.log('='.repeat(60));
|
|
128
|
+
|
|
129
|
+
const zeroAddress = '0x0000000000000000000000000000000000000000';
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
console.log(
|
|
133
|
+
`📝 Setting tagger to zero address (disable management)...`
|
|
134
|
+
);
|
|
135
|
+
const result = await domain.setTagger(tagName, zeroAddress);
|
|
136
|
+
console.log(`✅ Tagger set to zero address`);
|
|
137
|
+
console.log(` Transaction hash: ${result.transactionHash}\n`);
|
|
138
|
+
|
|
139
|
+
// Wait for indexing
|
|
140
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
141
|
+
|
|
142
|
+
// Verify
|
|
143
|
+
const publicTagger = await domain.getTagger(tagName);
|
|
144
|
+
console.log(`📖 Verified tagger: ${publicTagger}`);
|
|
145
|
+
|
|
146
|
+
if (publicTagger === zeroAddress) {
|
|
147
|
+
console.log(
|
|
148
|
+
' ✅ Tag management is now disabled (no one can set it)!\n'
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
} catch (error: any) {
|
|
152
|
+
console.error(`❌ Error setting tagger to zero: ${error.message}\n`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ========================================
|
|
156
|
+
// Part 5: Set Tagger to Self (Owner Only)
|
|
157
|
+
// ========================================
|
|
158
|
+
console.log('='.repeat(60));
|
|
159
|
+
console.log('Part 5: Set Tagger to Self (Owner Only)');
|
|
160
|
+
console.log('='.repeat(60));
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
console.log(`📝 Setting tagger to signer address (owner only)...`);
|
|
164
|
+
const result = await domain.setTagger(tagName, signerAddress);
|
|
165
|
+
console.log(`✅ Tagger set to: ${signerAddress}`);
|
|
166
|
+
console.log(` Transaction hash: ${result.transactionHash}\n`);
|
|
167
|
+
|
|
168
|
+
// Wait for indexing
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
170
|
+
|
|
171
|
+
// Verify
|
|
172
|
+
const ownerTagger = await domain.getTagger(tagName);
|
|
173
|
+
console.log(`📖 Verified tagger: ${ownerTagger}`);
|
|
174
|
+
|
|
175
|
+
if (ownerTagger.toLowerCase() === signerAddress.toLowerCase()) {
|
|
176
|
+
console.log(' ✅ Only the owner can manage this tag now!\n');
|
|
177
|
+
}
|
|
178
|
+
} catch (error: any) {
|
|
179
|
+
console.error(`❌ Error setting tagger to self: ${error.message}\n`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ========================================
|
|
183
|
+
// Part 6: Using TagContext (Advanced)
|
|
184
|
+
// ========================================
|
|
185
|
+
console.log('='.repeat(60));
|
|
186
|
+
console.log('Part 6: Using TagContext (Advanced API)');
|
|
187
|
+
console.log('='.repeat(60));
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const tagCtx = domain.tag();
|
|
191
|
+
|
|
192
|
+
console.log('📖 Getting tagger using TagContext...');
|
|
193
|
+
const ctxTagger = await tagCtx.getTagger(tagName);
|
|
194
|
+
console.log(` Tagger: ${ctxTagger}`);
|
|
195
|
+
|
|
196
|
+
console.log('\n📝 Setting tagger back to zero using TagContext...');
|
|
197
|
+
const result = await tagCtx.setTagger(tagName, zeroAddress);
|
|
198
|
+
console.log(` ✅ Done: ${result.transactionHash}\n`);
|
|
199
|
+
} catch (error: any) {
|
|
200
|
+
console.error(`❌ Error with TagContext: ${error.message}\n`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log('='.repeat(60));
|
|
204
|
+
console.log('✅ Tag Tagger Management Example Completed');
|
|
205
|
+
console.log('='.repeat(60));
|
|
206
|
+
console.log('\n💡 Key Points:');
|
|
207
|
+
console.log(' • Only domain owner can set taggers');
|
|
208
|
+
console.log(' • Zero address = disabled (no one can manage)');
|
|
209
|
+
console.log(' • Specific address = only that address can manage');
|
|
210
|
+
console.log(' • Use getTagger() to check who can manage a tag\n');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Run the example
|
|
214
|
+
main().catch((error) => {
|
|
215
|
+
console.error('❌ Fatal error:', error);
|
|
216
|
+
process.exit(1);
|
|
217
|
+
});
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { TagAbiCodec } from '../src/utils/tag-abi-codec';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test script for TagAbiCodec nested tuple conversion
|
|
5
|
+
* Tests the parseTupleFields and convertObjectToArray functions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
console.log('='.repeat(60));
|
|
9
|
+
console.log('TagAbiCodec Nested Tuple Conversion Test');
|
|
10
|
+
console.log('='.repeat(60));
|
|
11
|
+
|
|
12
|
+
// Test 1: Simple tuple
|
|
13
|
+
console.log('\n1. Simple Tuple:');
|
|
14
|
+
console.log(' ABI Type: tuple(string,uint8)');
|
|
15
|
+
const obj1 = { name: 'Alice', age: 30 };
|
|
16
|
+
console.log(' Input:', JSON.stringify(obj1));
|
|
17
|
+
const encoded1 = TagAbiCodec.encode('tuple(string,uint8)', obj1);
|
|
18
|
+
console.log(' Encoded:', encoded1);
|
|
19
|
+
const decoded1 = TagAbiCodec.decode('tuple(string,uint8)', encoded1);
|
|
20
|
+
console.log(
|
|
21
|
+
' Decoded:',
|
|
22
|
+
JSON.stringify(decoded1, (_, v) =>
|
|
23
|
+
typeof v === 'bigint' ? v.toString() : v
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Test 2: Nested tuple (1 level)
|
|
28
|
+
console.log('\n2. Nested Tuple (1 level):');
|
|
29
|
+
console.log(' ABI Type: tuple(string,tuple(uint8,bool))');
|
|
30
|
+
const obj2 = {
|
|
31
|
+
name: 'Alice',
|
|
32
|
+
details: {
|
|
33
|
+
age: 30,
|
|
34
|
+
verified: true
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
console.log(' Input:', JSON.stringify(obj2));
|
|
38
|
+
const encoded2 = TagAbiCodec.encode('tuple(string,tuple(uint8,bool))', obj2);
|
|
39
|
+
console.log(' Encoded:', encoded2);
|
|
40
|
+
const decoded2 = TagAbiCodec.decode(
|
|
41
|
+
'tuple(string,tuple(uint8,bool))',
|
|
42
|
+
encoded2
|
|
43
|
+
);
|
|
44
|
+
console.log(
|
|
45
|
+
' Decoded:',
|
|
46
|
+
JSON.stringify(decoded2, (_, v) =>
|
|
47
|
+
typeof v === 'bigint' ? v.toString() : v
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Test 3: Nested tuple (2 levels)
|
|
52
|
+
console.log('\n3. Nested Tuple (2 levels):');
|
|
53
|
+
console.log(
|
|
54
|
+
' ABI Type: tuple(string,tuple(uint8,bool),tuple(string,string))'
|
|
55
|
+
);
|
|
56
|
+
const obj3 = {
|
|
57
|
+
name: 'Alice',
|
|
58
|
+
details: {
|
|
59
|
+
age: 30,
|
|
60
|
+
verified: true
|
|
61
|
+
},
|
|
62
|
+
contact: {
|
|
63
|
+
email: 'alice@example.com',
|
|
64
|
+
phone: '+1-555-0123'
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
console.log(' Input:', JSON.stringify(obj3, null, 2));
|
|
68
|
+
const encoded3 = TagAbiCodec.encode(
|
|
69
|
+
'tuple(string,tuple(uint8,bool),tuple(string,string))',
|
|
70
|
+
obj3
|
|
71
|
+
);
|
|
72
|
+
console.log(' Encoded:', encoded3);
|
|
73
|
+
const decoded3 = TagAbiCodec.decode(
|
|
74
|
+
'tuple(string,tuple(uint8,bool),tuple(string,string))',
|
|
75
|
+
encoded3
|
|
76
|
+
);
|
|
77
|
+
console.log(
|
|
78
|
+
' Decoded:',
|
|
79
|
+
JSON.stringify(
|
|
80
|
+
decoded3,
|
|
81
|
+
(_, v) => (typeof v === 'bigint' ? v.toString() : v),
|
|
82
|
+
2
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// Test 4: Array notation (still supported)
|
|
87
|
+
console.log('\n4. Array Notation (still supported):');
|
|
88
|
+
console.log(' ABI Type: tuple(string,tuple(uint8,bool))');
|
|
89
|
+
const arr4 = ['Bob', [25, false]];
|
|
90
|
+
console.log(' Input:', JSON.stringify(arr4));
|
|
91
|
+
const encoded4 = TagAbiCodec.encode('tuple(string,tuple(uint8,bool))', arr4);
|
|
92
|
+
console.log(' Encoded:', encoded4);
|
|
93
|
+
const decoded4 = TagAbiCodec.decode(
|
|
94
|
+
'tuple(string,tuple(uint8,bool))',
|
|
95
|
+
encoded4
|
|
96
|
+
);
|
|
97
|
+
console.log(
|
|
98
|
+
' Decoded:',
|
|
99
|
+
JSON.stringify(decoded4, (_, v) =>
|
|
100
|
+
typeof v === 'bigint' ? v.toString() : v
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Test 5: Complex nested structure
|
|
105
|
+
console.log('\n5. Complex Nested Structure:');
|
|
106
|
+
console.log(' ABI Type: tuple(string,tuple(tuple(uint8,bool),address))');
|
|
107
|
+
const obj5 = {
|
|
108
|
+
name: 'Charlie',
|
|
109
|
+
data: {
|
|
110
|
+
info: {
|
|
111
|
+
age: 40,
|
|
112
|
+
active: true
|
|
113
|
+
},
|
|
114
|
+
wallet: '0x1234567890123456789012345678901234567890'
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
console.log(' Input:', JSON.stringify(obj5, null, 2));
|
|
118
|
+
const encoded5 = TagAbiCodec.encode(
|
|
119
|
+
'tuple(string,tuple(tuple(uint8,bool),address))',
|
|
120
|
+
obj5
|
|
121
|
+
);
|
|
122
|
+
console.log(' Encoded:', encoded5);
|
|
123
|
+
const decoded5 = TagAbiCodec.decode(
|
|
124
|
+
'tuple(string,tuple(tuple(uint8,bool),address))',
|
|
125
|
+
encoded5
|
|
126
|
+
);
|
|
127
|
+
console.log(
|
|
128
|
+
' Decoded:',
|
|
129
|
+
JSON.stringify(
|
|
130
|
+
decoded5,
|
|
131
|
+
(_, v) => (typeof v === 'bigint' ? v.toString() : v),
|
|
132
|
+
2
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
console.log('\n' + '='.repeat(60));
|
|
137
|
+
console.log('✅ All tests completed successfully!');
|
|
138
|
+
console.log('='.repeat(60));
|
|
139
|
+
console.log('\n💡 Key Features:');
|
|
140
|
+
console.log(' • Objects are automatically converted to arrays');
|
|
141
|
+
console.log(' • Nested tuples work recursively');
|
|
142
|
+
console.log(' • Array notation is still supported');
|
|
143
|
+
console.log(' • No need to manually provide field names\n');
|