solidity-scale-codec 0.1.3 → 0.2.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/DEFINITIONS.md +132 -0
  3. package/README.md +95 -1
  4. package/package.json +8 -3
  5. package/src/LittleEndian/LittleEndianU128.sol +4 -2
  6. package/src/LittleEndian/LittleEndianU16.sol +2 -2
  7. package/src/LittleEndian/LittleEndianU256.sol +4 -2
  8. package/src/LittleEndian/LittleEndianU32.sol +4 -2
  9. package/src/LittleEndian/LittleEndianU64.sol +4 -2
  10. package/src/LittleEndian/LittleEndianU8.sol +2 -2
  11. package/src/Scale/Address/Address.sol +55 -0
  12. package/src/Scale/Address.sol +4 -0
  13. package/src/Scale/Array/BoolArr.sol +16 -2
  14. package/src/Scale/Array/I128Arr.sol +16 -2
  15. package/src/Scale/Array/I16Arr.sol +16 -2
  16. package/src/Scale/Array/I256Arr.sol +16 -2
  17. package/src/Scale/Array/I32Arr.sol +16 -2
  18. package/src/Scale/Array/I64Arr.sol +16 -2
  19. package/src/Scale/Array/I8Arr.sol +16 -2
  20. package/src/Scale/Array/U128Arr.sol +16 -2
  21. package/src/Scale/Array/U16Arr.sol +16 -2
  22. package/src/Scale/Array/U256Arr.sol +16 -2
  23. package/src/Scale/Array/U32Arr.sol +16 -2
  24. package/src/Scale/Array/U64Arr.sol +16 -2
  25. package/src/Scale/Array/U8Arr.sol +16 -2
  26. package/src/Scale/Bool/Bool.sol +12 -0
  27. package/src/Scale/Bytes/Bytes.sol +63 -0
  28. package/src/Scale/Bytes/Bytes16.sol +53 -0
  29. package/src/Scale/Bytes/Bytes2.sol +53 -0
  30. package/src/Scale/Bytes/Bytes32.sol +53 -0
  31. package/src/Scale/Bytes/Bytes4.sol +53 -0
  32. package/src/Scale/Bytes/Bytes8.sol +53 -0
  33. package/src/Scale/Bytes.sol +8 -0
  34. package/src/Scale/Compact/Compact.sol +37 -3
  35. package/src/Scale/Signed/I128.sol +11 -0
  36. package/src/Scale/Signed/I16.sol +11 -0
  37. package/src/Scale/Signed/I256.sol +11 -0
  38. package/src/Scale/Signed/I32.sol +11 -0
  39. package/src/Scale/Signed/I64.sol +11 -0
  40. package/src/Scale/Signed/I8.sol +11 -0
  41. package/src/Scale/Unsigned/U128.sol +16 -2
  42. package/src/Scale/Unsigned/U16.sol +16 -2
  43. package/src/Scale/Unsigned/U256.sol +16 -2
  44. package/src/Scale/Unsigned/U32.sol +16 -2
  45. package/src/Scale/Unsigned/U64.sol +16 -2
  46. package/src/Scale/Unsigned/U8.sol +16 -2
  47. package/src/Xcm/Types/Version.sol +5 -0
  48. package/src/Xcm/VersionedXcm/VersionedXcm.sol +27 -0
  49. package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +70 -0
  50. package/src/Xcm/v3/Constants.sol +5 -0
  51. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +73 -0
  52. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +94 -0
  53. package/src/Xcm/v5/Asset/Asset.sol +13 -0
  54. package/src/Xcm/v5/Asset/AssetCodec.sol +72 -0
  55. package/src/Xcm/v5/AssetFilter/AssetFilter.sol +61 -0
  56. package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +105 -0
  57. package/src/Xcm/v5/AssetId/AssetId.sol +10 -0
  58. package/src/Xcm/v5/AssetId/AssetIdCodec.sol +57 -0
  59. package/src/Xcm/v5/AssetInstance/AssetInstance.sol +139 -0
  60. package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +174 -0
  61. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +82 -0
  62. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +95 -0
  63. package/src/Xcm/v5/Assets/Assets.sol +14 -0
  64. package/src/Xcm/v5/Assets/AssetsCodec.sol +94 -0
  65. package/src/Xcm/v5/BodyId/BodyId.sol +121 -0
  66. package/src/Xcm/v5/BodyId/BodyIdCodec.sol +128 -0
  67. package/src/Xcm/v5/BodyPart/BodyPart.sol +105 -0
  68. package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +134 -0
  69. package/src/Xcm/v5/Constants.sol +15 -0
  70. package/src/Xcm/v5/Fungibility/Fungibility.sol +60 -0
  71. package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +128 -0
  72. package/src/Xcm/v5/Hint/Hint.sol +40 -0
  73. package/src/Xcm/v5/Hint/HintCodec.sol +82 -0
  74. package/src/Xcm/v5/Instruction/Instruction.sol +1217 -0
  75. package/src/Xcm/v5/Instruction/InstructionCodec.sol +321 -0
  76. package/src/Xcm/v5/Junction/Junction.sol +258 -0
  77. package/src/Xcm/v5/Junction/JunctionCodec.sol +329 -0
  78. package/src/Xcm/v5/Junctions/Junctions.sol +12 -0
  79. package/src/Xcm/v5/Junctions/JunctionsCodec.sol +120 -0
  80. package/src/Xcm/v5/Location/Location.sol +12 -0
  81. package/src/Xcm/v5/Location/LocationCodec.sol +68 -0
  82. package/src/Xcm/v5/NetworkId/NetworkId.sol +115 -0
  83. package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +114 -0
  84. package/src/Xcm/v5/OriginKind/OriginKind.sol +14 -0
  85. package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +66 -0
  86. package/src/Xcm/v5/PalletInfo/PalletInfo.sol +18 -0
  87. package/src/Xcm/v5/PalletInfo/PalletInfoCodec.sol +119 -0
  88. package/src/Xcm/v5/QueryResponseInfo/QueryResponseInfo.sol +16 -0
  89. package/src/Xcm/v5/QueryResponseInfo/QueryResponseInfoCodec.sol +91 -0
  90. package/src/Xcm/v5/Response/Response.sol +145 -0
  91. package/src/Xcm/v5/Response/ResponseCodec.sol +174 -0
  92. package/src/Xcm/v5/Types/QueryId.sol +5 -0
  93. package/src/Xcm/v5/Weight/Weight.sol +10 -0
  94. package/src/Xcm/v5/Weight/WeightCodec.sol +87 -0
  95. package/src/Xcm/v5/WeightLimit/WeightLimit.sol +48 -0
  96. package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +88 -0
  97. package/src/Xcm/v5/WildAsset/WildAsset.sol +112 -0
  98. package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +166 -0
  99. package/src/Xcm/v5/WildFungibility/WildFungibility.sol +10 -0
  100. package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +74 -0
  101. package/src/Xcm/v5/Xcm/Xcm.sol +27 -0
  102. package/src/Xcm/v5/Xcm/XcmCodec.sol +83 -0
  103. package/src/Xcm/v5/XcmError/XcmError.sol +122 -0
  104. package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +85 -0
