@beclab/olaresid 0.1.13 → 0.2.1
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-TREE.md +107 -0
- package/CLI.md +122 -1340
- package/README.md +30 -12
- package/SDK-TREE.md +151 -0
- package/TAG.md +95 -41
- package/config.json +6 -4
- package/dist/abi/TerminusDIDQueryABI.d.ts +397 -0
- package/dist/abi/TerminusDIDQueryABI.d.ts.map +1 -0
- package/dist/abi/TerminusDIDQueryABI.js +519 -0
- package/dist/abi/TerminusDIDQueryABI.js.map +1 -0
- package/dist/business/index.d.ts.map +1 -1
- package/dist/business/index.js +9 -23
- package/dist/business/index.js.map +1 -1
- package/dist/business/tag-context.d.ts +1 -0
- package/dist/business/tag-context.d.ts.map +1 -1
- package/dist/business/tag-context.js +13 -7
- package/dist/business/tag-context.js.map +1 -1
- package/dist/cli.js +177 -76
- package/dist/cli.js.map +1 -1
- package/dist/config/index.d.ts +16 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +28 -14
- package/dist/config/index.js.map +1 -1
- package/dist/domain/core.d.ts +65 -0
- package/dist/domain/core.d.ts.map +1 -0
- package/dist/domain/core.js +317 -0
- package/dist/domain/core.js.map +1 -0
- package/dist/domain/index.d.ts +104 -57
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +188 -428
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/types.d.ts +56 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +3 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/index.d.ts +81 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +158 -143
- package/dist/index.js.map +1 -1
- package/dist/utils/crypto-utils.d.ts +110 -0
- package/dist/utils/crypto-utils.d.ts.map +1 -1
- package/dist/utils/crypto-utils.js +127 -8
- package/dist/utils/crypto-utils.js.map +1 -1
- package/dist/utils/error-parser.d.ts.map +1 -1
- package/dist/utils/error-parser.js +2 -1
- package/dist/utils/error-parser.js.map +1 -1
- package/dist/utils/event-parser.d.ts +161 -0
- package/dist/utils/event-parser.d.ts.map +1 -0
- package/dist/utils/event-parser.js +140 -0
- package/dist/utils/event-parser.js.map +1 -0
- package/dist/utils/tag-type-builder.d.ts +43 -0
- package/dist/utils/tag-type-builder.d.ts.map +1 -1
- package/dist/utils/tag-type-builder.js +122 -0
- package/dist/utils/tag-type-builder.js.map +1 -1
- package/dist/utils/tag-type-parser.d.ts +70 -0
- package/dist/utils/tag-type-parser.d.ts.map +1 -0
- package/dist/utils/tag-type-parser.js +190 -0
- package/dist/utils/tag-type-parser.js.map +1 -0
- package/examples/create-with-rpc-demo.ts +142 -0
- package/examples/fetch-all-flat-demo.ts +159 -0
- package/examples/fetch-by-indices-demo.ts +235 -0
- package/examples/fetch-domain-demo.ts +137 -0
- package/examples/fetch-domains-demo.ts +221 -0
- package/examples/frontend-demo/index.html +2 -2
- package/examples/frontend-demo/package-lock.json +4 -1
- package/examples/index.ts +3 -5
- package/jest.config.js +25 -0
- package/package.json +6 -2
- package/src/abi/TerminusDIDQueryABI.ts +516 -0
- package/src/business/index.ts +9 -33
- package/src/business/tag-context.ts +35 -7
- package/src/cli.ts +253 -90
- package/src/config/index.ts +34 -19
- package/src/domain/core.ts +382 -0
- package/src/domain/index.ts +271 -641
- package/src/domain/types.ts +59 -0
- package/src/index.ts +230 -207
- package/src/utils/crypto-utils.ts +205 -2
- package/src/utils/error-parser.ts +2 -1
- package/src/utils/event-parser.ts +353 -0
- package/src/utils/tag-type-builder.ts +138 -0
- package/src/utils/tag-type-parser.ts +246 -0
- package/tests/unit/crypto-utils.test.ts +338 -0
- package/tests/unit/ed25519-jwk.test.ts +201 -0
- package/tests/unit/event-parser.test.ts +690 -0
- package/tests/unit/generate-mnemonic.test.ts +268 -0
- package/tests/unit/olares-id-format.test.ts +321 -0
- package/tests/unit/tag-type-parser.test.ts +802 -0
- package/tests/unit/tag-types.test.ts +821 -0
- package/tests/unit/version.test.ts +14 -0
- package/tsconfig.json +3 -2
- package/dist/abi/ABITypeABI.d.ts +0 -88
- package/dist/abi/ABITypeABI.d.ts.map +0 -1
- package/dist/abi/ABITypeABI.js +0 -382
- package/dist/abi/ABITypeABI.js.map +0 -1
- package/dist/abi/RegistryABI.d.ts +0 -77
- package/dist/abi/RegistryABI.d.ts.map +0 -1
- package/dist/abi/RegistryABI.js +0 -462
- package/dist/abi/RegistryABI.js.map +0 -1
- package/dist/tag/address.d.ts +0 -11
- package/dist/tag/address.d.ts.map +0 -1
- package/dist/tag/address.js +0 -44
- package/dist/tag/address.js.map +0 -1
- package/dist/tag/array.d.ts +0 -14
- package/dist/tag/array.d.ts.map +0 -1
- package/dist/tag/array.js +0 -72
- package/dist/tag/array.js.map +0 -1
- package/dist/tag/bool.d.ts +0 -11
- package/dist/tag/bool.d.ts.map +0 -1
- package/dist/tag/bool.js +0 -43
- package/dist/tag/bool.js.map +0 -1
- package/dist/tag/bytes.d.ts +0 -11
- package/dist/tag/bytes.d.ts.map +0 -1
- package/dist/tag/bytes.js +0 -37
- package/dist/tag/bytes.js.map +0 -1
- package/dist/tag/flarray.d.ts +0 -15
- package/dist/tag/flarray.d.ts.map +0 -1
- package/dist/tag/flarray.js +0 -81
- package/dist/tag/flarray.js.map +0 -1
- package/dist/tag/flbytes.d.ts +0 -11
- package/dist/tag/flbytes.d.ts.map +0 -1
- package/dist/tag/flbytes.js +0 -47
- package/dist/tag/flbytes.js.map +0 -1
- package/dist/tag/index.d.ts +0 -32
- package/dist/tag/index.d.ts.map +0 -1
- package/dist/tag/index.js +0 -121
- package/dist/tag/index.js.map +0 -1
- package/dist/tag/int.d.ts +0 -12
- package/dist/tag/int.d.ts.map +0 -1
- package/dist/tag/int.js +0 -49
- package/dist/tag/int.js.map +0 -1
- package/dist/tag/string.d.ts +0 -11
- package/dist/tag/string.d.ts.map +0 -1
- package/dist/tag/string.js +0 -37
- package/dist/tag/string.js.map +0 -1
- package/dist/tag/tag.d.ts +0 -67
- package/dist/tag/tag.d.ts.map +0 -1
- package/dist/tag/tag.js +0 -157
- package/dist/tag/tag.js.map +0 -1
- package/dist/tag/tuple.d.ts +0 -17
- package/dist/tag/tuple.d.ts.map +0 -1
- package/dist/tag/tuple.js +0 -162
- package/dist/tag/tuple.js.map +0 -1
- package/dist/tag/uint.d.ts +0 -12
- package/dist/tag/uint.d.ts.map +0 -1
- package/dist/tag/uint.js +0 -49
- package/dist/tag/uint.js.map +0 -1
- package/dist/test/did.d.ts +0 -2
- package/dist/test/did.d.ts.map +0 -1
- package/dist/test/did.js +0 -177
- package/dist/test/did.js.map +0 -1
- package/dist/utils/tag-abi-codec.d.ts +0 -69
- package/dist/utils/tag-abi-codec.d.ts.map +0 -1
- package/dist/utils/tag-abi-codec.js +0 -144
- package/dist/utils/tag-abi-codec.js.map +0 -1
- package/examples/crypto-utilities.ts +0 -140
- package/examples/ed25519-jwk.ts +0 -73
- package/examples/generate-mnemonic.ts +0 -149
- package/examples/legacy.ts +0 -33
- package/examples/olares-id-format.ts +0 -197
- package/examples/tag-builder.ts +0 -235
- package/examples/tag-nested-tuple.ts +0 -190
- package/examples/tag-simple.ts +0 -149
- package/examples/tag-tagger.ts +0 -217
- package/examples/test-nested-tuple-conversion.ts +0 -143
- package/examples/test-type-bytes-parser.ts +0 -70
- package/src/abi/ABITypeABI.ts +0 -379
- package/src/abi/RegistryABI.ts +0 -459
- package/src/tag/address.ts +0 -48
- package/src/tag/array.ts +0 -80
- package/src/tag/bool.ts +0 -43
- package/src/tag/bytes.ts +0 -38
- package/src/tag/flarray.ts +0 -99
- package/src/tag/flbytes.ts +0 -48
- package/src/tag/index.ts +0 -170
- package/src/tag/int.ts +0 -51
- package/src/tag/string.ts +0 -38
- package/src/tag/tag.ts +0 -229
- package/src/tag/tuple.ts +0 -193
- package/src/tag/uint.ts +0 -51
- package/src/test/did.ts +0 -346
- package/src/utils/tag-abi-codec.ts +0 -158
|
@@ -0,0 +1,802 @@
|
|
|
1
|
+
import { AbiCoder } from 'ethers';
|
|
2
|
+
import { TagTypeParser } from '../../src/utils/tag-type-parser';
|
|
3
|
+
import { TagTypeBuilder } from '../../src/utils/tag-type-builder';
|
|
4
|
+
import { RawTagData } from '../../src/domain/types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Unit tests for TagTypeParser
|
|
8
|
+
* Tests tag parsing, tuple conversion, and BigInt handling
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
describe('TagTypeParser', () => {
|
|
12
|
+
let abiCoder: AbiCoder;
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
abiCoder = new AbiCoder();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// ========================================
|
|
19
|
+
// Parse Tag - Basic Types
|
|
20
|
+
// ========================================
|
|
21
|
+
|
|
22
|
+
describe('parseTag - Basic Types', () => {
|
|
23
|
+
it('should parse string tag', () => {
|
|
24
|
+
const rawTag: RawTagData = {
|
|
25
|
+
from: 'global',
|
|
26
|
+
name: 'latestDID',
|
|
27
|
+
abiType: '0x03',
|
|
28
|
+
value: abiCoder.encode(['string'], ['did:key:z6Mk...']),
|
|
29
|
+
fieldNamesHash: []
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
33
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
34
|
+
|
|
35
|
+
expect(tag.name).toBe('latestDID');
|
|
36
|
+
expect(tag.abiType).toBe('string');
|
|
37
|
+
expect(tag.valueFormatted).toBe('did:key:z6Mk...');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should parse uint8 tag', () => {
|
|
41
|
+
const rawTag: RawTagData = {
|
|
42
|
+
from: '1.com',
|
|
43
|
+
name: 'age',
|
|
44
|
+
abiType: '0x0101',
|
|
45
|
+
value: abiCoder.encode(['uint8'], [30]),
|
|
46
|
+
fieldNamesHash: []
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
50
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
51
|
+
|
|
52
|
+
expect(tag.abiType).toBe('uint8');
|
|
53
|
+
expect(tag.valueFormatted).toBe('30');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should parse uint256 tag and convert BigInt to string', () => {
|
|
57
|
+
const rawTag: RawTagData = {
|
|
58
|
+
from: '1.com',
|
|
59
|
+
name: 'balance',
|
|
60
|
+
abiType: '0x0120',
|
|
61
|
+
value: abiCoder.encode(['uint256'], [1000000000000000000n]),
|
|
62
|
+
fieldNamesHash: []
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
66
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
67
|
+
|
|
68
|
+
expect(tag.abiType).toBe('uint256');
|
|
69
|
+
expect(tag.valueFormatted).toBe('1000000000000000000');
|
|
70
|
+
expect(typeof tag.valueFormatted).toBe('string');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should parse bool tag', () => {
|
|
74
|
+
const rawTag: RawTagData = {
|
|
75
|
+
from: '1.com',
|
|
76
|
+
name: 'verified',
|
|
77
|
+
abiType: '0x02',
|
|
78
|
+
value: abiCoder.encode(['bool'], [true]),
|
|
79
|
+
fieldNamesHash: []
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
83
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
84
|
+
|
|
85
|
+
expect(tag.abiType).toBe('bool');
|
|
86
|
+
expect(tag.valueFormatted).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should parse address tag', () => {
|
|
90
|
+
const rawTag: RawTagData = {
|
|
91
|
+
from: 'global',
|
|
92
|
+
name: 'owner',
|
|
93
|
+
abiType: '0x07',
|
|
94
|
+
value: abiCoder.encode(
|
|
95
|
+
['address'],
|
|
96
|
+
['0x742d35cc6634c0532925a3b844bc9e7595f0beb0']
|
|
97
|
+
),
|
|
98
|
+
fieldNamesHash: []
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
102
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
103
|
+
|
|
104
|
+
expect(tag.abiType).toBe('address');
|
|
105
|
+
expect((tag.valueFormatted as string).toLowerCase()).toBe(
|
|
106
|
+
'0x742d35cc6634c0532925a3b844bc9e7595f0beb0'
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should parse bytes4 tag', () => {
|
|
111
|
+
const rawTag: RawTagData = {
|
|
112
|
+
from: 'global',
|
|
113
|
+
name: 'dnsARecord',
|
|
114
|
+
abiType: '0x0804',
|
|
115
|
+
value: abiCoder.encode(['bytes4'], ['0xc0a80101']),
|
|
116
|
+
fieldNamesHash: []
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
120
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
121
|
+
|
|
122
|
+
expect(tag.abiType).toBe('bytes4');
|
|
123
|
+
expect(tag.valueFormatted).toBe('0xc0a80101');
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ========================================
|
|
128
|
+
// Parse Tag - Array Types
|
|
129
|
+
// ========================================
|
|
130
|
+
|
|
131
|
+
describe('parseTag - Array Types', () => {
|
|
132
|
+
it('should parse address array', () => {
|
|
133
|
+
const addresses = [
|
|
134
|
+
'0x1111111111111111111111111111111111111111',
|
|
135
|
+
'0x2222222222222222222222222222222222222222'
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
const rawTag: RawTagData = {
|
|
139
|
+
from: '1.com',
|
|
140
|
+
name: 'wallets',
|
|
141
|
+
abiType: '0x0407',
|
|
142
|
+
value: abiCoder.encode(['address[]'], [addresses]),
|
|
143
|
+
fieldNamesHash: []
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
147
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
148
|
+
|
|
149
|
+
expect(tag.abiType).toBe('address[]');
|
|
150
|
+
const parsedAddresses = JSON.parse(tag.valueFormatted as string);
|
|
151
|
+
expect(Array.isArray(parsedAddresses)).toBe(true);
|
|
152
|
+
expect(parsedAddresses.length).toBe(2);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should parse string array', () => {
|
|
156
|
+
const links = ['https://x.com/alice', 'https://github.com/alice'];
|
|
157
|
+
|
|
158
|
+
const rawTag: RawTagData = {
|
|
159
|
+
from: '1.com',
|
|
160
|
+
name: 'socialLinks',
|
|
161
|
+
abiType: '0x0403',
|
|
162
|
+
value: abiCoder.encode(['string[]'], [links]),
|
|
163
|
+
fieldNamesHash: []
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
167
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
168
|
+
|
|
169
|
+
expect(tag.abiType).toBe('string[]');
|
|
170
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual(links);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should parse uint256 array and convert BigInt to string', () => {
|
|
174
|
+
const numbers = [100n, 200n, 300n];
|
|
175
|
+
|
|
176
|
+
const rawTag: RawTagData = {
|
|
177
|
+
from: '1.com',
|
|
178
|
+
name: 'scores',
|
|
179
|
+
abiType: '0x040120',
|
|
180
|
+
value: abiCoder.encode(['uint256[]'], [numbers]),
|
|
181
|
+
fieldNamesHash: []
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
185
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
186
|
+
|
|
187
|
+
expect(tag.abiType).toBe('uint256[]');
|
|
188
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual([
|
|
189
|
+
'100',
|
|
190
|
+
'200',
|
|
191
|
+
'300'
|
|
192
|
+
]);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// ========================================
|
|
197
|
+
// Parse Tag - Simple Tuple
|
|
198
|
+
// ========================================
|
|
199
|
+
|
|
200
|
+
describe('parseTag - Simple Tuple', () => {
|
|
201
|
+
it('should parse simple tuple with field names', () => {
|
|
202
|
+
const value = ['Alice', 30];
|
|
203
|
+
const hash =
|
|
204
|
+
'0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef';
|
|
205
|
+
|
|
206
|
+
const rawTag: RawTagData = {
|
|
207
|
+
from: '1.com',
|
|
208
|
+
name: 'userInfo',
|
|
209
|
+
abiType: '0x060002030101',
|
|
210
|
+
value: abiCoder.encode(['tuple(string,uint8)'], [value]),
|
|
211
|
+
fieldNamesHash: [hash]
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
215
|
+
fieldNamesMap.set(hash, ['name', 'age']);
|
|
216
|
+
|
|
217
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
218
|
+
|
|
219
|
+
expect(tag.abiType).toBe('tuple(string,uint8)');
|
|
220
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual({
|
|
221
|
+
name: 'Alice',
|
|
222
|
+
age: '30'
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('should parse tuple without field names (return array)', () => {
|
|
227
|
+
const value = ['Alice', 30];
|
|
228
|
+
|
|
229
|
+
const rawTag: RawTagData = {
|
|
230
|
+
from: '1.com',
|
|
231
|
+
name: 'userInfo',
|
|
232
|
+
abiType: '0x060002030101',
|
|
233
|
+
value: abiCoder.encode(['tuple(string,uint8)'], [value]),
|
|
234
|
+
fieldNamesHash: []
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
238
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
239
|
+
|
|
240
|
+
expect(tag.abiType).toBe('tuple(string,uint8)');
|
|
241
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual([
|
|
242
|
+
'Alice',
|
|
243
|
+
'30'
|
|
244
|
+
]);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should parse tuple with complex types', () => {
|
|
248
|
+
const value = [
|
|
249
|
+
'0x742d35cc6634c0532925a3b844bc9e7595f0beb0',
|
|
250
|
+
1000n,
|
|
251
|
+
true
|
|
252
|
+
];
|
|
253
|
+
const hash =
|
|
254
|
+
'0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890';
|
|
255
|
+
|
|
256
|
+
const rawTag: RawTagData = {
|
|
257
|
+
from: '1.com',
|
|
258
|
+
name: 'profile',
|
|
259
|
+
abiType: '0x060003070120020',
|
|
260
|
+
value: abiCoder.encode(
|
|
261
|
+
['tuple(address,uint256,bool)'],
|
|
262
|
+
[value]
|
|
263
|
+
),
|
|
264
|
+
fieldNamesHash: [hash]
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
268
|
+
fieldNamesMap.set(hash, ['owner', 'balance', 'active']);
|
|
269
|
+
|
|
270
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
271
|
+
|
|
272
|
+
expect(tag.abiType).toBe('tuple(address,uint256,bool)');
|
|
273
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual({
|
|
274
|
+
owner: expect.any(String),
|
|
275
|
+
balance: '1000',
|
|
276
|
+
active: true
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// ========================================
|
|
282
|
+
// Parse Tag - Nested Tuple
|
|
283
|
+
// ========================================
|
|
284
|
+
|
|
285
|
+
describe('parseTag - Nested Tuple', () => {
|
|
286
|
+
it('should parse nested tuple with field names', () => {
|
|
287
|
+
const value = ['Bob', [25, true]];
|
|
288
|
+
const hash1 =
|
|
289
|
+
'0x1111111111111111111111111111111111111111111111111111111111111111';
|
|
290
|
+
const hash2 =
|
|
291
|
+
'0x2222222222222222222222222222222222222222222222222222222222222222';
|
|
292
|
+
|
|
293
|
+
const rawTag: RawTagData = {
|
|
294
|
+
from: '1.com',
|
|
295
|
+
name: 'profile',
|
|
296
|
+
abiType: '0x06000203060002010102',
|
|
297
|
+
value: abiCoder.encode(
|
|
298
|
+
['tuple(string,tuple(uint8,bool))'],
|
|
299
|
+
[value]
|
|
300
|
+
),
|
|
301
|
+
fieldNamesHash: [hash1, hash2]
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
305
|
+
fieldNamesMap.set(hash1, ['name', 'details']);
|
|
306
|
+
fieldNamesMap.set(hash2, ['age', 'verified']);
|
|
307
|
+
|
|
308
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
309
|
+
|
|
310
|
+
expect(tag.abiType).toBe('tuple(string,tuple(uint8,bool))');
|
|
311
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual({
|
|
312
|
+
name: 'Bob',
|
|
313
|
+
details: {
|
|
314
|
+
age: '25',
|
|
315
|
+
verified: true
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('should parse deeply nested tuple', () => {
|
|
321
|
+
const value = ['Alice', [30, ['alice@example.com', '+1-555-0123']]];
|
|
322
|
+
const hash1 =
|
|
323
|
+
'0xaaaa111111111111111111111111111111111111111111111111111111111111';
|
|
324
|
+
const hash2 =
|
|
325
|
+
'0xbbbb222222222222222222222222222222222222222222222222222222222222';
|
|
326
|
+
const hash3 =
|
|
327
|
+
'0xcccc333333333333333333333333333333333333333333333333333333333333';
|
|
328
|
+
|
|
329
|
+
const rawTag: RawTagData = {
|
|
330
|
+
from: '1.com',
|
|
331
|
+
name: 'profile',
|
|
332
|
+
abiType: '0x06000203060002010106000203030',
|
|
333
|
+
value: abiCoder.encode(
|
|
334
|
+
['tuple(string,tuple(uint8,tuple(string,string)))'],
|
|
335
|
+
[value]
|
|
336
|
+
),
|
|
337
|
+
fieldNamesHash: [hash1, hash2, hash3]
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
341
|
+
fieldNamesMap.set(hash1, ['name', 'details']);
|
|
342
|
+
fieldNamesMap.set(hash2, ['age', 'contact']);
|
|
343
|
+
fieldNamesMap.set(hash3, ['email', 'phone']);
|
|
344
|
+
|
|
345
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
346
|
+
|
|
347
|
+
expect(tag.abiType).toBe(
|
|
348
|
+
'tuple(string,tuple(uint8,tuple(string,string)))'
|
|
349
|
+
);
|
|
350
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual({
|
|
351
|
+
name: 'Alice',
|
|
352
|
+
details: {
|
|
353
|
+
age: '30',
|
|
354
|
+
contact: {
|
|
355
|
+
email: 'alice@example.com',
|
|
356
|
+
phone: '+1-555-0123'
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// ========================================
|
|
364
|
+
// Parse Tag - Tuple Array
|
|
365
|
+
// ========================================
|
|
366
|
+
|
|
367
|
+
describe('parseTag - Tuple Array', () => {
|
|
368
|
+
it('should parse simple tuple array', () => {
|
|
369
|
+
const value = [
|
|
370
|
+
[0, '0x742d35cc6634c0532925a3b844bc9e7595f0beb0'],
|
|
371
|
+
[1, '0x1111111111111111111111111111111111111111']
|
|
372
|
+
];
|
|
373
|
+
const hash =
|
|
374
|
+
'0xa7011a7789e2d5350dd5d7f1cd1b05f9c6948c18fcad68f64983c8488b9b5625';
|
|
375
|
+
|
|
376
|
+
const rawTag: RawTagData = {
|
|
377
|
+
from: '',
|
|
378
|
+
name: 'authAddresses',
|
|
379
|
+
abiType: '0x04060002010107',
|
|
380
|
+
value: abiCoder.encode(['tuple(uint8,address)[]'], [value]),
|
|
381
|
+
fieldNamesHash: [hash]
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
385
|
+
fieldNamesMap.set(hash, ['algorithm', 'addr']);
|
|
386
|
+
|
|
387
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
388
|
+
|
|
389
|
+
expect(tag.abiType).toBe('tuple(uint8,address)[]');
|
|
390
|
+
const parsedAuthAddr = JSON.parse(tag.valueFormatted as string);
|
|
391
|
+
expect(Array.isArray(parsedAuthAddr)).toBe(true);
|
|
392
|
+
expect(parsedAuthAddr).toEqual([
|
|
393
|
+
{ algorithm: '0', addr: expect.any(String) },
|
|
394
|
+
{ algorithm: '1', addr: expect.any(String) }
|
|
395
|
+
]);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should parse nested tuple array', () => {
|
|
399
|
+
const value = [
|
|
400
|
+
[1, ['Alice', true]],
|
|
401
|
+
[2, ['Bob', false]]
|
|
402
|
+
];
|
|
403
|
+
const hash1 =
|
|
404
|
+
'0x1111111111111111111111111111111111111111111111111111111111111111';
|
|
405
|
+
const hash2 =
|
|
406
|
+
'0x2222222222222222222222222222222222222222222222222222222222222222';
|
|
407
|
+
|
|
408
|
+
const rawTag: RawTagData = {
|
|
409
|
+
from: '1.com',
|
|
410
|
+
name: 'items',
|
|
411
|
+
abiType: '0x04060002012006000203020',
|
|
412
|
+
value: abiCoder.encode(
|
|
413
|
+
['tuple(uint256,tuple(string,bool))[]'],
|
|
414
|
+
[value]
|
|
415
|
+
),
|
|
416
|
+
fieldNamesHash: [hash1, hash2]
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
420
|
+
fieldNamesMap.set(hash1, ['id', 'data']);
|
|
421
|
+
fieldNamesMap.set(hash2, ['name', 'active']);
|
|
422
|
+
|
|
423
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
424
|
+
|
|
425
|
+
expect(tag.abiType).toBe('tuple(uint256,tuple(string,bool))[]');
|
|
426
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual([
|
|
427
|
+
{ id: '1', data: { name: 'Alice', active: true } },
|
|
428
|
+
{ id: '2', data: { name: 'Bob', active: false } }
|
|
429
|
+
]);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it('should parse empty tuple array', () => {
|
|
433
|
+
const value: any[] = [];
|
|
434
|
+
const hash =
|
|
435
|
+
'0xa7011a7789e2d5350dd5d7f1cd1b05f9c6948c18fcad68f64983c8488b9b5625';
|
|
436
|
+
|
|
437
|
+
const rawTag: RawTagData = {
|
|
438
|
+
from: '',
|
|
439
|
+
name: 'authAddresses',
|
|
440
|
+
abiType: '0x04060002010107',
|
|
441
|
+
value: abiCoder.encode(['tuple(uint8,address)[]'], [value]),
|
|
442
|
+
fieldNamesHash: [hash]
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
446
|
+
fieldNamesMap.set(hash, ['algorithm', 'addr']);
|
|
447
|
+
|
|
448
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
449
|
+
|
|
450
|
+
expect(tag.abiType).toBe('tuple(uint8,address)[]');
|
|
451
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual([]);
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// ========================================
|
|
456
|
+
// Parse Tag - Complex Nested Tuples
|
|
457
|
+
// ========================================
|
|
458
|
+
|
|
459
|
+
describe('parseTag - Complex Nested Tuples', () => {
|
|
460
|
+
it('should parse tuple with multiple nested tuples', () => {
|
|
461
|
+
const value = [
|
|
462
|
+
'Alice Johnson',
|
|
463
|
+
[30, true],
|
|
464
|
+
['alice@example.com', '+1-555-0123']
|
|
465
|
+
];
|
|
466
|
+
const hash1 =
|
|
467
|
+
'0xbd67eb3ac6cf9025dadacf21cbc2fc2db499fc6154f0f8ff2ff87e114d60ad27';
|
|
468
|
+
const hash2 =
|
|
469
|
+
'0x2f85d0ec24ccc16f8739d2e76938c4e5104a4438ce0d6d2f9a793527d77aaf20';
|
|
470
|
+
const hash3 =
|
|
471
|
+
'0xc414cfe30fe6ad154c340fa4048fd9d2e36e551d4860498cb63f84188b08ffa4';
|
|
472
|
+
|
|
473
|
+
const rawTag: RawTagData = {
|
|
474
|
+
from: '1.com',
|
|
475
|
+
name: 'profile',
|
|
476
|
+
abiType: '0x06000303060002010102060002030303',
|
|
477
|
+
value: abiCoder.encode(
|
|
478
|
+
['tuple(string,tuple(uint8,bool),tuple(string,string))'],
|
|
479
|
+
[value]
|
|
480
|
+
),
|
|
481
|
+
fieldNamesHash: [hash1, hash2, hash3]
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
485
|
+
fieldNamesMap.set(hash1, ['name', 'details', 'contact']);
|
|
486
|
+
fieldNamesMap.set(hash2, ['age', 'verified']);
|
|
487
|
+
fieldNamesMap.set(hash3, ['email', 'phone']);
|
|
488
|
+
|
|
489
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
490
|
+
|
|
491
|
+
expect(tag.abiType).toBe(
|
|
492
|
+
'tuple(string,tuple(uint8,bool),tuple(string,string))'
|
|
493
|
+
);
|
|
494
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual({
|
|
495
|
+
name: 'Alice Johnson',
|
|
496
|
+
details: {
|
|
497
|
+
age: '30',
|
|
498
|
+
verified: true
|
|
499
|
+
},
|
|
500
|
+
contact: {
|
|
501
|
+
email: 'alice@example.com',
|
|
502
|
+
phone: '+1-555-0123'
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should parse tuple with array field', () => {
|
|
508
|
+
const value = [
|
|
509
|
+
'Alice',
|
|
510
|
+
31,
|
|
511
|
+
[
|
|
512
|
+
'0x1111111111111111111111111111111111111111',
|
|
513
|
+
'0x2222222222222222222222222222222222222222'
|
|
514
|
+
],
|
|
515
|
+
true
|
|
516
|
+
];
|
|
517
|
+
const hash =
|
|
518
|
+
'0xf1e429c1ee11d289bde872dd17c5937a9da2ad9212b711c15ff5afe8828ebcba';
|
|
519
|
+
|
|
520
|
+
const rawTag: RawTagData = {
|
|
521
|
+
from: '1.com',
|
|
522
|
+
name: 'userInfo',
|
|
523
|
+
abiType: '0x0600040301010407020',
|
|
524
|
+
value: abiCoder.encode(
|
|
525
|
+
['tuple(string,uint8,address[],bool)'],
|
|
526
|
+
[value]
|
|
527
|
+
),
|
|
528
|
+
fieldNamesHash: [hash]
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
532
|
+
fieldNamesMap.set(hash, ['name', 'age', 'wallets', 'verified']);
|
|
533
|
+
|
|
534
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
535
|
+
|
|
536
|
+
expect(tag.abiType).toBe('tuple(string,uint8,address[],bool)');
|
|
537
|
+
const parsedTuple = JSON.parse(tag.valueFormatted as string);
|
|
538
|
+
expect(parsedTuple).toEqual({
|
|
539
|
+
name: 'Alice',
|
|
540
|
+
age: '31',
|
|
541
|
+
wallets: expect.any(Array),
|
|
542
|
+
verified: true
|
|
543
|
+
});
|
|
544
|
+
expect(parsedTuple.wallets.length).toBe(2);
|
|
545
|
+
});
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// ========================================
|
|
549
|
+
// convertTupleToObject - Direct Tests
|
|
550
|
+
// ========================================
|
|
551
|
+
|
|
552
|
+
describe('convertTupleToObject', () => {
|
|
553
|
+
it('should convert simple tuple array to object', () => {
|
|
554
|
+
const value = ['Alice', 30];
|
|
555
|
+
const allFieldNames = [['name', 'age']];
|
|
556
|
+
const context = { fieldNameIndex: 0 };
|
|
557
|
+
|
|
558
|
+
const result = TagTypeParser.convertTupleToObject(
|
|
559
|
+
value,
|
|
560
|
+
'tuple(string,uint8)',
|
|
561
|
+
allFieldNames,
|
|
562
|
+
context
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
expect(result).toEqual({ name: 'Alice', age: 30 });
|
|
566
|
+
expect(context.fieldNameIndex).toBe(1);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
it('should convert nested tuple to object', () => {
|
|
570
|
+
const value = ['Bob', [25, true]];
|
|
571
|
+
const allFieldNames = [
|
|
572
|
+
['name', 'profile'],
|
|
573
|
+
['age', 'verified']
|
|
574
|
+
];
|
|
575
|
+
const context = { fieldNameIndex: 0 };
|
|
576
|
+
|
|
577
|
+
const result = TagTypeParser.convertTupleToObject(
|
|
578
|
+
value,
|
|
579
|
+
'tuple(string,tuple(uint8,bool))',
|
|
580
|
+
allFieldNames,
|
|
581
|
+
context
|
|
582
|
+
);
|
|
583
|
+
|
|
584
|
+
expect(result).toEqual({
|
|
585
|
+
name: 'Bob',
|
|
586
|
+
profile: { age: 25, verified: true }
|
|
587
|
+
});
|
|
588
|
+
expect(context.fieldNameIndex).toBe(2);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
it('should handle field name/value length mismatch', () => {
|
|
592
|
+
const value = ['Alice', 30, 'extra'];
|
|
593
|
+
const allFieldNames = [['name', 'age']]; // Only 2 field names
|
|
594
|
+
const context = { fieldNameIndex: 0 };
|
|
595
|
+
|
|
596
|
+
const result = TagTypeParser.convertTupleToObject(
|
|
597
|
+
value,
|
|
598
|
+
'tuple(string,uint8)',
|
|
599
|
+
allFieldNames,
|
|
600
|
+
context
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
// Should return original value when mismatch
|
|
604
|
+
expect(result).toEqual(value);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
it('should handle missing field names', () => {
|
|
608
|
+
const value = ['Alice', 30];
|
|
609
|
+
const allFieldNames: string[][] = []; // No field names
|
|
610
|
+
const context = { fieldNameIndex: 0 };
|
|
611
|
+
|
|
612
|
+
const result = TagTypeParser.convertTupleToObject(
|
|
613
|
+
value,
|
|
614
|
+
'tuple(string,uint8)',
|
|
615
|
+
allFieldNames,
|
|
616
|
+
context
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
// Should return original value when no field names
|
|
620
|
+
expect(result).toEqual(value);
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
it('should return non-array values as-is', () => {
|
|
624
|
+
const value = 'not-an-array';
|
|
625
|
+
const allFieldNames = [['name', 'age']];
|
|
626
|
+
const context = { fieldNameIndex: 0 };
|
|
627
|
+
|
|
628
|
+
const result = TagTypeParser.convertTupleToObject(
|
|
629
|
+
value,
|
|
630
|
+
'tuple(string,uint8)',
|
|
631
|
+
allFieldNames,
|
|
632
|
+
context
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
expect(result).toBe(value);
|
|
636
|
+
});
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
// ========================================
|
|
640
|
+
// convertBigIntToString - Direct Tests
|
|
641
|
+
// ========================================
|
|
642
|
+
|
|
643
|
+
describe('convertBigIntToString', () => {
|
|
644
|
+
it('should convert BigInt to string', () => {
|
|
645
|
+
const result = TagTypeParser.convertBigIntToString(1000n);
|
|
646
|
+
expect(result).toBe('1000');
|
|
647
|
+
expect(typeof result).toBe('string');
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
it('should convert BigInt in array', () => {
|
|
651
|
+
const result = TagTypeParser.convertBigIntToString([
|
|
652
|
+
100n,
|
|
653
|
+
200n,
|
|
654
|
+
300n
|
|
655
|
+
]);
|
|
656
|
+
expect(result).toEqual(['100', '200', '300']);
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it('should convert BigInt in object', () => {
|
|
660
|
+
const result = TagTypeParser.convertBigIntToString({
|
|
661
|
+
balance: 1000n,
|
|
662
|
+
amount: 2000n
|
|
663
|
+
});
|
|
664
|
+
expect(result).toEqual({
|
|
665
|
+
balance: '1000',
|
|
666
|
+
amount: '2000'
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
it('should handle nested structures with BigInt', () => {
|
|
671
|
+
const result = TagTypeParser.convertBigIntToString({
|
|
672
|
+
user: {
|
|
673
|
+
balances: [100n, 200n],
|
|
674
|
+
total: 300n
|
|
675
|
+
},
|
|
676
|
+
active: true
|
|
677
|
+
});
|
|
678
|
+
expect(result).toEqual({
|
|
679
|
+
user: {
|
|
680
|
+
balances: ['100', '200'],
|
|
681
|
+
total: '300'
|
|
682
|
+
},
|
|
683
|
+
active: true
|
|
684
|
+
});
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
it('should handle primitives and non-BigInt values', () => {
|
|
688
|
+
expect(TagTypeParser.convertBigIntToString('hello')).toBe('hello');
|
|
689
|
+
expect(TagTypeParser.convertBigIntToString(123)).toBe(123);
|
|
690
|
+
expect(TagTypeParser.convertBigIntToString(true)).toBe(true);
|
|
691
|
+
expect(TagTypeParser.convertBigIntToString(null)).toBe(null);
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
|
|
695
|
+
// ========================================
|
|
696
|
+
// Edge Cases
|
|
697
|
+
// ========================================
|
|
698
|
+
|
|
699
|
+
describe('Edge Cases', () => {
|
|
700
|
+
it('should handle tuple with all primitive types', () => {
|
|
701
|
+
const value = [
|
|
702
|
+
'test',
|
|
703
|
+
123,
|
|
704
|
+
true,
|
|
705
|
+
'0x742d35cc6634c0532925a3b844bc9e7595f0beb0',
|
|
706
|
+
'0xabcdef',
|
|
707
|
+
100n
|
|
708
|
+
];
|
|
709
|
+
const hash =
|
|
710
|
+
'0xedge111111111111111111111111111111111111111111111111111111111111';
|
|
711
|
+
|
|
712
|
+
const rawTag: RawTagData = {
|
|
713
|
+
from: '1.com',
|
|
714
|
+
name: 'mixed',
|
|
715
|
+
abiType: '0x0600060301010207090120',
|
|
716
|
+
value: abiCoder.encode(
|
|
717
|
+
['tuple(string,uint8,bool,address,bytes,uint256)'],
|
|
718
|
+
[value]
|
|
719
|
+
),
|
|
720
|
+
fieldNamesHash: [hash]
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
724
|
+
fieldNamesMap.set(hash, [
|
|
725
|
+
'str',
|
|
726
|
+
'num',
|
|
727
|
+
'flag',
|
|
728
|
+
'addr',
|
|
729
|
+
'data',
|
|
730
|
+
'balance'
|
|
731
|
+
]);
|
|
732
|
+
|
|
733
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
734
|
+
|
|
735
|
+
expect(tag.abiType).toBe(
|
|
736
|
+
'tuple(string,uint8,bool,address,bytes,uint256)'
|
|
737
|
+
);
|
|
738
|
+
const parsedMixed = JSON.parse(tag.valueFormatted as string);
|
|
739
|
+
expect(parsedMixed.str).toBe('test');
|
|
740
|
+
expect(parsedMixed.num).toBe('123');
|
|
741
|
+
expect(parsedMixed.flag).toBe(true);
|
|
742
|
+
expect(parsedMixed.balance).toBe('100');
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
it('should warn when field names not found for tuple', () => {
|
|
746
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
|
|
747
|
+
|
|
748
|
+
const value = ['Alice', 30];
|
|
749
|
+
const hash =
|
|
750
|
+
'0xnonexistent1111111111111111111111111111111111111111111111111111';
|
|
751
|
+
|
|
752
|
+
const rawTag: RawTagData = {
|
|
753
|
+
from: '1.com',
|
|
754
|
+
name: 'userInfo',
|
|
755
|
+
abiType: '0x060002030101',
|
|
756
|
+
value: abiCoder.encode(['tuple(string,uint8)'], [value]),
|
|
757
|
+
fieldNamesHash: [hash]
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
761
|
+
// Not adding the hash to fieldNamesMap
|
|
762
|
+
|
|
763
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
764
|
+
|
|
765
|
+
// Should have been called with the warning message
|
|
766
|
+
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
767
|
+
const callArgs = warnSpy.mock.calls[0];
|
|
768
|
+
expect(callArgs[0]).toContain('Field names not found');
|
|
769
|
+
expect(callArgs[0]).toContain('userInfo');
|
|
770
|
+
|
|
771
|
+
expect(JSON.parse(tag.valueFormatted as string)).toEqual([
|
|
772
|
+
'Alice',
|
|
773
|
+
'30'
|
|
774
|
+
]); // Falls back to array
|
|
775
|
+
|
|
776
|
+
warnSpy.mockRestore();
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
it('should not warn for zero hash', () => {
|
|
780
|
+
const warnSpy = jest.spyOn(console, 'warn').mockImplementation();
|
|
781
|
+
|
|
782
|
+
const value = ['Alice', 30];
|
|
783
|
+
|
|
784
|
+
const rawTag: RawTagData = {
|
|
785
|
+
from: '1.com',
|
|
786
|
+
name: 'userInfo',
|
|
787
|
+
abiType: '0x060002030101',
|
|
788
|
+
value: abiCoder.encode(['tuple(string,uint8)'], [value]),
|
|
789
|
+
fieldNamesHash: [
|
|
790
|
+
'0x0000000000000000000000000000000000000000000000000000000000000000'
|
|
791
|
+
]
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
const fieldNamesMap = new Map<string, string[]>();
|
|
795
|
+
const tag = TagTypeParser.parseTag(rawTag, fieldNamesMap, abiCoder);
|
|
796
|
+
|
|
797
|
+
expect(warnSpy).toHaveBeenCalledTimes(0);
|
|
798
|
+
|
|
799
|
+
warnSpy.mockRestore();
|
|
800
|
+
});
|
|
801
|
+
});
|
|
802
|
+
});
|