@latticexyz/protocol-parser 2.0.0-snapshot-test-32d38619 → 2.0.0
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/dist/index.d.ts +2 -0
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +145 -0
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -0
- package/package.json +19 -9
- package/src/abiTypesToSchema.ts +1 -1
- package/src/common.ts +17 -3
- package/src/decodeDynamicField.test.ts +26 -26
- package/src/decodeDynamicField.ts +4 -4
- package/src/decodeField.ts +2 -2
- package/src/decodeKey.ts +2 -2
- package/src/decodeKeyTuple.test.ts +3 -3
- package/src/decodeKeyTuple.ts +3 -3
- package/src/decodeRecord.test.ts +1 -1
- package/src/decodeRecord.ts +5 -5
- package/src/decodeStaticField.test.ts +16 -16
- package/src/decodeStaticField.ts +2 -2
- package/src/decodeValue.ts +2 -2
- package/src/decodeValueArgs.ts +3 -3
- package/src/encodeField.ts +4 -4
- package/src/encodeKey.ts +1 -1
- package/src/encodeKeyTuple.test.ts +3 -3
- package/src/encodeKeyTuple.ts +1 -1
- package/src/encodeLengths.test.ts +7 -1
- package/src/encodeLengths.ts +1 -1
- package/src/encodeRecord.test.ts +1 -1
- package/src/encodeRecord.ts +5 -5
- package/src/encodeValue.ts +1 -1
- package/src/encodeValueArgs.test.ts +53 -0
- package/src/encodeValueArgs.ts +18 -9
- package/src/errors.ts +12 -11
- package/src/exports/index.ts +5 -0
- package/src/exports/internal.ts +31 -0
- package/src/getKeySchema.ts +9 -0
- package/src/getSchemaTypes.ts +10 -0
- package/src/getValueSchema.ts +11 -0
- package/src/hexToEncodedLengths.test.ts +35 -0
- package/src/{hexToPackedCounter.ts → hexToEncodedLengths.ts} +5 -5
- package/src/hexToSchema.test.ts +3 -2
- package/src/hexToSchema.ts +8 -2
- package/src/keySchemaToHex.ts +1 -1
- package/src/schemaIndexToAbiType.ts +1 -1
- package/src/schemaToHex.test.ts +3 -3
- package/src/schemaToHex.ts +1 -1
- package/src/staticDataLength.ts +1 -1
- package/src/valueSchemaToFieldLayoutHex.ts +1 -1
- package/src/valueSchemaToHex.ts +1 -1
- package/src/hexToPackedCounter.test.ts +0 -34
- package/src/index.ts +0 -27
|
@@ -22,28 +22,28 @@ describe("decodeDynamicField", () => {
|
|
|
22
22
|
|
|
23
23
|
it("can decode uint256[]", () => {
|
|
24
24
|
expect(
|
|
25
|
-
decodeDynamicField("uint256[]", "0x0000000000000000000000000000000000000000000000000000000000000000")
|
|
25
|
+
decodeDynamicField("uint256[]", "0x0000000000000000000000000000000000000000000000000000000000000000"),
|
|
26
26
|
).toStrictEqual([0n]);
|
|
27
27
|
expect(
|
|
28
|
-
decodeDynamicField("uint256[]", "0x0000000000000000000000000000000000000000000000000000000000000001")
|
|
28
|
+
decodeDynamicField("uint256[]", "0x0000000000000000000000000000000000000000000000000000000000000001"),
|
|
29
29
|
).toStrictEqual([1n]);
|
|
30
30
|
expect(
|
|
31
|
-
decodeDynamicField("uint256[]", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
31
|
+
decodeDynamicField("uint256[]", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
32
32
|
).toStrictEqual([115792089237316195423570985008687907853269984665640564039457584007913129639935n]);
|
|
33
33
|
expect(
|
|
34
|
-
decodeDynamicField("uint256[]", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")
|
|
34
|
+
decodeDynamicField("uint256[]", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"),
|
|
35
35
|
).toStrictEqual([115792089237316195423570985008687907853269984665640564039457584007913129639934n]);
|
|
36
36
|
expect(
|
|
37
37
|
decodeDynamicField(
|
|
38
38
|
"uint256[]",
|
|
39
|
-
"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001"
|
|
40
|
-
)
|
|
39
|
+
"0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
|
|
40
|
+
),
|
|
41
41
|
).toStrictEqual([1n, 1n]);
|
|
42
42
|
expect(
|
|
43
43
|
decodeDynamicField(
|
|
44
44
|
"uint256[]",
|
|
45
|
-
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
46
|
-
)
|
|
45
|
+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
46
|
+
),
|
|
47
47
|
).toStrictEqual([
|
|
48
48
|
115792089237316195423570985008687907853269984665640564039457584007913129639935n,
|
|
49
49
|
115792089237316195423570985008687907853269984665640564039457584007913129639935n,
|
|
@@ -68,41 +68,41 @@ describe("decodeDynamicField", () => {
|
|
|
68
68
|
|
|
69
69
|
it("can decode int256[]", () => {
|
|
70
70
|
expect(
|
|
71
|
-
decodeDynamicField("int256[]", "0x0000000000000000000000000000000000000000000000000000000000000000")
|
|
71
|
+
decodeDynamicField("int256[]", "0x0000000000000000000000000000000000000000000000000000000000000000"),
|
|
72
72
|
).toStrictEqual([0n]);
|
|
73
73
|
expect(
|
|
74
|
-
decodeDynamicField("int256[]", "0x0000000000000000000000000000000000000000000000000000000000000001")
|
|
74
|
+
decodeDynamicField("int256[]", "0x0000000000000000000000000000000000000000000000000000000000000001"),
|
|
75
75
|
).toStrictEqual([1n]);
|
|
76
76
|
expect(
|
|
77
|
-
decodeDynamicField("int256[]", "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
77
|
+
decodeDynamicField("int256[]", "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
78
78
|
).toStrictEqual([57896044618658097711785492504343953926634992332820282019728792003956564819967n]);
|
|
79
79
|
expect(
|
|
80
|
-
decodeDynamicField("int256[]", "0x8000000000000000000000000000000000000000000000000000000000000000")
|
|
80
|
+
decodeDynamicField("int256[]", "0x8000000000000000000000000000000000000000000000000000000000000000"),
|
|
81
81
|
).toStrictEqual([-57896044618658097711785492504343953926634992332820282019728792003956564819968n]);
|
|
82
82
|
expect(
|
|
83
|
-
decodeDynamicField("int256[]", "0x8000000000000000000000000000000000000000000000000000000000000001")
|
|
83
|
+
decodeDynamicField("int256[]", "0x8000000000000000000000000000000000000000000000000000000000000001"),
|
|
84
84
|
).toStrictEqual([-57896044618658097711785492504343953926634992332820282019728792003956564819967n]);
|
|
85
85
|
expect(
|
|
86
|
-
decodeDynamicField("int256[]", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
86
|
+
decodeDynamicField("int256[]", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
|
87
87
|
).toStrictEqual([-1n]);
|
|
88
88
|
|
|
89
89
|
expect(
|
|
90
90
|
decodeDynamicField(
|
|
91
91
|
"int256[]",
|
|
92
|
-
"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
|
93
|
-
)
|
|
92
|
+
"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
93
|
+
),
|
|
94
94
|
).toStrictEqual([57896044618658097711785492504343953926634992332820282019728792003956564819967n, -1n]);
|
|
95
95
|
expect(
|
|
96
96
|
decodeDynamicField(
|
|
97
97
|
"int256[]",
|
|
98
|
-
"0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
99
|
-
)
|
|
98
|
+
"0x80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
99
|
+
),
|
|
100
100
|
).toStrictEqual([-57896044618658097711785492504343953926634992332820282019728792003956564819968n, 0n]);
|
|
101
101
|
expect(
|
|
102
102
|
decodeDynamicField(
|
|
103
103
|
"int256[]",
|
|
104
|
-
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000001"
|
|
105
|
-
)
|
|
104
|
+
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000001",
|
|
105
|
+
),
|
|
106
106
|
).toStrictEqual([-1n, -57896044618658097711785492504343953926634992332820282019728792003956564819967n]);
|
|
107
107
|
});
|
|
108
108
|
|
|
@@ -129,13 +129,13 @@ describe("decodeDynamicField", () => {
|
|
|
129
129
|
]);
|
|
130
130
|
expect(decodeDynamicField("bytes4[]", "0xff00ff00ff00ff00")).toStrictEqual(["0xff00ff00", "0xff00ff00"]);
|
|
131
131
|
expect(
|
|
132
|
-
decodeDynamicField("bytes32[]", "0x0000000000000000000000000000000000000000000000000000000000000001")
|
|
132
|
+
decodeDynamicField("bytes32[]", "0x0000000000000000000000000000000000000000000000000000000000000001"),
|
|
133
133
|
).toStrictEqual(["0x0000000000000000000000000000000000000000000000000000000000000001"]);
|
|
134
134
|
expect(
|
|
135
135
|
decodeDynamicField(
|
|
136
136
|
"bytes32[]",
|
|
137
|
-
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
|
|
138
|
-
)
|
|
137
|
+
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
|
|
138
|
+
),
|
|
139
139
|
).toStrictEqual([
|
|
140
140
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
141
141
|
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
@@ -151,10 +151,10 @@ describe("decodeDynamicField", () => {
|
|
|
151
151
|
]);
|
|
152
152
|
|
|
153
153
|
expect(() => decodeDynamicField("address[]", "0x00")).toThrow(
|
|
154
|
-
'Hex value "0x00" has length of 2, but expected a multiple of 40 for address[] type.'
|
|
154
|
+
'Hex value "0x00" has length of 2, but expected a multiple of 40 for address[] type.',
|
|
155
155
|
);
|
|
156
156
|
expect(() => decodeDynamicField("address[]", "0xffffffffffffffffffffffffffffffffffffffffff")).toThrow(
|
|
157
|
-
'Hex value "0xffffffffffffffffffffffffffffffffffffffffff" has length of 42, but expected a multiple of 40 for address[] type.'
|
|
157
|
+
'Hex value "0xffffffffffffffffffffffffffffffffffffffffff" has length of 42, but expected a multiple of 40 for address[] type.',
|
|
158
158
|
);
|
|
159
159
|
});
|
|
160
160
|
|
|
@@ -164,7 +164,7 @@ describe("decodeDynamicField", () => {
|
|
|
164
164
|
expect(decodeDynamicField("bytes", "0x0001")).toBe("0x0001");
|
|
165
165
|
expect(decodeDynamicField("bytes", "0xff00ff00ff00ff00")).toBe("0xff00ff00ff00ff00");
|
|
166
166
|
expect(decodeDynamicField("bytes", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(
|
|
167
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
|
167
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
168
168
|
);
|
|
169
169
|
});
|
|
170
170
|
|
|
@@ -3,9 +3,9 @@ import { assertExhaustive } from "@latticexyz/common/utils";
|
|
|
3
3
|
import {
|
|
4
4
|
DynamicAbiType,
|
|
5
5
|
DynamicAbiTypeToPrimitiveType,
|
|
6
|
-
|
|
6
|
+
arrayToStaticAbiType,
|
|
7
7
|
staticAbiTypeToByteLength,
|
|
8
|
-
} from "@latticexyz/schema-type";
|
|
8
|
+
} from "@latticexyz/schema-type/internal";
|
|
9
9
|
import { decodeStaticField } from "./decodeStaticField";
|
|
10
10
|
import { InvalidHexLengthError, InvalidHexLengthForArrayFieldError } from "./errors";
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@ import { InvalidHexLengthError, InvalidHexLengthForArrayFieldError } from "./err
|
|
|
14
14
|
|
|
15
15
|
export function decodeDynamicField<
|
|
16
16
|
TAbiType extends DynamicAbiType,
|
|
17
|
-
TPrimitiveType extends DynamicAbiTypeToPrimitiveType<TAbiType
|
|
17
|
+
TPrimitiveType extends DynamicAbiTypeToPrimitiveType<TAbiType>,
|
|
18
18
|
>(abiType: TAbiType, data: Hex): TPrimitiveType {
|
|
19
19
|
if (abiType === "bytes") {
|
|
20
20
|
return data as TPrimitiveType;
|
|
@@ -128,7 +128,7 @@ export function decodeDynamicField<
|
|
|
128
128
|
case "bytes32[]":
|
|
129
129
|
case "bool[]":
|
|
130
130
|
case "address[]": {
|
|
131
|
-
const staticAbiType =
|
|
131
|
+
const staticAbiType = arrayToStaticAbiType(abiType);
|
|
132
132
|
const itemByteLength = staticAbiTypeToByteLength[staticAbiType];
|
|
133
133
|
if (dataSize % itemByteLength !== 0) {
|
|
134
134
|
throw new InvalidHexLengthForArrayFieldError(staticAbiType, data);
|
package/src/decodeField.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Hex } from "viem";
|
|
2
|
-
import { SchemaAbiType, SchemaAbiTypeToPrimitiveType, isDynamicAbiType } from "@latticexyz/schema-type";
|
|
2
|
+
import { SchemaAbiType, SchemaAbiTypeToPrimitiveType, isDynamicAbiType } from "@latticexyz/schema-type/internal";
|
|
3
3
|
import { decodeDynamicField } from "./decodeDynamicField";
|
|
4
4
|
import { decodeStaticField } from "./decodeStaticField";
|
|
5
5
|
|
|
6
6
|
export function decodeField<
|
|
7
7
|
TAbiType extends SchemaAbiType,
|
|
8
|
-
TPrimitiveType extends SchemaAbiTypeToPrimitiveType<TAbiType
|
|
8
|
+
TPrimitiveType extends SchemaAbiTypeToPrimitiveType<TAbiType>,
|
|
9
9
|
>(abiType: TAbiType, data: Hex): TPrimitiveType {
|
|
10
10
|
return (
|
|
11
11
|
isDynamicAbiType(abiType) ? decodeDynamicField(abiType, data) : decodeStaticField(abiType, data)
|
package/src/decodeKey.ts
CHANGED
|
@@ -4,12 +4,12 @@ import { decodeKeyTuple } from "./decodeKeyTuple";
|
|
|
4
4
|
|
|
5
5
|
export function decodeKey<TSchema extends KeySchema>(
|
|
6
6
|
keySchema: TSchema,
|
|
7
|
-
data: readonly Hex[]
|
|
7
|
+
data: readonly Hex[],
|
|
8
8
|
): SchemaToPrimitives<TSchema> {
|
|
9
9
|
// TODO: refactor and move all decodeKeyTuple logic into this method so we can delete decodeKeyTuple
|
|
10
10
|
const keyValues = decodeKeyTuple({ staticFields: Object.values(keySchema), dynamicFields: [] }, data);
|
|
11
11
|
|
|
12
12
|
return Object.fromEntries(
|
|
13
|
-
Object.keys(keySchema).map((name, i) => [name, keyValues[i]])
|
|
13
|
+
Object.keys(keySchema).map((name, i) => [name, keyValues[i]]),
|
|
14
14
|
) as SchemaToPrimitives<TSchema>;
|
|
15
15
|
}
|
|
@@ -6,12 +6,12 @@ describe("decodeKeyTuple", () => {
|
|
|
6
6
|
expect(
|
|
7
7
|
decodeKeyTuple({ staticFields: ["bool"], dynamicFields: [] }, [
|
|
8
8
|
"0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
9
|
-
])
|
|
9
|
+
]),
|
|
10
10
|
).toStrictEqual([false]);
|
|
11
11
|
expect(
|
|
12
12
|
decodeKeyTuple({ staticFields: ["bool"], dynamicFields: [] }, [
|
|
13
13
|
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
14
|
-
])
|
|
14
|
+
]),
|
|
15
15
|
).toStrictEqual([true]);
|
|
16
16
|
});
|
|
17
17
|
|
|
@@ -24,7 +24,7 @@ describe("decodeKeyTuple", () => {
|
|
|
24
24
|
"0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff",
|
|
25
25
|
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
26
26
|
"0x0000000000000000000000000000000000000000000000000000000000000003",
|
|
27
|
-
])
|
|
27
|
+
]),
|
|
28
28
|
).toStrictEqual([
|
|
29
29
|
42n,
|
|
30
30
|
-42,
|
package/src/decodeKeyTuple.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hex, decodeAbiParameters } from "viem";
|
|
2
|
-
import { StaticPrimitiveType } from "@latticexyz/schema-type";
|
|
2
|
+
import { StaticPrimitiveType } from "@latticexyz/schema-type/internal";
|
|
3
3
|
import { Schema } from "./common";
|
|
4
4
|
|
|
5
5
|
// key tuples are encoded in the same way as abi.encode, so we can decode them with viem
|
|
@@ -8,10 +8,10 @@ import { Schema } from "./common";
|
|
|
8
8
|
export function decodeKeyTuple(keySchema: Schema, keyTuple: readonly Hex[]): StaticPrimitiveType[] {
|
|
9
9
|
if (keySchema.staticFields.length !== keyTuple.length) {
|
|
10
10
|
throw new Error(
|
|
11
|
-
`key tuple length ${keyTuple.length} does not match key schema length ${keySchema.staticFields.length}
|
|
11
|
+
`key tuple length ${keyTuple.length} does not match key schema length ${keySchema.staticFields.length}`,
|
|
12
12
|
);
|
|
13
13
|
}
|
|
14
14
|
return keyTuple.map(
|
|
15
|
-
(key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType
|
|
15
|
+
(key, index) => decodeAbiParameters([{ type: keySchema.staticFields[index] }], key)[0] as StaticPrimitiveType,
|
|
16
16
|
);
|
|
17
17
|
}
|
package/src/decodeRecord.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ describe("decodeRecord", () => {
|
|
|
6
6
|
const valueSchema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
|
|
7
7
|
const values = decodeRecord(
|
|
8
8
|
valueSchema,
|
|
9
|
-
"0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67"
|
|
9
|
+
"0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67",
|
|
10
10
|
);
|
|
11
11
|
expect(values).toStrictEqual([1, 2n, [3, 4], "some string"]);
|
|
12
12
|
});
|
package/src/decodeRecord.ts
CHANGED
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
DynamicPrimitiveType,
|
|
4
4
|
staticAbiTypeToByteLength,
|
|
5
5
|
dynamicAbiTypeToDefaultValue,
|
|
6
|
-
} from "@latticexyz/schema-type";
|
|
6
|
+
} from "@latticexyz/schema-type/internal";
|
|
7
7
|
import { Hex } from "viem";
|
|
8
8
|
import { Schema } from "./common";
|
|
9
9
|
import { decodeDynamicField } from "./decodeDynamicField";
|
|
10
10
|
import { decodeStaticField } from "./decodeStaticField";
|
|
11
|
-
import {
|
|
11
|
+
import { hexToEncodedLengths } from "./hexToEncodedLengths";
|
|
12
12
|
import { staticDataLength } from "./staticDataLength";
|
|
13
13
|
import { readHex } from "@latticexyz/common";
|
|
14
14
|
|
|
@@ -34,12 +34,12 @@ export function decodeRecord(valueSchema: Schema, data: Hex): readonly (StaticPr
|
|
|
34
34
|
expectedLength: schemaStaticDataLength,
|
|
35
35
|
actualLength: actualStaticDataLength,
|
|
36
36
|
bytesOffset,
|
|
37
|
-
}
|
|
37
|
+
},
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (valueSchema.dynamicFields.length > 0) {
|
|
42
|
-
const dataLayout =
|
|
42
|
+
const dataLayout = hexToEncodedLengths(readHex(data, bytesOffset, bytesOffset + 32));
|
|
43
43
|
bytesOffset += 32;
|
|
44
44
|
|
|
45
45
|
valueSchema.dynamicFields.forEach((fieldType, i) => {
|
|
@@ -63,7 +63,7 @@ export function decodeRecord(valueSchema: Schema, data: Hex): readonly (StaticPr
|
|
|
63
63
|
expectedLength: dataLayout.totalByteLength,
|
|
64
64
|
actualLength: actualDynamicDataLength,
|
|
65
65
|
bytesOffset,
|
|
66
|
-
}
|
|
66
|
+
},
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -7,22 +7,22 @@ describe("decodeStaticField", () => {
|
|
|
7
7
|
expect(decodeStaticField("bool", "0x01")).toBe(true);
|
|
8
8
|
|
|
9
9
|
expect(() => decodeStaticField("bool", "0x0")).toThrow(
|
|
10
|
-
'Hex value "0x0" has length of 1, but expected length of 2 for bool type.'
|
|
10
|
+
'Hex value "0x0" has length of 1, but expected length of 2 for bool type.',
|
|
11
11
|
);
|
|
12
12
|
expect(() => decodeStaticField("bool", "0x1")).toThrow(
|
|
13
|
-
'Hex value "0x1" has length of 1, but expected length of 2 for bool type.'
|
|
13
|
+
'Hex value "0x1" has length of 1, but expected length of 2 for bool type.',
|
|
14
14
|
);
|
|
15
15
|
expect(() => decodeStaticField("bool", "0x000")).toThrow(
|
|
16
|
-
'Hex value "0x000" is an odd length (3). It must be an even length.'
|
|
16
|
+
'Hex value "0x000" is an odd length (3). It must be an even length.',
|
|
17
17
|
);
|
|
18
18
|
expect(() => decodeStaticField("bool", "0x001")).toThrow(
|
|
19
|
-
'Hex value "0x001" is an odd length (3). It must be an even length.'
|
|
19
|
+
'Hex value "0x001" is an odd length (3). It must be an even length.',
|
|
20
20
|
);
|
|
21
21
|
expect(() => decodeStaticField("bool", "0x0000")).toThrow(
|
|
22
|
-
'Hex value "0x0000" has length of 4, but expected length of 2 for bool type.'
|
|
22
|
+
'Hex value "0x0000" has length of 4, but expected length of 2 for bool type.',
|
|
23
23
|
);
|
|
24
24
|
expect(() => decodeStaticField("bool", "0x0001")).toThrow(
|
|
25
|
-
'Hex value "0x0001" has length of 4, but expected length of 2 for bool type.'
|
|
25
|
+
'Hex value "0x0001" has length of 4, but expected length of 2 for bool type.',
|
|
26
26
|
);
|
|
27
27
|
});
|
|
28
28
|
|
|
@@ -36,10 +36,10 @@ describe("decodeStaticField", () => {
|
|
|
36
36
|
expect(decodeStaticField("uint256", "0x0000000000000000000000000000000000000000000000000000000000000000")).toBe(0n);
|
|
37
37
|
expect(decodeStaticField("uint256", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(1n);
|
|
38
38
|
expect(decodeStaticField("uint256", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
39
|
-
115792089237316195423570985008687907853269984665640564039457584007913129639935n
|
|
39
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639935n,
|
|
40
40
|
);
|
|
41
41
|
expect(decodeStaticField("uint256", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")).toBe(
|
|
42
|
-
115792089237316195423570985008687907853269984665640564039457584007913129639934n
|
|
42
|
+
115792089237316195423570985008687907853269984665640564039457584007913129639934n,
|
|
43
43
|
);
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -56,13 +56,13 @@ describe("decodeStaticField", () => {
|
|
|
56
56
|
expect(decodeStaticField("int256", "0x0000000000000000000000000000000000000000000000000000000000000000")).toBe(0n);
|
|
57
57
|
expect(decodeStaticField("int256", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(1n);
|
|
58
58
|
expect(decodeStaticField("int256", "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
59
|
-
57896044618658097711785492504343953926634992332820282019728792003956564819967n
|
|
59
|
+
57896044618658097711785492504343953926634992332820282019728792003956564819967n,
|
|
60
60
|
);
|
|
61
61
|
expect(decodeStaticField("int256", "0x8000000000000000000000000000000000000000000000000000000000000000")).toBe(
|
|
62
|
-
-57896044618658097711785492504343953926634992332820282019728792003956564819968n
|
|
62
|
+
-57896044618658097711785492504343953926634992332820282019728792003956564819968n,
|
|
63
63
|
);
|
|
64
64
|
expect(decodeStaticField("int256", "0x8000000000000000000000000000000000000000000000000000000000000001")).toBe(
|
|
65
|
-
-57896044618658097711785492504343953926634992332820282019728792003956564819967n
|
|
65
|
+
-57896044618658097711785492504343953926634992332820282019728792003956564819967n,
|
|
66
66
|
);
|
|
67
67
|
expect(decodeStaticField("int256", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")).toBe(-1n);
|
|
68
68
|
});
|
|
@@ -72,23 +72,23 @@ describe("decodeStaticField", () => {
|
|
|
72
72
|
expect(decodeStaticField("bytes2", "0x0001")).toBe("0x0001");
|
|
73
73
|
expect(decodeStaticField("bytes8", "0xff00ff00ff00ff00")).toBe("0xff00ff00ff00ff00");
|
|
74
74
|
expect(decodeStaticField("bytes32", "0x0000000000000000000000000000000000000000000000000000000000000001")).toBe(
|
|
75
|
-
"0x0000000000000000000000000000000000000000000000000000000000000001"
|
|
75
|
+
"0x0000000000000000000000000000000000000000000000000000000000000001",
|
|
76
76
|
);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
it("can decode address", () => {
|
|
80
80
|
expect(decodeStaticField("address", "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266")).toBe(
|
|
81
|
-
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
|
81
|
+
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
82
82
|
);
|
|
83
83
|
expect(decodeStaticField("address", "0xffffffffffffffffffffffffffffffffffffffff")).toBe(
|
|
84
|
-
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF"
|
|
84
|
+
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF",
|
|
85
85
|
);
|
|
86
86
|
|
|
87
87
|
expect(() => decodeStaticField("address", "0x00")).toThrow(
|
|
88
|
-
'Hex value "0x00" has length of 2, but expected length of 40 for address type.'
|
|
88
|
+
'Hex value "0x00" has length of 2, but expected length of 40 for address type.',
|
|
89
89
|
);
|
|
90
90
|
expect(() => decodeStaticField("address", "0xffffffffffffffffffffffffffffffffffffffffff")).toThrow(
|
|
91
|
-
'Hex value "0xffffffffffffffffffffffffffffffffffffffffff" has length of 42, but expected length of 40 for address type.'
|
|
91
|
+
'Hex value "0xffffffffffffffffffffffffffffffffffffffffff" has length of 42, but expected length of 40 for address type.',
|
|
92
92
|
);
|
|
93
93
|
});
|
|
94
94
|
});
|
package/src/decodeStaticField.ts
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
StaticAbiTypeToPrimitiveType,
|
|
6
6
|
staticAbiTypeToByteLength,
|
|
7
7
|
staticAbiTypeToDefaultValue,
|
|
8
|
-
} from "@latticexyz/schema-type";
|
|
8
|
+
} from "@latticexyz/schema-type/internal";
|
|
9
9
|
import { InvalidHexLengthError, InvalidHexLengthForStaticFieldError } from "./errors";
|
|
10
10
|
|
|
11
11
|
export function decodeStaticField<
|
|
12
12
|
TAbiType extends StaticAbiType,
|
|
13
|
-
TPrimitiveType extends StaticAbiTypeToPrimitiveType<TAbiType
|
|
13
|
+
TPrimitiveType extends StaticAbiTypeToPrimitiveType<TAbiType>,
|
|
14
14
|
>(abiType: TAbiType, data: Hex): TPrimitiveType {
|
|
15
15
|
if (data.length > 3 && data.length % 2 !== 0) {
|
|
16
16
|
throw new InvalidHexLengthError(data);
|
package/src/decodeValue.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type";
|
|
1
|
+
import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type/internal";
|
|
2
2
|
import { Hex } from "viem";
|
|
3
3
|
import { SchemaToPrimitives, ValueSchema } from "./common";
|
|
4
4
|
import { decodeRecord } from "./decodeRecord";
|
|
@@ -11,6 +11,6 @@ export function decodeValue<TSchema extends ValueSchema>(valueSchema: TSchema, d
|
|
|
11
11
|
const valueTuple = decodeRecord({ staticFields, dynamicFields }, data);
|
|
12
12
|
|
|
13
13
|
return Object.fromEntries(
|
|
14
|
-
Object.keys(valueSchema).map((name, i) => [name, valueTuple[i]])
|
|
14
|
+
Object.keys(valueSchema).map((name, i) => [name, valueTuple[i]]),
|
|
15
15
|
) as SchemaToPrimitives<TSchema>;
|
|
16
16
|
}
|
package/src/decodeValueArgs.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { concatHex } from "viem";
|
|
2
|
-
import { isStaticAbiType } from "@latticexyz/schema-type";
|
|
2
|
+
import { isStaticAbiType } from "@latticexyz/schema-type/internal";
|
|
3
3
|
import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common";
|
|
4
4
|
import { decodeValue } from "./decodeValue";
|
|
5
5
|
import { staticDataLength } from "./staticDataLength";
|
|
@@ -7,7 +7,7 @@ import { readHex } from "@latticexyz/common";
|
|
|
7
7
|
|
|
8
8
|
export function decodeValueArgs<TSchema extends ValueSchema>(
|
|
9
9
|
valueSchema: TSchema,
|
|
10
|
-
{ staticData, encodedLengths, dynamicData }: ValueArgs
|
|
10
|
+
{ staticData, encodedLengths, dynamicData }: ValueArgs,
|
|
11
11
|
): SchemaToPrimitives<TSchema> {
|
|
12
12
|
return decodeValue(
|
|
13
13
|
valueSchema,
|
|
@@ -15,6 +15,6 @@ export function decodeValueArgs<TSchema extends ValueSchema>(
|
|
|
15
15
|
readHex(staticData, 0, staticDataLength(Object.values(valueSchema).filter(isStaticAbiType))),
|
|
16
16
|
encodedLengths,
|
|
17
17
|
dynamicData,
|
|
18
|
-
])
|
|
18
|
+
]),
|
|
19
19
|
);
|
|
20
20
|
}
|
package/src/encodeField.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { SchemaAbiType,
|
|
1
|
+
import { SchemaAbiType, arrayToStaticAbiType, isArrayAbiType } from "@latticexyz/schema-type/internal";
|
|
2
2
|
import { AbiParameterToPrimitiveType } from "abitype";
|
|
3
3
|
import { Hex, encodePacked } from "viem";
|
|
4
4
|
|
|
5
5
|
export function encodeField<TSchemaAbiType extends SchemaAbiType>(
|
|
6
6
|
fieldType: TSchemaAbiType,
|
|
7
|
-
value: AbiParameterToPrimitiveType<{ type: TSchemaAbiType }
|
|
7
|
+
value: AbiParameterToPrimitiveType<{ type: TSchemaAbiType }>,
|
|
8
8
|
): Hex {
|
|
9
9
|
if (isArrayAbiType(fieldType) && Array.isArray(value)) {
|
|
10
|
-
const staticFieldType =
|
|
10
|
+
const staticFieldType = arrayToStaticAbiType(fieldType);
|
|
11
11
|
// TODO: we can remove conditional once this is fixed: https://github.com/wagmi-dev/viem/pull/1147
|
|
12
12
|
return value.length === 0
|
|
13
13
|
? "0x"
|
|
14
14
|
: encodePacked(
|
|
15
15
|
value.map(() => staticFieldType),
|
|
16
|
-
value
|
|
16
|
+
value,
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
return encodePacked([fieldType], [value]);
|
package/src/encodeKey.ts
CHANGED
|
@@ -12,8 +12,8 @@ describe("encodeKeyTuple", () => {
|
|
|
12
12
|
staticFields: ["bool"],
|
|
13
13
|
dynamicFields: [],
|
|
14
14
|
},
|
|
15
|
-
[true]
|
|
16
|
-
)
|
|
15
|
+
[true],
|
|
16
|
+
),
|
|
17
17
|
).toStrictEqual(["0x0000000000000000000000000000000000000000000000000000000000000001"]);
|
|
18
18
|
});
|
|
19
19
|
|
|
@@ -26,7 +26,7 @@ describe("encodeKeyTuple", () => {
|
|
|
26
26
|
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF",
|
|
27
27
|
true,
|
|
28
28
|
3,
|
|
29
|
-
])
|
|
29
|
+
]),
|
|
30
30
|
).toStrictEqual([
|
|
31
31
|
"0x000000000000000000000000000000000000000000000000000000000000002a",
|
|
32
32
|
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd6",
|
package/src/encodeKeyTuple.ts
CHANGED
|
@@ -2,9 +2,15 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { encodeLengths } from "./encodeLengths";
|
|
3
3
|
|
|
4
4
|
describe("encodeLengths", () => {
|
|
5
|
+
it("can encode empty tuple", () => {
|
|
6
|
+
expect(encodeLengths([])).toMatchInlineSnapshot(
|
|
7
|
+
'"0x0000000000000000000000000000000000000000000000000000000000000000"',
|
|
8
|
+
);
|
|
9
|
+
});
|
|
10
|
+
|
|
5
11
|
it("can encode bool key tuple", () => {
|
|
6
12
|
expect(encodeLengths(["0x1234", "0x12345678"])).toMatchInlineSnapshot(
|
|
7
|
-
'"0x0000000000000000000000000000000000000004000000000200000000000006"'
|
|
13
|
+
'"0x0000000000000000000000000000000000000004000000000200000000000006"',
|
|
8
14
|
);
|
|
9
15
|
});
|
|
10
16
|
});
|
package/src/encodeLengths.ts
CHANGED
package/src/encodeRecord.test.ts
CHANGED
|
@@ -6,7 +6,7 @@ describe("encodeRecord", () => {
|
|
|
6
6
|
const valueSchema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const;
|
|
7
7
|
const hex = encodeRecord(valueSchema, [1, 2n, [3, 4], "some string"]);
|
|
8
8
|
expect(hex).toBe(
|
|
9
|
-
"0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67"
|
|
9
|
+
"0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67",
|
|
10
10
|
);
|
|
11
11
|
});
|
|
12
12
|
|
package/src/encodeRecord.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StaticPrimitiveType, DynamicPrimitiveType } from "@latticexyz/schema-type";
|
|
1
|
+
import { StaticPrimitiveType, DynamicPrimitiveType } from "@latticexyz/schema-type/internal";
|
|
2
2
|
import { Hex } from "viem";
|
|
3
3
|
import { encodeField } from "./encodeField";
|
|
4
4
|
import { Schema } from "./common";
|
|
@@ -6,7 +6,7 @@ import { Schema } from "./common";
|
|
|
6
6
|
/** @deprecated use `encodeValue` instead */
|
|
7
7
|
export function encodeRecord(
|
|
8
8
|
valueSchema: Schema,
|
|
9
|
-
values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]
|
|
9
|
+
values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[],
|
|
10
10
|
): Hex {
|
|
11
11
|
const staticValues = values.slice(0, valueSchema.staticFields.length) as readonly StaticPrimitiveType[];
|
|
12
12
|
const dynamicValues = values.slice(valueSchema.staticFields.length) as readonly DynamicPrimitiveType[];
|
|
@@ -18,7 +18,7 @@ export function encodeRecord(
|
|
|
18
18
|
if (valueSchema.dynamicFields.length === 0) return `0x${staticData}`;
|
|
19
19
|
|
|
20
20
|
const dynamicDataItems = dynamicValues.map((value, i) =>
|
|
21
|
-
encodeField(valueSchema.dynamicFields[i], value).replace(/^0x/, "")
|
|
21
|
+
encodeField(valueSchema.dynamicFields[i], value).replace(/^0x/, ""),
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2).reverse();
|
|
@@ -26,9 +26,9 @@ export function encodeRecord(
|
|
|
26
26
|
|
|
27
27
|
const dynamicData = dynamicDataItems.join("");
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const encodedLengths = `${dynamicFieldByteLengths
|
|
30
30
|
.map((length) => encodeField("uint40", length).replace(/^0x/, ""))
|
|
31
31
|
.join("")}${encodeField("uint56", dynamicTotalByteLength).replace(/^0x/, "")}`.padStart(64, "0");
|
|
32
32
|
|
|
33
|
-
return `0x${staticData}${
|
|
33
|
+
return `0x${staticData}${encodedLengths}${dynamicData}`;
|
|
34
34
|
}
|
package/src/encodeValue.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { encodeValueArgs } from "./encodeValueArgs";
|
|
|
4
4
|
|
|
5
5
|
export function encodeValue<TSchema extends ValueSchema>(
|
|
6
6
|
valueSchema: TSchema,
|
|
7
|
-
value: SchemaToPrimitives<TSchema
|
|
7
|
+
value: SchemaToPrimitives<TSchema>,
|
|
8
8
|
): Hex {
|
|
9
9
|
const { staticData, encodedLengths, dynamicData } = encodeValueArgs(valueSchema, value);
|
|
10
10
|
return concatHex([staticData, encodedLengths, dynamicData]);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { encodeValueArgs } from "./encodeValueArgs";
|
|
3
|
+
import { stringToHex } from "viem";
|
|
4
|
+
|
|
5
|
+
describe("encodeValueArgs", () => {
|
|
6
|
+
it("can encode record value to hex", () => {
|
|
7
|
+
const valueSchema = {
|
|
8
|
+
entityId: "bytes32",
|
|
9
|
+
exists: "bool",
|
|
10
|
+
playerName: "string",
|
|
11
|
+
badges: "uint256[]",
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
const result = encodeValueArgs(valueSchema, {
|
|
15
|
+
entityId: stringToHex("hello", { size: 32 }),
|
|
16
|
+
exists: true,
|
|
17
|
+
playerName: "henry",
|
|
18
|
+
badges: [42n],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
expect(result).toMatchInlineSnapshot(`
|
|
22
|
+
{
|
|
23
|
+
"dynamicData": "0x68656e7279000000000000000000000000000000000000000000000000000000000000002a",
|
|
24
|
+
"encodedLengths": "0x0000000000000000000000000000000000000020000000000500000000000025",
|
|
25
|
+
"staticData": "0x68656c6c6f00000000000000000000000000000000000000000000000000000001",
|
|
26
|
+
}
|
|
27
|
+
`);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("encodes record when key order of value and valueSchema do not match", () => {
|
|
31
|
+
const valueSchema = {
|
|
32
|
+
entityId: "bytes32",
|
|
33
|
+
playerName: "string",
|
|
34
|
+
exists: "bool",
|
|
35
|
+
badges: "uint256[]",
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
const result = encodeValueArgs(valueSchema, {
|
|
39
|
+
exists: true,
|
|
40
|
+
playerName: "henry",
|
|
41
|
+
entityId: stringToHex("hello", { size: 32 }),
|
|
42
|
+
badges: [42n],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
expect(result).toMatchInlineSnapshot(`
|
|
46
|
+
{
|
|
47
|
+
"dynamicData": "0x68656e7279000000000000000000000000000000000000000000000000000000000000002a",
|
|
48
|
+
"encodedLengths": "0x0000000000000000000000000000000000000020000000000500000000000025",
|
|
49
|
+
"staticData": "0x68656c6c6f00000000000000000000000000000000000000000000000000000001",
|
|
50
|
+
}
|
|
51
|
+
`);
|
|
52
|
+
});
|
|
53
|
+
});
|