@@ -0,0 +1,8 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ import {Bytes2} from "./Bytes/Bytes2.sol";
5
+ import {Bytes4} from "./Bytes/Bytes4.sol";
6
+ import {Bytes8} from "./Bytes/Bytes8.sol";
7
+ import {Bytes16} from "./Bytes/Bytes16.sol";
8
+ import {Bytes32} from "./Bytes/Bytes32.sol";
@@ -43,6 +43,35 @@ library Compact {
43
43
  }
44
44
  }
45
45
 
46
+ /// @notice Returns the number of bytes that the Compact-encoded value at the given offset occupies
47
+ /// @param data The byte sequence containing the Compact-encoded value
48
+ /// @param offset The byte offset to start reading from
49
+ /// @return size The total number of bytes occupied by the Compact-encoded value, including the header byte
50
+ /// @dev Reverts if the offset is out of bounds or if the header byte indicates an invalid encoding mode
51
+ function encodedSizeAt(
52
+ bytes memory data,
53
+ uint256 offset
54
+ ) internal pure returns (uint256 size) {
55
+ if (offset >= data.length) revert OffsetOutOfBounds();
56
+ uint8 header;
57
+ assembly {
58
+ header := shr(248, mload(add(add(data, 32), offset)))
59
+ }
60
+ uint8 mode = header & 0x03;
61
+ if (mode == MODE_SINGLE) {
62
+ size = 1;
63
+ } else if (mode == MODE_TWO) {
64
+ size = 2;
65
+ } else if (mode == MODE_FOUR) {
66
+ size = 4;
67
+ } else {
68
+ uint8 m = (header >> 2) + 4;
69
+ size = 1 + m;
70
+ }
71
+
72
+ if (data.length < offset + size) revert OffsetOutOfBounds();
73
+ }
74
+
46
75
  ///@notice Decodes a uint256 value from SCALE Compact format
