@latticexyz/protocol-parser 2.0.0-alpha.1.222
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/LICENSE +21 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
- package/src/abiTypeToDefaultValue.ts +8 -0
- package/src/abiTypesToSchema.test.ts +28 -0
- package/src/abiTypesToSchema.ts +15 -0
- package/src/abiTypesToSchemaData.test.ts +14 -0
- package/src/abiTypesToSchemaData.ts +21 -0
- package/src/assertExhaustive.ts +3 -0
- package/src/common.ts +13 -0
- package/src/decodeDynamicField.test-d.ts +48 -0
- package/src/decodeDynamicField.test.ts +175 -0
- package/src/decodeDynamicField.ts +141 -0
- package/src/decodeKeyTuple.test.ts +34 -0
- package/src/decodeKeyTuple.ts +11 -0
- package/src/decodeStaticField.test-d.ts +40 -0
- package/src/decodeStaticField.test.ts +94 -0
- package/src/decodeStaticField.ts +145 -0
- package/src/dynamicAbiTypes.test-d.ts +66 -0
- package/src/dynamicAbiTypes.ts +131 -0
- package/src/errors.ts +64 -0
- package/src/hexToPackedCounter.test.ts +34 -0
- package/src/hexToPackedCounter.ts +31 -0
- package/src/hexToSchema.test.ts +40 -0
- package/src/hexToSchema.ts +41 -0
- package/src/hexToTableSchema.ts +14 -0
- package/src/index.ts +14 -0
- package/src/schemaAbiTypes.ts +211 -0
- package/src/staticAbiTypes.test-d.ts +58 -0
- package/src/staticAbiTypes.ts +221 -0
- package/src/utils.ts +5 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Hex, hexToString, sliceHex } from "viem";
|
|
2
|
+
import { DynamicAbiType, DynamicAbiTypeToPrimitiveType, arrayAbiTypeToStaticAbiType } from "./dynamicAbiTypes";
|
|
3
|
+
import { assertExhaustive } from "./assertExhaustive";
|
|
4
|
+
import { staticAbiTypeToByteLength } from "./staticAbiTypes";
|
|
5
|
+
import { decodeStaticField } from "./decodeStaticField";
|
|
6
|
+
import { InvalidHexLengthError, InvalidHexLengthForArrayFieldError } from "./errors";
|
|
7
|
+
|
|
8
|
+
// TODO: require size/length for dynamic fields, because hex might be longer (sometimes we just move the length pointer of arrays without updating the value)
|
|
9
|
+
// this means the error should probably change from "invalid length" to "too short", which viem has that we could reuse?
|
|
10
|
+
|
|
11
|
+
export function decodeDynamicField<
|
|
12
|
+
TAbiType extends DynamicAbiType,
|
|
13
|
+
TPrimitiveType extends DynamicAbiTypeToPrimitiveType<TAbiType>
|
|
14
|
+
>(abiType: TAbiType, data: Hex): TPrimitiveType {
|
|
15
|
+
if (abiType === "bytes") {
|
|
16
|
+
return data as TPrimitiveType;
|
|
17
|
+
}
|
|
18
|
+
if (abiType === "string") {
|
|
19
|
+
return hexToString(data) as TPrimitiveType;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (data.length > 3 && data.length % 2 !== 0) {
|
|
23
|
+
throw new InvalidHexLengthError(data);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const dataSize = (data.length - 2) / 2;
|
|
27
|
+
|
|
28
|
+
switch (abiType) {
|
|
29
|
+
case "uint8[]":
|
|
30
|
+
case "uint16[]":
|
|
31
|
+
case "uint24[]":
|
|
32
|
+
case "uint32[]":
|
|
33
|
+
case "uint40[]":
|
|
34
|
+
case "uint48[]":
|
|
35
|
+
case "uint56[]":
|
|
36
|
+
case "uint64[]":
|
|
37
|
+
case "uint72[]":
|
|
38
|
+
case "uint80[]":
|
|
39
|
+
case "uint88[]":
|
|
40
|
+
case "uint96[]":
|
|
41
|
+
case "uint104[]":
|
|
42
|
+
case "uint112[]":
|
|
43
|
+
case "uint120[]":
|
|
44
|
+
case "uint128[]":
|
|
45
|
+
case "uint136[]":
|
|
46
|
+
case "uint144[]":
|
|
47
|
+
case "uint152[]":
|
|
48
|
+
case "uint160[]":
|
|
49
|
+
case "uint168[]":
|
|
50
|
+
case "uint176[]":
|
|
51
|
+
case "uint184[]":
|
|
52
|
+
case "uint192[]":
|
|
53
|
+
case "uint200[]":
|
|
54
|
+
case "uint208[]":
|
|
55
|
+
case "uint216[]":
|
|
56
|
+
case "uint224[]":
|
|
57
|
+
case "uint232[]":
|
|
58
|
+
case "uint240[]":
|
|
59
|
+
case "uint248[]":
|
|
60
|
+
case "uint256[]":
|
|
61
|
+
case "int8[]":
|
|
62
|
+
case "int16[]":
|
|
63
|
+
case "int24[]":
|
|
64
|
+
case "int32[]":
|
|
65
|
+
case "int40[]":
|
|
66
|
+
case "int48[]":
|
|
67
|
+
case "int56[]":
|
|
68
|
+
case "int64[]":
|
|
69
|
+
case "int72[]":
|
|
70
|
+
case "int80[]":
|
|
71
|
+
case "int88[]":
|
|
72
|
+
case "int96[]":
|
|
73
|
+
case "int104[]":
|
|
74
|
+
case "int112[]":
|
|
75
|
+
case "int120[]":
|
|
76
|
+
case "int128[]":
|
|
77
|
+
case "int136[]":
|
|
78
|
+
case "int144[]":
|
|
79
|
+
case "int152[]":
|
|
80
|
+
case "int160[]":
|
|
81
|
+
case "int168[]":
|
|
82
|
+
case "int176[]":
|
|
83
|
+
case "int184[]":
|
|
84
|
+
case "int192[]":
|
|
85
|
+
case "int200[]":
|
|
86
|
+
case "int208[]":
|
|
87
|
+
case "int216[]":
|
|
88
|
+
case "int224[]":
|
|
89
|
+
case "int232[]":
|
|
90
|
+
case "int240[]":
|
|
91
|
+
case "int248[]":
|
|
92
|
+
case "int256[]":
|
|
93
|
+
case "bytes1[]":
|
|
94
|
+
case "bytes2[]":
|
|
95
|
+
case "bytes3[]":
|
|
96
|
+
case "bytes4[]":
|
|
97
|
+
case "bytes5[]":
|
|
98
|
+
case "bytes6[]":
|
|
99
|
+
case "bytes7[]":
|
|
100
|
+
case "bytes8[]":
|
|
101
|
+
case "bytes9[]":
|
|
102
|
+
case "bytes10[]":
|
|
103
|
+
case "bytes11[]":
|
|
104
|
+
case "bytes12[]":
|
|
105
|
+
case "bytes13[]":
|
|
106
|
+
case "bytes14[]":
|
|
107
|
+
case "bytes15[]":
|
|
108
|
+
case "bytes16[]":
|
|
109
|
+
case "bytes17[]":
|
|
110
|
+
case "bytes18[]":
|
|
111
|
+
case "bytes19[]":
|
|
112
|
+
case "bytes20[]":
|
|
113
|
+
case "bytes21[]":
|
|
114
|
+
case "bytes22[]":
|
|
115
|
+
case "bytes23[]":
|
|
116
|
+
case "bytes24[]":
|
|
117
|
+
case "bytes25[]":
|
|
118
|
+
case "bytes26[]":
|
|
119
|
+
case "bytes27[]":
|
|
120
|
+
case "bytes28[]":
|
|
121
|
+
case "bytes29[]":
|
|
122
|
+
case "bytes30[]":
|
|
123
|
+
case "bytes31[]":
|
|
124
|
+
case "bytes32[]":
|
|
125
|
+
case "bool[]":
|
|
126
|
+
case "address[]": {
|
|
127
|
+
const staticAbiType = arrayAbiTypeToStaticAbiType(abiType);
|
|
128
|
+
const itemByteLength = staticAbiTypeToByteLength[staticAbiType];
|
|
129
|
+
if (dataSize % itemByteLength !== 0) {
|
|
130
|
+
throw new InvalidHexLengthForArrayFieldError(staticAbiType, data);
|
|
131
|
+
}
|
|
132
|
+
const items = new Array(dataSize / itemByteLength).fill(undefined).map((_, i) => {
|
|
133
|
+
const itemData = sliceHex(data, i * itemByteLength, (i + 1) * itemByteLength);
|
|
134
|
+
return decodeStaticField(staticAbiType, itemData);
|
|
135
|
+
});
|
|
136
|
+
return items as TPrimitiveType;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return assertExhaustive(abiType, `Unsupported dynamic ABI type: ${abiType}`);
|
|
141
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { decodeKeyTuple } from "./decodeKeyTuple";
|
|
3
|
+
import { abiTypesToSchema } from "./abiTypesToSchema";
|
|
4
|
+
|
|
5
|
+
describe("decodeKeyTuple", () => {
|
|
6
|
+
it("can decode bool key tuple", () => {
|
|
7
|
+
expect(
|
|
8
|
+
decodeKeyTuple(abiTypesToSchema(["bool"]), ["0x0000000000000000000000000000000000000000000000000000000000000000"])
|
|
9
|
+
).toStrictEqual([false]);
|
|
10
|
+
expect(
|
|
11
|
+
decodeKeyTuple(abiTypesToSchema(["bool"]), ["0x0000000000000000000000000000000000000000000000000000000000000001"])
|
|
12
|
+
).toStrictEqual([true]);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("can decode complex key tuple", () => {
|
|
16
|
+
expect(
|
|
17
|
+
decodeKeyTuple(abiTypesToSchema(["uint256", "int32", "bytes16", "address", "bool", "int8"]), [
|
|
18
|
+
"0x000000000000000000000000000000000000000000000000000000000000002a",
|
|
19
|
+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6",
|
|
20
|
+
"0x1234000000000000000000000000000000000000000000000000000000000000",
|
|
21
|
+
"0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff",
|
|
22
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
23
|
+
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
24
|
+
])
|
|
25
|
+
).toStrictEqual([
|
|
26
|
+
42n,
|
|
27
|
+
-42,
|
|
28
|
+
"0x12340000000000000000000000000000",
|
|
29
|
+
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF",
|
|
30
|
+
true,
|
|
31
|
+
3,
|
|
32
|
+
]);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Schema } from "./common";
|
|
2
|
+
import { Hex, decodeAbiParameters } from "viem";
|
|
3
|
+
import { StaticPrimitiveType } from "./staticAbiTypes";
|
|
4
|
+
|
|
5
|
+
// key tuples are encoded in the same way as abi.encode, so we can decode them with viem
|
|
6
|
+
|
|
7
|
+
export function decodeKeyTuple(keySchema: Schema, keyTuple: Hex[]): StaticPrimitiveType[] {
|
|
8
|
+
return keyTuple.map(
|
|
9
|
+
(key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { assertType, describe, it } from "vitest";
|
|
2
|
+
import { decodeStaticField } from "./decodeStaticField";
|
|
3
|
+
import { Hex } from "viem";
|
|
4
|
+
|
|
5
|
+
describe("decodeStaticField", () => {
|
|
6
|
+
it("returns a boolean for bool ABI type", () => {
|
|
7
|
+
assertType<boolean>(decodeStaticField("bool", "0x"));
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("returns a number or bigint for uint ABI types", () => {
|
|
11
|
+
assertType<number>(decodeStaticField("uint8", "0x"));
|
|
12
|
+
assertType<number>(decodeStaticField("uint16", "0x"));
|
|
13
|
+
assertType<number>(decodeStaticField("uint32", "0x"));
|
|
14
|
+
assertType<number>(decodeStaticField("uint48", "0x"));
|
|
15
|
+
assertType<bigint>(decodeStaticField("uint56", "0x"));
|
|
16
|
+
assertType<bigint>(decodeStaticField("uint128", "0x"));
|
|
17
|
+
assertType<bigint>(decodeStaticField("uint256", "0x"));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("returns a number or bigint for int ABI types", () => {
|
|
21
|
+
assertType<number>(decodeStaticField("int8", "0x"));
|
|
22
|
+
assertType<number>(decodeStaticField("int16", "0x"));
|
|
23
|
+
assertType<number>(decodeStaticField("int32", "0x"));
|
|
24
|
+
assertType<number>(decodeStaticField("int48", "0x"));
|
|
25
|
+
assertType<bigint>(decodeStaticField("int56", "0x"));
|
|
26
|
+
assertType<bigint>(decodeStaticField("int128", "0x"));
|
|
27
|
+
assertType<bigint>(decodeStaticField("int256", "0x"));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("returns a hex for bytes ABI types", () => {
|
|
31
|
+
assertType<Hex>(decodeStaticField("bytes1", "0x"));
|
|
32
|
+
assertType<Hex>(decodeStaticField("bytes2", "0x"));
|
|
33
|
+
assertType<Hex>(decodeStaticField("bytes8", "0x"));
|
|
34
|
+
assertType<Hex>(decodeStaticField("bytes32", "0x"));
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("returns a hex for address ABI type", () => {
|
|
38
|
+
assertType<Hex>(decodeStaticField("address", "0x"));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { decodeStaticField } from "./decodeStaticField";
|
|
3
|
+
|
|
4
|
+
describe("decodeStaticField", () => {
|
|
5
|
+
it("can decode bool", () => {
|
|
6
|
+
expect(decodeStaticField("bool", "0x00")).toBe(false);
|
|
7
|
+
expect(decodeStaticField("bool", "0x01")).toBe(true);
|
|
8
|
+
|
|
9
|
+
expect(() => decodeStaticField("bool", "0x0")).toThrow(
|
|
10
|
+
'Hex value "0x0" has length of 1, but expected length of 2 for bool type.'
|
|
11
|
+
);
|
|
12
|
+
expect(() => decodeStaticField("bool", "0x1")).toThrow(
|
|
13
|
+
'Hex value "0x1" has length of 1, but expected length of 2 for bool type.'
|
|
14
|
+
);
|
|
15
|
+
expect(() => decodeStaticField("bool", "0x000")).toThrow(
|
|
16
|
+
'Hex value "0x000" is an odd length (3). It must be an even length.'
|
|
17
|
+
);
|
|
18
|
+
expect(() => decodeStaticField("bool", "0x001")).toThrow(
|
|
19
|
+
'Hex value "0x001" is an odd length (3). It must be an even length.'
|
|
20
|
+
);
|
|
21
|
+
expect(() => decodeStaticField("bool", "0x0000")).toThrow(
|
|
22
|
+
'Hex value "0x0000" has length of 4, but expected length of 2 for bool type.'
|
|
23
|
+
);
|
|
24
|
+
expect(() => decodeStaticField("bool", "0x0001")).toThrow(
|
|
25
|
+
'Hex value "0x0001" has length of 4, but expected length of 2 for bool type.'
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("can decode uint8", () => {
|
|
30
|
+
expect(decodeStaticField("uint8", "0x00")).toBe(0);
|
|
31
|
+
expect(decodeStaticField("uint8", "0x01")).toBe(1);
|
|
32
|
+
expect(decodeStaticField("uint8", "0xff")).toBe(255);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("can decode uint256", () => {
|
|
36
|
+
expect(decodeStaticField("uint256", "0x0000000000000000000000000000000000000000000000000000000000000000")).toBe(0n);
|
|
37
|
+
expect(decodeStaticField("uint256", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(1n);
|
|
38
|
+
expect(decodeStaticField("uint256", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
39
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639935n
|
|
40
|
+
);
|
|
41
|
+
expect(decodeStaticField("uint256", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")).toBe(
|
|
42
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639934n
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("can decode int8", () => {
|
|
47
|
+
expect(decodeStaticField("int8", "0x00")).toBe(0);
|
|
48
|
+
expect(decodeStaticField("int8", "0x01")).toBe(1);
|
|
49
|
+
expect(decodeStaticField("int8", "0x7f")).toBe(127);
|
|
50
|
+
expect(decodeStaticField("int8", "0x80")).toBe(-128);
|
|
51
|
+
expect(decodeStaticField("int8", "0x81")).toBe(-127);
|
|
52
|
+
expect(decodeStaticField("int8", "0xff")).toBe(-1);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("can decode int256", () => {
|
|
56
|
+
expect(decodeStaticField("int256", "0x0000000000000000000000000000000000000000000000000000000000000000")).toBe(0n);
|
|
57
|
+
expect(decodeStaticField("int256", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(1n);
|
|
58
|
+
expect(decodeStaticField("int256", "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
59
|
+
57896044618658097711785492504343953926634992332820282019728792003956564819967n
|
|
60
|
+
);
|
|
61
|
+
expect(decodeStaticField("int256", "0x8000000000000000000000000000000000000000000000000000000000000000")).toBe(
|
|
62
|
+
-57896044618658097711785492504343953926634992332820282019728792003956564819968n
|
|
63
|
+
);
|
|
64
|
+
expect(decodeStaticField("int256", "0x8000000000000000000000000000000000000000000000000000000000000001")).toBe(
|
|
65
|
+
-57896044618658097711785492504343953926634992332820282019728792003956564819967n
|
|
66
|
+
);
|
|
67
|
+
expect(decodeStaticField("int256", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(-1n);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("can decode bytes", () => {
|
|
71
|
+
expect(decodeStaticField("bytes1", "0x01")).toBe("0x01");
|
|
72
|
+
expect(decodeStaticField("bytes2", "0x0001")).toBe("0x0001");
|
|
73
|
+
expect(decodeStaticField("bytes8", "0xff00ff00ff00ff00")).toBe("0xff00ff00ff00ff00");
|
|
74
|
+
expect(decodeStaticField("bytes32", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(
|
|
75
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("can decode address", () => {
|
|
80
|
+
expect(decodeStaticField("address", "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")).toBe(
|
|
81
|
+
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
|
82
|
+
);
|
|
83
|
+
expect(decodeStaticField("address", "0xffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
84
|
+
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF"
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
expect(() => decodeStaticField("address", "0x00")).toThrow(
|
|
88
|
+
'Hex value "0x00" has length of 2, but expected length of 40 for address type.'
|
|
89
|
+
);
|
|
90
|
+
expect(() => decodeStaticField("address", "0xffffffffffffffffffffffffffffffffffffffffff")).toThrow(
|
|
91
|
+
'Hex value "0xffffffffffffffffffffffffffffffffffffffffff" has length of 42, but expected length of 40 for address type.'
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Hex, getAddress, hexToBigInt, hexToBool } from "viem";
|
|
2
|
+
import {
|
|
3
|
+
StaticAbiType,
|
|
4
|
+
StaticAbiTypeToPrimitiveType,
|
|
5
|
+
staticAbiTypeToByteLength,
|
|
6
|
+
staticAbiTypeToDefaultValue,
|
|
7
|
+
} from "./staticAbiTypes";
|
|
8
|
+
import { assertExhaustive } from "./assertExhaustive";
|
|
9
|
+
import { InvalidHexLengthError, InvalidHexLengthForStaticFieldError } from "./errors";
|
|
10
|
+
|
|
11
|
+
export function decodeStaticField<
|
|
12
|
+
TAbiType extends StaticAbiType,
|
|
13
|
+
TPrimitiveType extends StaticAbiTypeToPrimitiveType<TAbiType>
|
|
14
|
+
>(abiType: TAbiType, data: Hex): TPrimitiveType {
|
|
15
|
+
if (data.length > 3 && data.length % 2 !== 0) {
|
|
16
|
+
throw new InvalidHexLengthError(data);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const dataSize = (data.length - 2) / 2;
|
|
20
|
+
if (dataSize !== staticAbiTypeToByteLength[abiType]) {
|
|
21
|
+
throw new InvalidHexLengthForStaticFieldError(abiType, data);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
switch (abiType) {
|
|
25
|
+
case "uint8":
|
|
26
|
+
case "uint16":
|
|
27
|
+
case "uint24":
|
|
28
|
+
case "uint32":
|
|
29
|
+
case "uint40":
|
|
30
|
+
case "uint48":
|
|
31
|
+
case "uint56":
|
|
32
|
+
case "uint64":
|
|
33
|
+
case "uint72":
|
|
34
|
+
case "uint80":
|
|
35
|
+
case "uint88":
|
|
36
|
+
case "uint96":
|
|
37
|
+
case "uint104":
|
|
38
|
+
case "uint112":
|
|
39
|
+
case "uint120":
|
|
40
|
+
case "uint128":
|
|
41
|
+
case "uint136":
|
|
42
|
+
case "uint144":
|
|
43
|
+
case "uint152":
|
|
44
|
+
case "uint160":
|
|
45
|
+
case "uint168":
|
|
46
|
+
case "uint176":
|
|
47
|
+
case "uint184":
|
|
48
|
+
case "uint192":
|
|
49
|
+
case "uint200":
|
|
50
|
+
case "uint208":
|
|
51
|
+
case "uint216":
|
|
52
|
+
case "uint224":
|
|
53
|
+
case "uint232":
|
|
54
|
+
case "uint240":
|
|
55
|
+
case "uint248":
|
|
56
|
+
case "uint256":
|
|
57
|
+
case "int8":
|
|
58
|
+
case "int16":
|
|
59
|
+
case "int24":
|
|
60
|
+
case "int32":
|
|
61
|
+
case "int40":
|
|
62
|
+
case "int48":
|
|
63
|
+
case "int56":
|
|
64
|
+
case "int64":
|
|
65
|
+
case "int72":
|
|
66
|
+
case "int80":
|
|
67
|
+
case "int88":
|
|
68
|
+
case "int96":
|
|
69
|
+
case "int104":
|
|
70
|
+
case "int112":
|
|
71
|
+
case "int120":
|
|
72
|
+
case "int128":
|
|
73
|
+
case "int136":
|
|
74
|
+
case "int144":
|
|
75
|
+
case "int152":
|
|
76
|
+
case "int160":
|
|
77
|
+
case "int168":
|
|
78
|
+
case "int176":
|
|
79
|
+
case "int184":
|
|
80
|
+
case "int192":
|
|
81
|
+
case "int200":
|
|
82
|
+
case "int208":
|
|
83
|
+
case "int216":
|
|
84
|
+
case "int224":
|
|
85
|
+
case "int232":
|
|
86
|
+
case "int240":
|
|
87
|
+
case "int248":
|
|
88
|
+
case "int256": {
|
|
89
|
+
const value = hexToBigInt(data, { signed: abiType.startsWith("int") });
|
|
90
|
+
const defaultValueType = typeof staticAbiTypeToDefaultValue[abiType];
|
|
91
|
+
if (defaultValueType === "number") {
|
|
92
|
+
return Number(value) as TPrimitiveType;
|
|
93
|
+
}
|
|
94
|
+
if (defaultValueType === "bigint") {
|
|
95
|
+
return value as TPrimitiveType;
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Unexpected default value type (${defaultValueType}) for ABI type (${abiType})`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
case "bytes1":
|
|
101
|
+
case "bytes2":
|
|
102
|
+
case "bytes3":
|
|
103
|
+
case "bytes4":
|
|
104
|
+
case "bytes5":
|
|
105
|
+
case "bytes6":
|
|
106
|
+
case "bytes7":
|
|
107
|
+
case "bytes8":
|
|
108
|
+
case "bytes9":
|
|
109
|
+
case "bytes10":
|
|
110
|
+
case "bytes11":
|
|
111
|
+
case "bytes12":
|
|
112
|
+
case "bytes13":
|
|
113
|
+
case "bytes14":
|
|
114
|
+
case "bytes15":
|
|
115
|
+
case "bytes16":
|
|
116
|
+
case "bytes17":
|
|
117
|
+
case "bytes18":
|
|
118
|
+
case "bytes19":
|
|
119
|
+
case "bytes20":
|
|
120
|
+
case "bytes21":
|
|
121
|
+
case "bytes22":
|
|
122
|
+
case "bytes23":
|
|
123
|
+
case "bytes24":
|
|
124
|
+
case "bytes25":
|
|
125
|
+
case "bytes26":
|
|
126
|
+
case "bytes27":
|
|
127
|
+
case "bytes28":
|
|
128
|
+
case "bytes29":
|
|
129
|
+
case "bytes30":
|
|
130
|
+
case "bytes31":
|
|
131
|
+
case "bytes32": {
|
|
132
|
+
return data as TPrimitiveType;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
case "bool": {
|
|
136
|
+
return hexToBool(data) as TPrimitiveType;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
case "address": {
|
|
140
|
+
return getAddress(data) as TPrimitiveType;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return assertExhaustive(abiType, `Unsupported static ABI type: ${abiType}`);
|
|
145
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from "vitest";
|
|
2
|
+
import { DynamicAbiTypeToPrimitiveType } from "./dynamicAbiTypes";
|
|
3
|
+
import { Hex } from "viem";
|
|
4
|
+
|
|
5
|
+
describe("DynamicAbiTypeToPrimitiveType", () => {
|
|
6
|
+
it("maps uint8 array to number array", () => {
|
|
7
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"uint8[]">>().toMatchTypeOf<number[]>();
|
|
8
|
+
});
|
|
9
|
+
it("maps uint32 array to number array", () => {
|
|
10
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"uint32[]">>().toMatchTypeOf<number[]>();
|
|
11
|
+
});
|
|
12
|
+
it("maps uint48 array to number array", () => {
|
|
13
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"uint48[]">>().toMatchTypeOf<number[]>();
|
|
14
|
+
});
|
|
15
|
+
it("maps uint56 array to bigint array", () => {
|
|
16
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"uint56[]">>().toMatchTypeOf<bigint[]>();
|
|
17
|
+
});
|
|
18
|
+
it("maps uint256 array to bigint array", () => {
|
|
19
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"uint256[]">>().toMatchTypeOf<bigint[]>();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("maps int8 array to number array", () => {
|
|
23
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"int8[]">>().toMatchTypeOf<number[]>();
|
|
24
|
+
});
|
|
25
|
+
it("maps int32 array to number array", () => {
|
|
26
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"int32[]">>().toMatchTypeOf<number[]>();
|
|
27
|
+
});
|
|
28
|
+
it("maps int48 array to number array", () => {
|
|
29
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"int48[]">>().toMatchTypeOf<number[]>();
|
|
30
|
+
});
|
|
31
|
+
it("maps int56 array to bigint array", () => {
|
|
32
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"int56[]">>().toMatchTypeOf<bigint[]>();
|
|
33
|
+
});
|
|
34
|
+
it("maps int256 array to bigint array", () => {
|
|
35
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"int256[]">>().toMatchTypeOf<bigint[]>();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("maps bytes1 array to hex array", () => {
|
|
39
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bytes1[]">>().toMatchTypeOf<Hex[]>();
|
|
40
|
+
});
|
|
41
|
+
it("maps bytes2 array to hex array", () => {
|
|
42
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bytes2[]">>().toMatchTypeOf<Hex[]>();
|
|
43
|
+
});
|
|
44
|
+
it("maps bytes8 array to hex array", () => {
|
|
45
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bytes8[]">>().toMatchTypeOf<Hex[]>();
|
|
46
|
+
});
|
|
47
|
+
it("maps bytes32 array to hex array", () => {
|
|
48
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bytes32[]">>().toMatchTypeOf<Hex[]>();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("maps bool array to boolean array", () => {
|
|
52
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bool[]">>().toMatchTypeOf<boolean[]>();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("maps address array to hex array", () => {
|
|
56
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"address[]">>().toMatchTypeOf<Hex[]>();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("maps bytes to hex", () => {
|
|
60
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"bytes">>().toMatchTypeOf<Hex>();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("maps string to string", () => {
|
|
64
|
+
expectTypeOf<DynamicAbiTypeToPrimitiveType<"string">>().toMatchTypeOf<string>();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { StaticAbiType } from "./staticAbiTypes";
|
|
2
|
+
import { Hex } from "viem";
|
|
3
|
+
import { dynamicAbiTypes } from "./schemaAbiTypes";
|
|
4
|
+
|
|
5
|
+
// Variable-length ABI types, where their lengths are defined by a PackedCounter
|
|
6
|
+
|
|
7
|
+
export { dynamicAbiTypes };
|
|
8
|
+
|
|
9
|
+
export type DynamicAbiType = (typeof dynamicAbiTypes)[number];
|
|
10
|
+
|
|
11
|
+
export type DynamicPrimitiveType = number[] | bigint[] | Hex[] | boolean[] | Hex | string;
|
|
12
|
+
|
|
13
|
+
export const dynamicAbiTypeToDefaultValue = {
|
|
14
|
+
"uint8[]": [] as number[],
|
|
15
|
+
"uint16[]": [] as number[],
|
|
16
|
+
"uint24[]": [] as number[],
|
|
17
|
+
"uint32[]": [] as number[],
|
|
18
|
+
"uint40[]": [] as number[],
|
|
19
|
+
"uint48[]": [] as number[],
|
|
20
|
+
"uint56[]": [] as bigint[],
|
|
21
|
+
"uint64[]": [] as bigint[],
|
|
22
|
+
"uint72[]": [] as bigint[],
|
|
23
|
+
"uint80[]": [] as bigint[],
|
|
24
|
+
"uint88[]": [] as bigint[],
|
|
25
|
+
"uint96[]": [] as bigint[],
|
|
26
|
+
"uint104[]": [] as bigint[],
|
|
27
|
+
"uint112[]": [] as bigint[],
|
|
28
|
+
"uint120[]": [] as bigint[],
|
|
29
|
+
"uint128[]": [] as bigint[],
|
|
30
|
+
"uint136[]": [] as bigint[],
|
|
31
|
+
"uint144[]": [] as bigint[],
|
|
32
|
+
"uint152[]": [] as bigint[],
|
|
33
|
+
"uint160[]": [] as bigint[],
|
|
34
|
+
"uint168[]": [] as bigint[],
|
|
35
|
+
"uint176[]": [] as bigint[],
|
|
36
|
+
"uint184[]": [] as bigint[],
|
|
37
|
+
"uint192[]": [] as bigint[],
|
|
38
|
+
"uint200[]": [] as bigint[],
|
|
39
|
+
"uint208[]": [] as bigint[],
|
|
40
|
+
"uint216[]": [] as bigint[],
|
|
41
|
+
"uint224[]": [] as bigint[],
|
|
42
|
+
"uint232[]": [] as bigint[],
|
|
43
|
+
"uint240[]": [] as bigint[],
|
|
44
|
+
"uint248[]": [] as bigint[],
|
|
45
|
+
"uint256[]": [] as bigint[],
|
|
46
|
+
|
|
47
|
+
"int8[]": [] as number[],
|
|
48
|
+
"int16[]": [] as number[],
|
|
49
|
+
"int24[]": [] as number[],
|
|
50
|
+
"int32[]": [] as number[],
|
|
51
|
+
"int40[]": [] as number[],
|
|
52
|
+
"int48[]": [] as number[],
|
|
53
|
+
"int56[]": [] as bigint[],
|
|
54
|
+
"int64[]": [] as bigint[],
|
|
55
|
+
"int72[]": [] as bigint[],
|
|
56
|
+
"int80[]": [] as bigint[],
|
|
57
|
+
"int88[]": [] as bigint[],
|
|
58
|
+
"int96[]": [] as bigint[],
|
|
59
|
+
"int104[]": [] as bigint[],
|
|
60
|
+
"int112[]": [] as bigint[],
|
|
61
|
+
"int120[]": [] as bigint[],
|
|
62
|
+
"int128[]": [] as bigint[],
|
|
63
|
+
"int136[]": [] as bigint[],
|
|
64
|
+
"int144[]": [] as bigint[],
|
|
65
|
+
"int152[]": [] as bigint[],
|
|
66
|
+
"int160[]": [] as bigint[],
|
|
67
|
+
"int168[]": [] as bigint[],
|
|
68
|
+
"int176[]": [] as bigint[],
|
|
69
|
+
"int184[]": [] as bigint[],
|
|
70
|
+
"int192[]": [] as bigint[],
|
|
71
|
+
"int200[]": [] as bigint[],
|
|
72
|
+
"int208[]": [] as bigint[],
|
|
73
|
+
"int216[]": [] as bigint[],
|
|
74
|
+
"int224[]": [] as bigint[],
|
|
75
|
+
"int232[]": [] as bigint[],
|
|
76
|
+
"int240[]": [] as bigint[],
|
|
77
|
+
"int248[]": [] as bigint[],
|
|
78
|
+
"int256[]": [] as bigint[],
|
|
79
|
+
|
|
80
|
+
"bytes1[]": [] as Hex[],
|
|
81
|
+
"bytes2[]": [] as Hex[],
|
|
82
|
+
"bytes3[]": [] as Hex[],
|
|
83
|
+
"bytes4[]": [] as Hex[],
|
|
84
|
+
"bytes5[]": [] as Hex[],
|
|
85
|
+
"bytes6[]": [] as Hex[],
|
|
86
|
+
"bytes7[]": [] as Hex[],
|
|
87
|
+
"bytes8[]": [] as Hex[],
|
|
88
|
+
"bytes9[]": [] as Hex[],
|
|
89
|
+
"bytes10[]": [] as Hex[],
|
|
90
|
+
"bytes11[]": [] as Hex[],
|
|
91
|
+
"bytes12[]": [] as Hex[],
|
|
92
|
+
"bytes13[]": [] as Hex[],
|
|
93
|
+
"bytes14[]": [] as Hex[],
|
|
94
|
+
"bytes15[]": [] as Hex[],
|
|
95
|
+
"bytes16[]": [] as Hex[],
|
|
96
|
+
"bytes17[]": [] as Hex[],
|
|
97
|
+
"bytes18[]": [] as Hex[],
|
|
98
|
+
"bytes19[]": [] as Hex[],
|
|
99
|
+
"bytes20[]": [] as Hex[],
|
|
100
|
+
"bytes21[]": [] as Hex[],
|
|
101
|
+
"bytes22[]": [] as Hex[],
|
|
102
|
+
"bytes23[]": [] as Hex[],
|
|
103
|
+
"bytes24[]": [] as Hex[],
|
|
104
|
+
"bytes25[]": [] as Hex[],
|
|
105
|
+
"bytes26[]": [] as Hex[],
|
|
106
|
+
"bytes27[]": [] as Hex[],
|
|
107
|
+
"bytes28[]": [] as Hex[],
|
|
108
|
+
"bytes29[]": [] as Hex[],
|
|
109
|
+
"bytes30[]": [] as Hex[],
|
|
110
|
+
"bytes31[]": [] as Hex[],
|
|
111
|
+
"bytes32[]": [] as Hex[],
|
|
112
|
+
|
|
113
|
+
"bool[]": [] as boolean[],
|
|
114
|
+
"address[]": [] as Hex[],
|
|
115
|
+
|
|
116
|
+
bytes: "0x",
|
|
117
|
+
string: "",
|
|
118
|
+
} as const satisfies Record<DynamicAbiType, DynamicPrimitiveType>;
|
|
119
|
+
|
|
120
|
+
export type DynamicAbiTypeToPrimitiveType<TDynamicAbiType extends DynamicAbiType = DynamicAbiType> =
|
|
121
|
+
(typeof dynamicAbiTypeToDefaultValue)[TDynamicAbiType];
|
|
122
|
+
|
|
123
|
+
export type ArrayAbiTypeToStaticAbiType<T extends string> = T extends `${infer StaticAbiType}[]`
|
|
124
|
+
? StaticAbiType
|
|
125
|
+
: never;
|
|
126
|
+
|
|
127
|
+
export function arrayAbiTypeToStaticAbiType<T extends `${StaticAbiType}[]`>(
|
|
128
|
+
abiType: T
|
|
129
|
+
): ArrayAbiTypeToStaticAbiType<T> {
|
|
130
|
+
return abiType.replace(/\[\]$/g, "") as ArrayAbiTypeToStaticAbiType<T>;
|
|
131
|
+
}
|