47
76
  /// @dev Reverts if the encoding is invalid or non-canonical, or if the decoded value exceeds uint256 range
48
77
  /// @param data The Compact-encoded byte sequence
@@ -74,15 +103,20 @@ library Compact {
74
103
  value = uint256(header) >> 2;
75
104
  bytesRead = 1;
76
105
  } else if (mode == MODE_TWO) {
77
- value = uint256(LittleEndianU16.fromLE(data, offset)) >> 2;
106
+ if (data.length < offset + 2) revert OffsetOutOfBounds();
107
+ value =
108
+ uint256(LittleEndianU16.fromLittleEndian(data, offset)) >> 2;
78
109
  bytesRead = 2;
79
110
  } else if (mode == MODE_FOUR) {
80
- value = uint256(LittleEndianU32.fromLE(data, offset)) >> 2;
111
+ if (data.length < offset + 4) revert OffsetOutOfBounds();
112
+ value =
113
+ uint256(LittleEndianU32.fromLittleEndian(data, offset)) >> 2;
81
114
  bytesRead = 4;
82
115
  } else {
83
116
  uint8 m = (header >> 2) + 4;
84
117
  if (m > 32) revert ValueOutOfRange();
85
- value = LittleEndianU256.fromLE(data, offset + 1);
118
+ if (data.length < offset + 1 + m) revert OffsetOutOfBounds();
119
+ value = LittleEndianU256.fromLittleEndian(data, offset + 1);
86
120
  if (m < 32) {
87
121
  value &= (uint256(1) << (uint256(m) * 8)) - 1; // zero out bytes beyond m
88
122
  }
@@ -16,6 +16,17 @@ library I128 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int128` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int128`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int128`.
22
+ /// @return The number of bytes that the `int128` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U128.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int128`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int128`.
@@ -16,6 +16,17 @@ library I16 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int16` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int16`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int16`.
22
+ /// @return The number of bytes that the `int16` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U16.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int16`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int16`.
@@ -16,6 +16,17 @@ library I256 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int256` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int256`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int256`.
22
+ /// @return The number of bytes that the `int256` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U256.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int256`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int256`.
@@ -16,6 +16,17 @@ library I32 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int32` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int32`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int32`.
22
+ /// @return The number of bytes that the `int32` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U32.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int32`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int32`.
@@ -16,6 +16,17 @@ library I64 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int64` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int64`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int64`.
22
+ /// @return The number of bytes that the `int64` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U64.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int64`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int64`.
@@ -16,6 +16,17 @@ library I8 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `int8` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `int8`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `int8`.
22
+ /// @return The number of bytes that the `int8` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ return U8.encodedSizeAt(data, offset);
28
+ }
29
+
19
30
  /// @notice Decodes SCALE-encoded bytes into an `int8`.
20
31
  /// @param data The SCALE-encoded byte sequence.
21
32
  /// @return The decoded `int8`.
@@ -16,6 +16,20 @@ library U128 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint128` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint128`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint128`.
22
+ /// @return The number of bytes that the `uint128` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 16) {
28
+ revert InvalidU128Length();
29
+ }
30
+ return 16;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint128`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint128`.
@@ -32,7 +46,7 @@ library U128 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint128 value) {
34
48
  if (data.length < offset + 16) revert InvalidU128Length();
35
- return LittleEndianU128.fromLE(data, offset);
49
+ return LittleEndianU128.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint128` to little-endian bytes16
@@ -41,6 +55,6 @@ library U128 {
41
55
  function toLittleEndian(
42
56
  uint128 value
43
57
  ) internal pure returns (bytes16 result) {
44
- return LittleEndianU128.toLE(value);
58
+ return LittleEndianU128.toLittleEndian(value);
45
59
  }
46
60
  }
@@ -16,6 +16,20 @@ library U16 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint16` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint16`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint16`.
22
+ /// @return The number of bytes that the `uint16` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 2) {
28
+ revert InvalidU16Length();
29
+ }
30
+ return 2;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint16`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint16`.
@@ -32,7 +46,7 @@ library U16 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint16 value) {
34
48
  if (data.length < offset + 2) revert InvalidU16Length();
35
- return LittleEndianU16.fromLE(data, offset);
49
+ return LittleEndianU16.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint16` to little-endian bytes2
@@ -41,6 +55,6 @@ library U16 {
41
55
  function toLittleEndian(
42
56
  uint16 value
43
57
  ) internal pure returns (bytes2 result) {
44
- return LittleEndianU16.toLE(value);
58
+ return LittleEndianU16.toLittleEndian(value);
45
59
  }
46
60
  }
@@ -16,6 +16,20 @@ library U256 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint256` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint256`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint256`.
22
+ /// @return The number of bytes that the `uint256` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 32) {
28
+ revert InvalidU256Length();
29
+ }
30
+ return 32;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint256`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint256`.
@@ -32,7 +46,7 @@ library U256 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint256 value) {
34
48
  if (data.length < offset + 32) revert InvalidU256Length();
35
- return LittleEndianU256.fromLE(data, offset);
49
+ return LittleEndianU256.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint256` to little-endian bytes32
@@ -41,6 +55,6 @@ library U256 {
41
55
  function toLittleEndian(
42
56
  uint256 value
43
57
  ) internal pure returns (bytes32 result) {
44
- return LittleEndianU256.toLE(value);
58
+ return LittleEndianU256.toLittleEndian(value);
45
59
  }
46
60
  }
@@ -16,6 +16,20 @@ library U32 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint32` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint32`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint32`.
22
+ /// @return The number of bytes that the `uint32` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 4) {
28
+ revert InvalidU32Length();
29
+ }
30
+ return 4;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint32`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint32`.
@@ -32,7 +46,7 @@ library U32 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint32 value) {
34
48
  if (data.length < offset + 4) revert InvalidU32Length();
35
- return LittleEndianU32.fromLE(data, offset);
49
+ return LittleEndianU32.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint32` to little-endian bytes4
@@ -41,6 +55,6 @@ library U32 {
41
55
  function toLittleEndian(
42
56
  uint32 value
43
57
  ) internal pure returns (bytes4 result) {
44
- return LittleEndianU32.toLE(value);
58
+ return LittleEndianU32.toLittleEndian(value);
45
59
  }
46
60
  }
@@ -16,6 +16,20 @@ library U64 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint64` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint64`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint64`.
22
+ /// @return The number of bytes that the `uint64` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 8) {
28
+ revert InvalidU64Length();
29
+ }
30
+ return 8;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint64`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint64`.
@@ -32,7 +46,7 @@ library U64 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint64 value) {
34
48
  if (data.length < offset + 8) revert InvalidU64Length();
35
- return LittleEndianU64.fromLE(data, offset);
49
+ return LittleEndianU64.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint64` to little-endian bytes8
@@ -41,6 +55,6 @@ library U64 {
41
55
  function toLittleEndian(
42
56
  uint64 value
43
57
  ) internal pure returns (bytes8 result) {
44
- return LittleEndianU64.toLE(value);
58
+ return LittleEndianU64.toLittleEndian(value);
45
59
  }
46
60
  }
@@ -16,6 +16,20 @@ library U8 {
16
16
  return abi.encodePacked(toLittleEndian(value));
17
17
  }
18
18
 
19
+ /// @notice Returns the number of bytes that a `uint8` would occupy when SCALE-encoded.
20
+ /// @param data The byte sequence containing the encoded `uint8`.
21
+ /// @param offset The starting index in `data` from which to calculate the encoded size of the `uint8`.
22
+ /// @return The number of bytes that the `uint8` would occupy when SCALE-encoded.
23
+ function encodedSizeAt(
24
+ bytes memory data,
25
+ uint256 offset
26
+ ) internal pure returns (uint256) {
27
+ if (data.length < offset + 1) {
28
+ revert InvalidU8Length();
29
+ }
30
+ return 1;
31
+ }
32
+
19
33
  /// @notice Decodes SCALE-encoded bytes into an `uint8`.
20
34
  /// @param data The SCALE-encoded byte sequence.
21
35
  /// @return The decoded `uint8`.
@@ -32,13 +46,13 @@ library U8 {
32
46
  uint256 offset
33
47
  ) internal pure returns (uint8 value) {
34
48
  if (data.length < offset + 1) revert InvalidU8Length();
35
- return LittleEndianU8.fromLE(data, offset);
49
+ return LittleEndianU8.fromLittleEndian(data, offset);
36
50
  }
37
51
 
38
52
  /// @notice Converts an `uint8` to little-endian bytes1
39
53
  /// @param value The unsigned 8-bit integer to convert.
40
54
  /// @return result Little-endian byte representation of the input value.
41
55
  function toLittleEndian(uint8 value) internal pure returns (bytes1 result) {
42
- return LittleEndianU8.toLE(value);
56
+ return LittleEndianU8.toLittleEndian(value);
43
57
  }
44
58
  }
@@ -0,0 +1,5 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ /// @notice A version of XCM.
5
+ type Version is uint32;
@@ -0,0 +1,27 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ import {Xcm as XcmV5} from "../v5/Xcm/Xcm.sol";
5
+ import {XcmCodec as XcmV5Codec} from "../v5/Xcm/XcmCodec.sol";
6
+
7
+ /// @notice The XCM versions supported by this package.
8
+ enum XcmVersion {
9
+ _unsupported_V2,
10
+ _unsupported_V3,
11
+ V5
12
+ }
13
+
14
+ /// @notice A single XCM message, together with its version code.
15
+ struct VersionedXcm {
16
+ /// @custom:property The version of the XCM message.
17
+ XcmVersion version;
18
+ /// @custom:property The XCM message, encoded according to its version.
19
+ bytes xcm;
20
+ }
21
+
22
+ /// @notice Creates a `VersionedXcm` with version `V5` from an `XcmV5` struct.
23
+ /// @param xcm The `XcmV5` struct to wrap.
24
+ /// @return A `VersionedXcm` with version `V5` and the ABI-encoded `xcm` as its payload.
25
+ function v5(XcmV5 memory xcm) pure returns (VersionedXcm memory) {
26
+ return VersionedXcm({version: XcmVersion.V5, xcm: XcmV5Codec.encode(xcm)});
27
+ }
@@ -0,0 +1,70 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ import {VersionedXcm, XcmVersion} from "./VersionedXcm.sol";
5
+ import {Xcm as XcmV5} from "../v5/Xcm/Xcm.sol";
6
+ import {XcmCodec as XcmV5Codec} from "../v5/Xcm/XcmCodec.sol";
7
+
8
+ library VersionedXcmCodec {
9
+ error InvalidVersionedXcmLength();
10
+ error UnsupportedXcmVersion(XcmVersion version);
11
+
12
+ /// @notice Encodes a `VersionedXcm` into bytes, using the appropriate encoding for its version.
13
+ /// @param versionedXcm The `VersionedXcm` to encode.
14
+ /// @return The encoded bytes of the `VersionedXcm`.
15
+ function encode(
16
+ VersionedXcm memory versionedXcm
17
+ ) internal pure returns (bytes memory) {
18
+ if (versionedXcm.version == XcmVersion.V5) {
19
+ return
20
+ abi.encodePacked(uint8(versionedXcm.version), versionedXcm.xcm);
21
+ } else {
22
+ revert UnsupportedXcmVersion(versionedXcm.version);
23
+ }
24
+ }
25
+
26
+ /// @notice Decodes a `VersionedXcm` from bytes, using the appropriate decoding for its version.
27
+ /// @param data The byte sequence containing the encoded `VersionedXcm`.
28
+ /// @return versionedXcm The decoded `VersionedXcm` struct.
29
+ /// @return bytesRead The number of bytes read from `data` to decode the `VersionedXcm`.
30
+ function decode(
31
+ bytes memory data
32
+ )
33
+ internal
34
+ pure
35
+ returns (VersionedXcm memory versionedXcm, uint256 bytesRead)
36
+ {
37
+ return decodeAt(data, 0);
38
+ }
39
+
40
+ /// @notice Decodes a `VersionedXcm` from bytes starting at a given offset, using the appropriate decoding for its version.
41
+ /// @param data The byte sequence containing the encoded `VersionedXcm`.
42
+ /// @param offset The starting index in `data` from which to decode the `VersionedXcm`.
43
+ /// @return versionedXcm The decoded `VersionedXcm` struct.
44
+ /// @return bytesRead The number of bytes read from `data` to decode the `VersionedXcm`.
45
+ function decodeAt(
46
+ bytes memory data,
47
+ uint256 offset
48
+ )
49
+ internal
50
+ pure
51
+ returns (VersionedXcm memory versionedXcm, uint256 bytesRead)
52
+ {
53
+ if (data.length < offset + 1) revert InvalidVersionedXcmLength();
54
+ XcmVersion version = XcmVersion(uint8(data[offset]));
55
+ uint256 xcmByteLength;
56
+ bytes memory xcmBytes;
57
+ if (version == XcmVersion.V5) {
58
+ xcmByteLength = XcmV5Codec.encodedSizeAt(data, offset + 1);
59
+ if (data.length < offset + 1 + xcmByteLength)
60
+ revert InvalidVersionedXcmLength();
61
+ xcmBytes = new bytes(xcmByteLength);
62
+ for (uint256 i = 0; i < xcmByteLength; i++)
63
+ xcmBytes[i] = data[offset + 1 + i];
64
+ versionedXcm = VersionedXcm({version: version, xcm: xcmBytes});
65
+ bytesRead = 1 + xcmByteLength;
66
+ } else {
67
+ revert UnsupportedXcmVersion(version);
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,5 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ // Maximum size of the encoded error code coming from a `Dispatch` result, used for `MaybeErrorCode`.
5
+ uint32 constant MAX_DISPATCH_ERROR_LEN = 128;
@@ -0,0 +1,73 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.28;
3
+
4
+ import {U8Arr} from "../../../Scale/Array.sol";
5
+ import {MAX_DISPATCH_ERROR_LEN} from "../Constants.sol";
6
+
7
+ /// @notice Discriminant for the `MaybeErrorCode` enum.
8
+ enum MaybeErrorCodeType {
9
+ /// @custom:variant No error occurred.
10
+ Success,
11
+ /// @custom:variant An error occurred, containing the dispatch error bytes.
12
+ Error,
13
+ /// @custom:variant An error occurred but the error code was truncated to MAX_DISPATCH_ERROR_LEN bytes.
14
+ TruncatedError
15
+ }
16
+
17
+ /// @notice The result of a `Transact` dispatch, either success or an error code.
18
+ struct MaybeErrorCode {
19
+ /// @custom:property The type of the result. See `MaybeErrorCodeType` enum for possible values.
20
+ MaybeErrorCodeType meType;
21
+ /// @custom:property The SCALE-encoded dispatch error bytes. Only meaningful when `meType` is `Error` or `TruncatedError`. Max length is MAX_DISPATCH_ERROR_LEN (128 bytes).
22
+ bytes payload;
23
+ }
24
+
25
+ /// @notice Parameters for the `Error` variant.
26
+ struct ErrorParams {
27
+ /// @custom:property Dispatch error bytes.
28
+ uint8[] errorBytes;
29
+ }
30
+
31
+ /// @notice Parameters for the `TruncatedError` variant.
32
+ struct TruncatedErrorParams {
33
+ /// @custom:property Truncated dispatch error bytes.
34
+ uint8[] errorBytes;
35
+ }
36
+
37
+ // ============ Factory Functions ============
38
+
39
+ /// @notice Creates a `Success` MaybeErrorCode.
40
+ /// @return A `MaybeErrorCode` struct representing success.
41
+ function success() pure returns (MaybeErrorCode memory) {
42
+ return MaybeErrorCode({meType: MaybeErrorCodeType.Success, payload: ""});
43
+ }
44
+
45
+ /// @notice Creates an `Error` MaybeErrorCode with the given dispatch error bytes.
46
+ /// @param params Parameters for the error variant.
47
+ /// @return A `MaybeErrorCode` struct representing the error.
48
+ function error(ErrorParams memory params) pure returns (MaybeErrorCode memory) {
49
+ if (params.errorBytes.length > MAX_DISPATCH_ERROR_LEN)
50
+ revert MaybeErrorCodeTooLong(params.errorBytes.length);
51
+ return
52
+ MaybeErrorCode({
53
+ meType: MaybeErrorCodeType.Error,
54
+ payload: U8Arr.encode(params.errorBytes)
55
+ });
56
+ }
57
+
58
+ /// @notice Creates a `TruncatedError` MaybeErrorCode with the given dispatch error bytes.
59
+ /// @param params Parameters for the truncated-error variant.
60
+ /// @return A `MaybeErrorCode` struct representing the truncated error.
61
+ function truncatedError(
62
+ TruncatedErrorParams memory params
63
+ ) pure returns (MaybeErrorCode memory) {
64
+ if (params.errorBytes.length > MAX_DISPATCH_ERROR_LEN)
65
+ revert MaybeErrorCodeTooLong(params.errorBytes.length);
66
+ return
67
+ MaybeErrorCode({
68
+ meType: MaybeErrorCodeType.TruncatedError,
69
+ payload: U8Arr.encode(params.errorBytes)
70
+ });
71
+ }
72
+
73
+ error MaybeErrorCodeTooLong(uint256 length);