solidity-scale-codec 0.3.4 → 1.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +31 -3
  2. package/package.json +1 -1
  3. package/src/Utils/BytesUtils.sol +26 -0
  4. package/src/Utils/UnsignedUtils.sol +52 -0
  5. package/src/Xcm/VersionedXcm/VersionedXcm.sol +4 -1
  6. package/src/Xcm/VersionedXcm/VersionedXcmCodec.sol +11 -0
  7. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCode.sol +8 -7
  8. package/src/Xcm/v3/MaybeErrorCode/MaybeErrorCodeCodec.sol +18 -19
  9. package/src/Xcm/v5/AssetFilter/AssetFilter.sol +8 -8
  10. package/src/Xcm/v5/AssetFilter/AssetFilterCodec.sol +47 -34
  11. package/src/Xcm/v5/AssetInstance/AssetInstance.sol +13 -12
  12. package/src/Xcm/v5/AssetInstance/AssetInstanceCodec.sol +53 -56
  13. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilter.sol +12 -12
  14. package/src/Xcm/v5/AssetTransferFilter/AssetTransferFilterCodec.sol +48 -20
  15. package/src/Xcm/v5/Assets/Assets.sol +16 -0
  16. package/src/Xcm/v5/Assets/AssetsCodec.sol +3 -3
  17. package/src/Xcm/v5/BodyId/BodyId.sol +24 -24
  18. package/src/Xcm/v5/BodyId/BodyIdCodec.sol +41 -48
  19. package/src/Xcm/v5/BodyPart/BodyPart.sol +44 -28
  20. package/src/Xcm/v5/BodyPart/BodyPartCodec.sol +70 -37
  21. package/src/Xcm/v5/Constants.sol +2 -2
  22. package/src/Xcm/v5/Fungibility/Fungibility.sol +6 -6
  23. package/src/Xcm/v5/Fungibility/FungibilityCodec.sol +40 -36
  24. package/src/Xcm/v5/Hint/Hint.sol +5 -5
  25. package/src/Xcm/v5/Hint/HintCodec.sol +24 -20
  26. package/src/Xcm/v5/Instruction/Instruction.sol +81 -55
  27. package/src/Xcm/v5/Instruction/InstructionCodec.sol +1047 -73
  28. package/src/Xcm/v5/Junction/Junction.sol +55 -69
  29. package/src/Xcm/v5/Junction/JunctionCodec.sol +72 -135
  30. package/src/Xcm/v5/Junctions/Junctions.sol +34 -0
  31. package/src/Xcm/v5/Junctions/JunctionsCodec.sol +0 -18
  32. package/src/Xcm/v5/Location/Location.sol +8 -0
  33. package/src/Xcm/v5/NetworkId/NetworkId.sol +15 -16
  34. package/src/Xcm/v5/NetworkId/NetworkIdCodec.sol +57 -34
  35. package/src/Xcm/v5/OriginKind/OriginKindCodec.sol +1 -1
  36. package/src/Xcm/v5/Response/Response.sol +49 -40
  37. package/src/Xcm/v5/Response/ResponseCodec.sol +64 -54
  38. package/src/Xcm/v5/Weight/WeightCodec.sol +3 -2
  39. package/src/Xcm/v5/WeightLimit/WeightLimit.sol +6 -6
  40. package/src/Xcm/v5/WeightLimit/WeightLimitCodec.sol +32 -23
  41. package/src/Xcm/v5/WildAsset/WildAsset.sol +17 -25
  42. package/src/Xcm/v5/WildAsset/WildAssetCodec.sol +35 -38
  43. package/src/Xcm/v5/WildFungibility/WildFungibilityCodec.sol +6 -6
  44. package/src/Xcm/v5/Xcm/XcmBuilder.sol +689 -0
  45. package/src/Xcm/v5/XcmError/XcmError.sol +7 -7
  46. package/src/Xcm/v5/XcmError/XcmErrorCodec.sol +25 -22
@@ -1,7 +1,59 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  pragma solidity ^0.8.28;
3
3
 
4
- import {Instruction, InstructionType} from "./Instruction.sol";
4
+ import {
5
+ AliasOriginParams,
6
+ BurnAssetParams,
7
+ BuyExecutionParams,
8
+ ClaimAssetParams,
9
+ DepositAssetParams,
10
+ DepositReserveAssetParams,
11
+ DescendOriginParams,
12
+ ExecuteWithOriginParams,
13
+ ExchangeAssetParams,
14
+ ExpectAssetParams,
15
+ ExpectErrorParams,
16
+ ExpectOriginParams,
17
+ ExpectPalletParams,
18
+ ExpectTransactStatusParams,
19
+ ExportMessageParams,
20
+ HrmpChannelAcceptedParams,
21
+ HrmpChannelClosingParams,
22
+ HrmpNewChannelOpenRequestParams,
23
+ InitiateReserveWithdrawParams,
24
+ InitiateTeleportParams,
25
+ InitiateTransferParams,
26
+ Instruction,
27
+ InstructionVariant,
28
+ LockAssetParams,
29
+ NoteUnlockableParams,
30
+ PayFeesParams,
31
+ QueryPalletParams,
32
+ QueryResponseParams,
33
+ ReceiveTeleportedAssetParams,
34
+ ReportErrorParams,
35
+ ReportHoldingParams,
36
+ ReportTransactStatusParams,
37
+ RequestUnlockParams,
38
+ ReserveAssetDepositedParams,
39
+ SetAppendixParams,
40
+ SetErrorHandlerParams,
41
+ SetFeesModeParams,
42
+ SetHintsParams,
43
+ SetTopicParams,
44
+ SubscribeVersionParams,
45
+ TransactParams,
46
+ TransferAssetParams,
47
+ TransferReserveAssetParams,
48
+ TrapParams,
49
+ UnlockAssetParams,
50
+ UniversalOriginParams,
51
+ UnpaidExecutionParams,
52
+ WithdrawAssetParams
53
+ } from "./Instruction.sol";
54
+ import {AssetTransferFilter} from "../AssetTransferFilter/AssetTransferFilter.sol";
55
+ import {Hint} from "../Hint/Hint.sol";
56
+ import {QueryId} from "../Types/QueryId.sol";
5
57
  import {AssetsCodec} from "../Assets/AssetsCodec.sol";
6
58
  import {AssetCodec} from "../Asset/AssetCodec.sol";
7
59
  import {LocationCodec} from "../Location/LocationCodec.sol";
@@ -22,15 +74,19 @@ import {MAX_ASSET_TRANSFER_FILTERS, HINT_NUM_VARIANTS} from "../Constants.sol";
22
74
 
23
75
  import {Compact} from "../../../Scale/Compact.sol";
24
76
  import {Bool} from "../../../Scale/Bool/Bool.sol";
77
+ import {Bytes32} from "../../../Scale/Bytes/Bytes32.sol";
25
78
  import {Bytes} from "../../../Scale/Bytes/Bytes.sol";
26
79
 
80
+ import {BytesUtils} from "../../../Utils/BytesUtils.sol";
81
+ import {UnsignedUtils} from "../../../Utils/UnsignedUtils.sol";
82
+
27
83
  /// @title SCALE Codec for XCM v5 `Instruction`
28
84
  /// @notice SCALE-compliant encoder/decoder for the `Instruction` type.
29
85
  /// @dev SCALE reference: https://docs.polkadot.com/polkadot-protocol/basics/data-encoding
30
86
  /// @dev XCM v5 reference: https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v5/index.html
31
87
  library InstructionCodec {
32
88
  error InvalidInstructionLength();
33
- error InvalidInstructionType(uint8 iType);
89
+ error InvalidInstructionVariant(uint8 variant);
34
90
  error InvalidInstructionPayload();
35
91
 
36
92
  /// @notice Encodes an `Instruction` into SCALE bytes.
@@ -39,7 +95,8 @@ library InstructionCodec {
39
95
  function encode(
40
96
  Instruction memory instruction
41
97
  ) internal pure returns (bytes memory) {
42
- return abi.encodePacked(uint8(instruction.iType), instruction.payload);
98
+ return
99
+ abi.encodePacked(uint8(instruction.variant), instruction.payload);
43
100
  }
44
101
 
45
102
  /// @notice Returns the number of bytes that an `Instruction` occupies when SCALE-encoded.
@@ -52,23 +109,23 @@ library InstructionCodec {
52
109
  ) internal pure returns (uint256) {
53
110
  if (data.length < offset + 1) revert InvalidInstructionLength();
54
111
 
55
- uint8 iTypeRaw = uint8(data[offset]);
56
- if (iTypeRaw > uint8(InstructionType.SetHints)) {
57
- revert InvalidInstructionType(iTypeRaw);
112
+ uint8 variantRaw = uint8(data[offset]);
113
+ if (variantRaw > uint8(type(InstructionVariant).max)) {
114
+ revert InvalidInstructionVariant(variantRaw);
58
115
  }
59
116
 
60
- InstructionType iType = InstructionType(iTypeRaw);
117
+ InstructionVariant variant = InstructionVariant(variantRaw);
61
118
  uint256 pos = offset + 1;
62
119
 
63
120
  if (
64
- iType == InstructionType.WithdrawAsset ||
65
- iType == InstructionType.ReserveAssetDeposited ||
66
- iType == InstructionType.ReceiveTeleportedAsset ||
67
- iType == InstructionType.BurnAsset ||
68
- iType == InstructionType.ExpectAsset
121
+ variant == InstructionVariant.WithdrawAsset ||
122
+ variant == InstructionVariant.ReserveAssetDeposited ||
123
+ variant == InstructionVariant.ReceiveTeleportedAsset ||
124
+ variant == InstructionVariant.BurnAsset ||
125
+ variant == InstructionVariant.ExpectAsset
69
126
  ) {
70
127
  pos += AssetsCodec.encodedSizeAt(data, pos);
71
- } else if (iType == InstructionType.QueryResponse) {
128
+ } else if (variant == InstructionVariant.QueryResponse) {
72
129
  pos += Compact.encodedSizeAt(data, pos);
73
130
  pos += ResponseCodec.encodedSizeAt(data, pos);
74
131
  pos += WeightCodec.encodedSizeAt(data, pos);
@@ -77,16 +134,16 @@ library InstructionCodec {
77
134
  if (hasQuerier) {
78
135
  pos += LocationCodec.encodedSizeAt(data, pos);
79
136
  }
80
- } else if (iType == InstructionType.TransferAsset) {
137
+ } else if (variant == InstructionVariant.TransferAsset) {
81
138
  pos += AssetsCodec.encodedSizeAt(data, pos);
82
139
  pos += LocationCodec.encodedSizeAt(data, pos);
83
140
  } else if (
84
- iType == InstructionType.TransferReserveAsset ||
85
- iType == InstructionType.DepositReserveAsset ||
86
- iType == InstructionType.InitiateReserveWithdraw ||
87
- iType == InstructionType.InitiateTeleport
141
+ variant == InstructionVariant.TransferReserveAsset ||
142
+ variant == InstructionVariant.DepositReserveAsset ||
143
+ variant == InstructionVariant.InitiateReserveWithdraw ||
144
+ variant == InstructionVariant.InitiateTeleport
88
145
  ) {
89
- if (iType == InstructionType.TransferReserveAsset) {
146
+ if (variant == InstructionVariant.TransferReserveAsset) {
90
147
  pos += AssetsCodec.encodedSizeAt(data, pos);
91
148
  pos += LocationCodec.encodedSizeAt(data, pos);
92
149
  } else {
@@ -94,7 +151,7 @@ library InstructionCodec {
94
151
  pos += LocationCodec.encodedSizeAt(data, pos);
95
152
  }
96
153
  pos += _xcmEncodedSizeAt(data, pos);
97
- } else if (iType == InstructionType.Transact) {
154
+ } else if (variant == InstructionVariant.Transact) {
98
155
  pos += OriginKindCodec.encodedSizeAt(data, pos);
99
156
  bool hasFallbackMaxWeight = Bool.decodeAt(data, pos);
100
157
  pos += 1;
@@ -102,113 +159,114 @@ library InstructionCodec {
102
159
  pos += WeightCodec.encodedSizeAt(data, pos);
103
160
  }
104
161
  pos += Bytes.encodedSizeAt(data, pos);
105
- } else if (iType == InstructionType.HrmpNewChannelOpenRequest) {
162
+ } else if (variant == InstructionVariant.HrmpNewChannelOpenRequest) {
106
163
  pos += Compact.encodedSizeAt(data, pos);
107
164
  pos += Compact.encodedSizeAt(data, pos);
108
165
  pos += Compact.encodedSizeAt(data, pos);
109
- } else if (iType == InstructionType.HrmpChannelAccepted) {
166
+ } else if (variant == InstructionVariant.HrmpChannelAccepted) {
110
167
  pos += Compact.encodedSizeAt(data, pos);
111
- } else if (iType == InstructionType.HrmpChannelClosing) {
168
+ } else if (variant == InstructionVariant.HrmpChannelClosing) {
112
169
  pos += Compact.encodedSizeAt(data, pos);
113
170
  pos += Compact.encodedSizeAt(data, pos);
114
171
  pos += Compact.encodedSizeAt(data, pos);
115
172
  } else if (
116
- iType == InstructionType.ClearOrigin ||
117
- iType == InstructionType.RefundSurplus ||
118
- iType == InstructionType.ClearError ||
119
- iType == InstructionType.UnsubscribeVersion ||
120
- iType == InstructionType.ClearTransactStatus ||
121
- iType == InstructionType.ClearTopic
173
+ variant == InstructionVariant.ClearOrigin ||
174
+ variant == InstructionVariant.RefundSurplus ||
175
+ variant == InstructionVariant.ClearError ||
176
+ variant == InstructionVariant.UnsubscribeVersion ||
177
+ variant == InstructionVariant.ClearTransactStatus ||
178
+ variant == InstructionVariant.ClearTopic
122
179
  ) {
123
180
  // no payload
124
- } else if (iType == InstructionType.DescendOrigin) {
181
+ return pos - offset;
182
+ } else if (variant == InstructionVariant.DescendOrigin) {
125
183
  pos += JunctionsCodec.encodedSizeAt(data, pos);
126
184
  } else if (
127
- iType == InstructionType.ReportError ||
128
- iType == InstructionType.ReportTransactStatus
185
+ variant == InstructionVariant.ReportError ||
186
+ variant == InstructionVariant.ReportTransactStatus
129
187
  ) {
130
188
  pos += QueryResponseInfoCodec.encodedSizeAt(data, pos);
131
- } else if (iType == InstructionType.DepositAsset) {
189
+ } else if (variant == InstructionVariant.DepositAsset) {
132
190
  pos += AssetFilterCodec.encodedSizeAt(data, pos);
133
191
  pos += LocationCodec.encodedSizeAt(data, pos);
134
- } else if (iType == InstructionType.ExchangeAsset) {
192
+ } else if (variant == InstructionVariant.ExchangeAsset) {
135
193
  pos += AssetFilterCodec.encodedSizeAt(data, pos);
136
194
  pos += AssetsCodec.encodedSizeAt(data, pos);
137
195
  pos += 1;
138
- } else if (iType == InstructionType.ReportHolding) {
196
+ } else if (variant == InstructionVariant.ReportHolding) {
139
197
  pos += QueryResponseInfoCodec.encodedSizeAt(data, pos);
140
198
  pos += AssetFilterCodec.encodedSizeAt(data, pos);
141
- } else if (iType == InstructionType.BuyExecution) {
199
+ } else if (variant == InstructionVariant.BuyExecution) {
142
200
  pos += AssetCodec.encodedSizeAt(data, pos);
143
201
  pos += WeightLimitCodec.encodedSizeAt(data, pos);
144
202
  } else if (
145
- iType == InstructionType.SetErrorHandler ||
146
- iType == InstructionType.SetAppendix
203
+ variant == InstructionVariant.SetErrorHandler ||
204
+ variant == InstructionVariant.SetAppendix
147
205
  ) {
148
206
  pos += _xcmEncodedSizeAt(data, pos);
149
- } else if (iType == InstructionType.ClaimAsset) {
207
+ } else if (variant == InstructionVariant.ClaimAsset) {
150
208
  pos += AssetsCodec.encodedSizeAt(data, pos);
151
209
  pos += LocationCodec.encodedSizeAt(data, pos);
152
- } else if (iType == InstructionType.Trap) {
210
+ } else if (variant == InstructionVariant.Trap) {
153
211
  pos += Compact.encodedSizeAt(data, pos);
154
- } else if (iType == InstructionType.SubscribeVersion) {
212
+ } else if (variant == InstructionVariant.SubscribeVersion) {
155
213
  pos += Compact.encodedSizeAt(data, pos);
156
214
  pos += WeightCodec.encodedSizeAt(data, pos);
157
- } else if (iType == InstructionType.ExpectOrigin) {
215
+ } else if (variant == InstructionVariant.ExpectOrigin) {
158
216
  bool hasOrigin = Bool.decodeAt(data, pos);
159
217
  pos += 1;
160
218
  if (hasOrigin) {
161
219
  pos += LocationCodec.encodedSizeAt(data, pos);
162
220
  }
163
- } else if (iType == InstructionType.ExpectError) {
221
+ } else if (variant == InstructionVariant.ExpectError) {
164
222
  bool hasError = Bool.decodeAt(data, pos);
165
223
  pos += 1;
166
224
  if (hasError) {
167
225
  pos += Compact.encodedSizeAt(data, pos);
168
226
  pos += XcmErrorCodec.encodedSizeAt(data, pos);
169
227
  }
170
- } else if (iType == InstructionType.ExpectTransactStatus) {
228
+ } else if (variant == InstructionVariant.ExpectTransactStatus) {
171
229
  pos += MaybeErrorCodeCodec.encodedSizeAt(data, pos);
172
- } else if (iType == InstructionType.QueryPallet) {
230
+ } else if (variant == InstructionVariant.QueryPallet) {
173
231
  pos += Bytes.encodedSizeAt(data, pos);
174
232
  pos += QueryResponseInfoCodec.encodedSizeAt(data, pos);
175
- } else if (iType == InstructionType.ExpectPallet) {
233
+ } else if (variant == InstructionVariant.ExpectPallet) {
176
234
  pos += Compact.encodedSizeAt(data, pos);
177
235
  pos += Bytes.encodedSizeAt(data, pos);
178
236
  pos += Bytes.encodedSizeAt(data, pos);
179
237
  pos += Compact.encodedSizeAt(data, pos);
180
238
  pos += Compact.encodedSizeAt(data, pos);
181
- } else if (iType == InstructionType.UniversalOrigin) {
239
+ } else if (variant == InstructionVariant.UniversalOrigin) {
182
240
  pos += JunctionCodec.encodedSizeAt(data, pos);
183
- } else if (iType == InstructionType.ExportMessage) {
241
+ } else if (variant == InstructionVariant.ExportMessage) {
184
242
  pos += NetworkIdCodec.encodedSizeAt(data, pos);
185
243
  pos += JunctionsCodec.encodedSizeAt(data, pos);
186
244
  pos += _xcmEncodedSizeAt(data, pos);
187
245
  } else if (
188
- iType == InstructionType.LockAsset ||
189
- iType == InstructionType.UnlockAsset ||
190
- iType == InstructionType.NoteUnlockable ||
191
- iType == InstructionType.RequestUnlock
246
+ variant == InstructionVariant.LockAsset ||
247
+ variant == InstructionVariant.UnlockAsset ||
248
+ variant == InstructionVariant.NoteUnlockable ||
249
+ variant == InstructionVariant.RequestUnlock
192
250
  ) {
193
251
  pos += AssetCodec.encodedSizeAt(data, pos);
194
252
  pos += LocationCodec.encodedSizeAt(data, pos);
195
- } else if (iType == InstructionType.SetFeesMode) {
253
+ } else if (variant == InstructionVariant.SetFeesMode) {
196
254
  pos += 1;
197
- } else if (iType == InstructionType.SetTopic) {
255
+ } else if (variant == InstructionVariant.SetTopic) {
198
256
  if (data.length < pos + 32) revert InvalidInstructionPayload();
199
257
  pos += 32;
200
- } else if (iType == InstructionType.AliasOrigin) {
258
+ } else if (variant == InstructionVariant.AliasOrigin) {
201
259
  pos += LocationCodec.encodedSizeAt(data, pos);
202
- } else if (iType == InstructionType.UnpaidExecution) {
260
+ } else if (variant == InstructionVariant.UnpaidExecution) {
203
261
  pos += WeightLimitCodec.encodedSizeAt(data, pos);
204
262
  bool hasCheckOrigin = Bool.decodeAt(data, pos);
205
263
  pos += 1;
206
264
  if (hasCheckOrigin) {
207
265
  pos += LocationCodec.encodedSizeAt(data, pos);
208
266
  }
209
- } else if (iType == InstructionType.PayFees) {
267
+ } else if (variant == InstructionVariant.PayFees) {
210
268
  pos += AssetCodec.encodedSizeAt(data, pos);
211
- } else if (iType == InstructionType.InitiateTransfer) {
269
+ } else if (variant == InstructionVariant.InitiateTransfer) {
212
270
  pos += LocationCodec.encodedSizeAt(data, pos);
213
271
  bool hasRemoteFees = Bool.decodeAt(data, pos);
214
272
  pos += 1;
@@ -233,14 +291,14 @@ library InstructionCodec {
233
291
  if (data.length < pos + remoteXcmLen)
234
292
  revert InvalidInstructionPayload();
235
293
  pos += remoteXcmLen;
236
- } else if (iType == InstructionType.ExecuteWithOrigin) {
294
+ } else if (variant == InstructionVariant.ExecuteWithOrigin) {
237
295
  bool hasDescendantOrigin = Bool.decodeAt(data, pos);
238
296
  pos += 1;
239
297
  if (hasDescendantOrigin) {
240
298
  pos += JunctionsCodec.encodedSizeAt(data, pos);
241
299
  }
242
300
  pos += _xcmEncodedSizeAt(data, pos);
243
- } else if (iType == InstructionType.SetHints) {
301
+ } else if (variant == InstructionVariant.SetHints) {
244
302
  (uint256 hintsCount, uint256 hintsCountBytes) = Compact.decodeAt(
245
303
  data,
246
304
  pos
@@ -284,27 +342,925 @@ library InstructionCodec {
284
342
  pure
285
343
  returns (Instruction memory instruction, uint256 bytesRead)
286
344
  {
287
- if (data.length < offset + 1) revert InvalidInstructionLength();
288
-
289
- uint8 iTypeRaw = uint8(data[offset]);
290
- if (iTypeRaw > uint8(InstructionType.SetHints)) {
291
- revert InvalidInstructionType(iTypeRaw);
292
- }
293
-
294
345
  uint256 size = encodedSizeAt(data, offset);
346
+ uint8 variantRaw = uint8(data[offset]);
295
347
  uint256 payloadLength = size - 1;
296
- bytes memory payload = new bytes(payloadLength);
297
- for (uint256 i = 0; i < payloadLength; ++i) {
298
- payload[i] = data[offset + 1 + i];
299
- }
300
-
348
+ bytes memory payload = BytesUtils.copy(data, offset + 1, payloadLength);
301
349
  instruction = Instruction({
302
- iType: InstructionType(iTypeRaw),
350
+ variant: InstructionVariant(variantRaw),
303
351
  payload: payload
304
352
  });
305
353
  bytesRead = size;
306
354
  }
307
355
 
356
+ /// @notice Extracts the decoded `WithdrawAssetParams` from a `WithdrawAsset` instruction. Reverts if the instruction is not of type `WithdrawAsset`.
357
+ /// @param instruction The `Instruction` struct to decode, which must have type `WithdrawAsset`.
358
+ /// @return params The decoded `WithdrawAssetParams` extracted from the instruction payload.
359
+ function asWithdrawAsset(
360
+ Instruction memory instruction
361
+ ) internal pure returns (WithdrawAssetParams memory params) {
362
+ _assertVariant(instruction, InstructionVariant.WithdrawAsset);
363
+ uint256 bytesRead;
364
+ (params.assets, bytesRead) = AssetsCodec.decode(instruction.payload);
365
+ }
366
+
367
+ /// @notice Extracts the decoded `ReserveAssetDepositedParams` from a `ReserveAssetDeposited` instruction. Reverts if the instruction is not of type `ReserveAssetDeposited`.
368
+ /// @param instruction The `Instruction` struct to decode, which must have type `ReserveAssetDeposited`.
369
+ /// @return params The decoded `ReserveAssetDepositedParams` extracted from the instruction payload.
370
+ function asReserveAssetDeposited(
371
+ Instruction memory instruction
372
+ ) internal pure returns (ReserveAssetDepositedParams memory params) {
373
+ _assertVariant(instruction, InstructionVariant.ReserveAssetDeposited);
374
+ uint256 bytesRead;
375
+ (params.assets, bytesRead) = AssetsCodec.decode(instruction.payload);
376
+ }
377
+
378
+ /// @notice Extracts the decoded `ReceiveTeleportedAssetParams` from a `ReceiveTeleportedAsset` instruction. Reverts if the instruction is not of type `ReceiveTeleportedAsset`.
379
+ /// @param instruction The `Instruction` struct to decode, which must have type `ReceiveTeleportedAsset`.
380
+ /// @return params The decoded `ReceiveTeleportedAssetParams` extracted from the instruction payload.
381
+ function asReceiveTeleportedAsset(
382
+ Instruction memory instruction
383
+ ) internal pure returns (ReceiveTeleportedAssetParams memory params) {
384
+ _assertVariant(instruction, InstructionVariant.ReceiveTeleportedAsset);
385
+ uint256 bytesRead;
386
+ (params.assets, bytesRead) = AssetsCodec.decode(instruction.payload);
387
+ }
388
+
389
+ /// @notice Extracts the decoded `QueryResponseParams` from a `QueryResponse` instruction. Reverts if the instruction is not of type `QueryResponse`.
390
+ /// @param instruction The `Instruction` struct to decode, which must have type `QueryResponse`.
391
+ /// @return params The decoded `QueryResponseParams` extracted from the instruction payload.
392
+ function asQueryResponse(
393
+ Instruction memory instruction
394
+ ) internal pure returns (QueryResponseParams memory params) {
395
+ _assertVariant(instruction, InstructionVariant.QueryResponse);
396
+ bytes memory payload = instruction.payload;
397
+ uint256 pos;
398
+ uint256 bytesRead;
399
+ uint256 queryIdRaw;
400
+
401
+ (queryIdRaw, bytesRead) = Compact.decodeAt(payload, pos);
402
+ params.queryId = QueryId.wrap(UnsignedUtils.toU64(queryIdRaw));
403
+ pos += bytesRead;
404
+
405
+ (params.response, bytesRead) = ResponseCodec.decodeAt(payload, pos);
406
+ pos += bytesRead;
407
+
408
+ (params.maxWeight, bytesRead) = WeightCodec.decodeAt(payload, pos);
409
+ pos += bytesRead;
410
+
411
+ params.hasQuerier = Bool.decodeAt(payload, pos);
412
+ pos += 1;
413
+
414
+ if (params.hasQuerier) {
415
+ (params.querier, bytesRead) = LocationCodec.decodeAt(payload, pos);
416
+ pos += bytesRead;
417
+ }
418
+ }
419
+
420
+ /// @notice Extracts the decoded `TransferAssetParams` from a `TransferAsset` instruction. Reverts if the instruction is not of type `TransferAsset`.
421
+ /// @param instruction The `Instruction` struct to decode, which must have type `TransferAsset`.
422
+ /// @return params The decoded `TransferAssetParams` extracted from the instruction payload.
423
+ function asTransferAsset(
424
+ Instruction memory instruction
425
+ ) internal pure returns (TransferAssetParams memory params) {
426
+ _assertVariant(instruction, InstructionVariant.TransferAsset);
427
+ bytes memory payload = instruction.payload;
428
+ uint256 pos;
429
+ uint256 bytesRead;
430
+
431
+ (params.assets, bytesRead) = AssetsCodec.decodeAt(payload, pos);
432
+ pos += bytesRead;
433
+
434
+ (params.beneficiary, bytesRead) = LocationCodec.decodeAt(payload, pos);
435
+ pos += bytesRead;
436
+ }
437
+
438
+ /// @notice Extracts the decoded `TransferReserveAssetParams` from a `TransferReserveAsset` instruction. Reverts if the instruction is not of type `TransferReserveAsset`.
439
+ /// @param instruction The `Instruction` struct to decode, which must have type `TransferReserveAsset`.
440
+ /// @return params The decoded `TransferReserveAssetParams` extracted from the instruction payload.
441
+ function asTransferReserveAsset(
442
+ Instruction memory instruction
443
+ ) internal pure returns (TransferReserveAssetParams memory params) {
444
+ _assertVariant(instruction, InstructionVariant.TransferReserveAsset);
445
+ bytes memory payload = instruction.payload;
446
+ uint256 pos;
447
+ uint256 bytesRead;
448
+
449
+ (params.assets, bytesRead) = AssetsCodec.decodeAt(payload, pos);
450
+ pos += bytesRead;
451
+
452
+ (params.dest, bytesRead) = LocationCodec.decodeAt(payload, pos);
453
+ pos += bytesRead;
454
+
455
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
456
+ }
457
+
458
+ /// @notice Extracts the decoded `TransactParams` from a `Transact` instruction. Reverts if the instruction is not of type `Transact`.
459
+ /// @param instruction The `Instruction` struct to decode, which must have type `Transact`.
460
+ /// @return params The decoded `TransactParams` extracted from the instruction payload.
461
+ function asTransact(
462
+ Instruction memory instruction
463
+ ) internal pure returns (TransactParams memory params) {
464
+ _assertVariant(instruction, InstructionVariant.Transact);
465
+ bytes memory payload = instruction.payload;
466
+ uint256 pos;
467
+ uint256 bytesRead;
468
+
469
+ (params.originKind, bytesRead) = OriginKindCodec.decodeAt(payload, pos);
470
+ pos += bytesRead;
471
+
472
+ params.hasFallbackMaxWeight = Bool.decodeAt(payload, pos);
473
+ pos += 1;
474
+
475
+ if (params.hasFallbackMaxWeight) {
476
+ (params.fallbackMaxWeight, bytesRead) = WeightCodec.decodeAt(
477
+ payload,
478
+ pos
479
+ );
480
+ pos += bytesRead;
481
+ }
482
+
483
+ (params.call, bytesRead) = Bytes.decodeAt(payload, pos);
484
+ pos += bytesRead;
485
+ }
486
+
487
+ /// @notice Extracts the decoded `HrmpNewChannelOpenRequestParams` from a `HrmpNewChannelOpenRequest` instruction. Reverts if the instruction is not of type `HrmpNewChannelOpenRequest`.
488
+ /// @param instruction The `Instruction` struct to decode, which must have type `HrmpNewChannelOpenRequest`.
489
+ /// @return params The decoded `HrmpNewChannelOpenRequestParams` extracted from the instruction payload.
490
+ function asHrmpNewChannelOpenRequest(
491
+ Instruction memory instruction
492
+ ) internal pure returns (HrmpNewChannelOpenRequestParams memory params) {
493
+ _assertVariant(
494
+ instruction,
495
+ InstructionVariant.HrmpNewChannelOpenRequest
496
+ );
497
+ bytes memory payload = instruction.payload;
498
+ uint256 pos;
499
+ uint256 bytesRead;
500
+ uint256 value;
501
+
502
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
503
+ params.sender = UnsignedUtils.toU32(value);
504
+ pos += bytesRead;
505
+
506
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
507
+ params.maxMessageSize = UnsignedUtils.toU32(value);
508
+ pos += bytesRead;
509
+
510
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
511
+ params.maxCapacity = UnsignedUtils.toU32(value);
512
+ pos += bytesRead;
513
+ }
514
+
515
+ /// @notice Extracts the decoded `HrmpChannelAcceptedParams` from a `HrmpChannelAccepted` instruction. Reverts if the instruction is not of type `HrmpChannelAccepted`.
516
+ /// @param instruction The `Instruction` struct to decode, which must have type `HrmpChannelAccepted`.
517
+ /// @return params The decoded `HrmpChannelAcceptedParams` extracted from the instruction payload.
518
+ function asHrmpChannelAccepted(
519
+ Instruction memory instruction
520
+ ) internal pure returns (HrmpChannelAcceptedParams memory params) {
521
+ _assertVariant(instruction, InstructionVariant.HrmpChannelAccepted);
522
+ uint256 value;
523
+ uint256 bytesRead;
524
+ (value, bytesRead) = Compact.decode(instruction.payload);
525
+ params.recipient = UnsignedUtils.toU32(value);
526
+ }
527
+
528
+ /// @notice Extracts the decoded `HrmpChannelClosingParams` from a `HrmpChannelClosing` instruction. Reverts if the instruction is not of type `HrmpChannelClosing`.
529
+ /// @param instruction The `Instruction` struct to decode, which must have type `HrmpChannelClosing`.
530
+ /// @return params The decoded `HrmpChannelClosingParams` extracted from the instruction payload.
531
+ function asHrmpChannelClosing(
532
+ Instruction memory instruction
533
+ ) internal pure returns (HrmpChannelClosingParams memory params) {
534
+ _assertVariant(instruction, InstructionVariant.HrmpChannelClosing);
535
+ bytes memory payload = instruction.payload;
536
+ uint256 pos;
537
+ uint256 bytesRead;
538
+ uint256 value;
539
+
540
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
541
+ params.initiator = UnsignedUtils.toU32(value);
542
+ pos += bytesRead;
543
+
544
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
545
+ params.sender = UnsignedUtils.toU32(value);
546
+ pos += bytesRead;
547
+
548
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
549
+ params.recipient = UnsignedUtils.toU32(value);
550
+ pos += bytesRead;
551
+ }
552
+
553
+ /// @notice Validates a `ClearOrigin` instruction payload. Reverts if the instruction is not of type `ClearOrigin` or the payload is invalid.
554
+ /// @param instruction The `Instruction` struct to validate, which must have type `ClearOrigin`.
555
+ function asClearOrigin(Instruction memory instruction) internal pure {
556
+ _assertVariant(instruction, InstructionVariant.ClearOrigin);
557
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
558
+ }
559
+
560
+ /// @notice Extracts the decoded `DescendOriginParams` from a `DescendOrigin` instruction. Reverts if the instruction is not of type `DescendOrigin`.
561
+ /// @param instruction The `Instruction` struct to decode, which must have type `DescendOrigin`.
562
+ /// @return params The decoded `DescendOriginParams` extracted from the instruction payload.
563
+ function asDescendOrigin(
564
+ Instruction memory instruction
565
+ ) internal pure returns (DescendOriginParams memory params) {
566
+ _assertVariant(instruction, InstructionVariant.DescendOrigin);
567
+ uint256 bytesRead;
568
+ (params.interior, bytesRead) = JunctionsCodec.decode(
569
+ instruction.payload
570
+ );
571
+ }
572
+
573
+ /// @notice Extracts the decoded `ReportErrorParams` from a `ReportError` instruction. Reverts if the instruction is not of type `ReportError`.
574
+ /// @param instruction The `Instruction` struct to decode, which must have type `ReportError`.
575
+ /// @return params The decoded `ReportErrorParams` extracted from the instruction payload.
576
+ function asReportError(
577
+ Instruction memory instruction
578
+ ) internal pure returns (ReportErrorParams memory params) {
579
+ _assertVariant(instruction, InstructionVariant.ReportError);
580
+ uint256 bytesRead;
581
+ (params.responseInfo, bytesRead) = QueryResponseInfoCodec.decode(
582
+ instruction.payload
583
+ );
584
+ }
585
+
586
+ /// @notice Extracts the decoded `DepositAssetParams` from a `DepositAsset` instruction. Reverts if the instruction is not of type `DepositAsset`.
587
+ /// @param instruction The `Instruction` struct to decode, which must have type `DepositAsset`.
588
+ /// @return params The decoded `DepositAssetParams` extracted from the instruction payload.
589
+ function asDepositAsset(
590
+ Instruction memory instruction
591
+ ) internal pure returns (DepositAssetParams memory params) {
592
+ _assertVariant(instruction, InstructionVariant.DepositAsset);
593
+ bytes memory payload = instruction.payload;
594
+ uint256 pos;
595
+ uint256 bytesRead;
596
+
597
+ (params.assets, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
598
+ pos += bytesRead;
599
+
600
+ (params.beneficiary, bytesRead) = LocationCodec.decodeAt(payload, pos);
601
+ pos += bytesRead;
602
+ }
603
+
604
+ /// @notice Extracts the decoded `DepositReserveAssetParams` from a `DepositReserveAsset` instruction. Reverts if the instruction is not of type `DepositReserveAsset`.
605
+ /// @param instruction The `Instruction` struct to decode, which must have type `DepositReserveAsset`.
606
+ /// @return params The decoded `DepositReserveAssetParams` extracted from the instruction payload.
607
+ function asDepositReserveAsset(
608
+ Instruction memory instruction
609
+ ) internal pure returns (DepositReserveAssetParams memory params) {
610
+ _assertVariant(instruction, InstructionVariant.DepositReserveAsset);
611
+ bytes memory payload = instruction.payload;
612
+ uint256 pos;
613
+ uint256 bytesRead;
614
+
615
+ (params.assets, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
616
+ pos += bytesRead;
617
+
618
+ (params.dest, bytesRead) = LocationCodec.decodeAt(payload, pos);
619
+ pos += bytesRead;
620
+
621
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
622
+ }
623
+
624
+ /// @notice Extracts the decoded `ExchangeAssetParams` from a `ExchangeAsset` instruction. Reverts if the instruction is not of type `ExchangeAsset`.
625
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExchangeAsset`.
626
+ /// @return params The decoded `ExchangeAssetParams` extracted from the instruction payload.
627
+ function asExchangeAsset(
628
+ Instruction memory instruction
629
+ ) internal pure returns (ExchangeAssetParams memory params) {
630
+ _assertVariant(instruction, InstructionVariant.ExchangeAsset);
631
+ bytes memory payload = instruction.payload;
632
+ uint256 pos;
633
+ uint256 bytesRead;
634
+
635
+ (params.give, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
636
+ pos += bytesRead;
637
+
638
+ (params.want, bytesRead) = AssetsCodec.decodeAt(payload, pos);
639
+ pos += bytesRead;
640
+
641
+ params.maximal = Bool.decodeAt(payload, pos);
642
+ pos += 1;
643
+ }
644
+
645
+ /// @notice Extracts the decoded `InitiateReserveWithdrawParams` from a `InitiateReserveWithdraw` instruction. Reverts if the instruction is not of type `InitiateReserveWithdraw`.
646
+ /// @param instruction The `Instruction` struct to decode, which must have type `InitiateReserveWithdraw`.
647
+ /// @return params The decoded `InitiateReserveWithdrawParams` extracted from the instruction payload.
648
+ function asInitiateReserveWithdraw(
649
+ Instruction memory instruction
650
+ ) internal pure returns (InitiateReserveWithdrawParams memory params) {
651
+ _assertVariant(instruction, InstructionVariant.InitiateReserveWithdraw);
652
+ bytes memory payload = instruction.payload;
653
+ uint256 pos;
654
+ uint256 bytesRead;
655
+
656
+ (params.assets, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
657
+ pos += bytesRead;
658
+
659
+ (params.reserve, bytesRead) = LocationCodec.decodeAt(payload, pos);
660
+ pos += bytesRead;
661
+
662
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
663
+ }
664
+
665
+ /// @notice Extracts the decoded `InitiateTeleportParams` from a `InitiateTeleport` instruction. Reverts if the instruction is not of type `InitiateTeleport`.
666
+ /// @param instruction The `Instruction` struct to decode, which must have type `InitiateTeleport`.
667
+ /// @return params The decoded `InitiateTeleportParams` extracted from the instruction payload.
668
+ function asInitiateTeleport(
669
+ Instruction memory instruction
670
+ ) internal pure returns (InitiateTeleportParams memory params) {
671
+ _assertVariant(instruction, InstructionVariant.InitiateTeleport);
672
+ bytes memory payload = instruction.payload;
673
+ uint256 pos;
674
+ uint256 bytesRead;
675
+
676
+ (params.assets, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
677
+ pos += bytesRead;
678
+
679
+ (params.dest, bytesRead) = LocationCodec.decodeAt(payload, pos);
680
+ pos += bytesRead;
681
+
682
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
683
+ }
684
+
685
+ /// @notice Extracts the decoded `ReportHoldingParams` from a `ReportHolding` instruction. Reverts if the instruction is not of type `ReportHolding`.
686
+ /// @param instruction The `Instruction` struct to decode, which must have type `ReportHolding`.
687
+ /// @return params The decoded `ReportHoldingParams` extracted from the instruction payload.
688
+ function asReportHolding(
689
+ Instruction memory instruction
690
+ ) internal pure returns (ReportHoldingParams memory params) {
691
+ _assertVariant(instruction, InstructionVariant.ReportHolding);
692
+ bytes memory payload = instruction.payload;
693
+ uint256 pos;
694
+ uint256 bytesRead;
695
+
696
+ (params.responseInfo, bytesRead) = QueryResponseInfoCodec.decodeAt(
697
+ payload,
698
+ pos
699
+ );
700
+ pos += bytesRead;
701
+
702
+ (params.assets, bytesRead) = AssetFilterCodec.decodeAt(payload, pos);
703
+ pos += bytesRead;
704
+ }
705
+
706
+ /// @notice Extracts the decoded `BuyExecutionParams` from a `BuyExecution` instruction. Reverts if the instruction is not of type `BuyExecution`.
707
+ /// @param instruction The `Instruction` struct to decode, which must have type `BuyExecution`.
708
+ /// @return params The decoded `BuyExecutionParams` extracted from the instruction payload.
709
+ function asBuyExecution(
710
+ Instruction memory instruction
711
+ ) internal pure returns (BuyExecutionParams memory params) {
712
+ _assertVariant(instruction, InstructionVariant.BuyExecution);
713
+ bytes memory payload = instruction.payload;
714
+ uint256 pos;
715
+ uint256 bytesRead;
716
+
717
+ (params.fees, bytesRead) = AssetCodec.decodeAt(payload, pos);
718
+ pos += bytesRead;
719
+
720
+ (params.weightLimit, bytesRead) = WeightLimitCodec.decodeAt(
721
+ payload,
722
+ pos
723
+ );
724
+ pos += bytesRead;
725
+ }
726
+
727
+ /// @notice Validates a `RefundSurplus` instruction payload. Reverts if the instruction is not of type `RefundSurplus` or the payload is invalid.
728
+ /// @param instruction The `Instruction` struct to validate, which must have type `RefundSurplus`.
729
+ function asRefundSurplus(Instruction memory instruction) internal pure {
730
+ _assertVariant(instruction, InstructionVariant.RefundSurplus);
731
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
732
+ }
733
+
734
+ /// @notice Extracts the decoded `SetErrorHandlerParams` from a `SetErrorHandler` instruction. Reverts if the instruction is not of type `SetErrorHandler`.
735
+ /// @param instruction The `Instruction` struct to decode, which must have type `SetErrorHandler`.
736
+ /// @return params The decoded `SetErrorHandlerParams` extracted from the instruction payload.
737
+ function asSetErrorHandler(
738
+ Instruction memory instruction
739
+ ) internal pure returns (SetErrorHandlerParams memory params) {
740
+ _assertVariant(instruction, InstructionVariant.SetErrorHandler);
741
+ (params.xcm, ) = _decodeXcmAt(instruction.payload, 0);
742
+ }
743
+
744
+ /// @notice Extracts the decoded `SetAppendixParams` from a `SetAppendix` instruction. Reverts if the instruction is not of type `SetAppendix`.
745
+ /// @param instruction The `Instruction` struct to decode, which must have type `SetAppendix`.
746
+ /// @return params The decoded `SetAppendixParams` extracted from the instruction payload.
747
+ function asSetAppendix(
748
+ Instruction memory instruction
749
+ ) internal pure returns (SetAppendixParams memory params) {
750
+ _assertVariant(instruction, InstructionVariant.SetAppendix);
751
+ (params.xcm, ) = _decodeXcmAt(instruction.payload, 0);
752
+ }
753
+
754
+ /// @notice Validates a `ClearError` instruction payload. Reverts if the instruction is not of type `ClearError` or the payload is invalid.
755
+ /// @param instruction The `Instruction` struct to validate, which must have type `ClearError`.
756
+ function asClearError(Instruction memory instruction) internal pure {
757
+ _assertVariant(instruction, InstructionVariant.ClearError);
758
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
759
+ }
760
+
761
+ /// @notice Extracts the decoded `ClaimAssetParams` from a `ClaimAsset` instruction. Reverts if the instruction is not of type `ClaimAsset`.
762
+ /// @param instruction The `Instruction` struct to decode, which must have type `ClaimAsset`.
763
+ /// @return params The decoded `ClaimAssetParams` extracted from the instruction payload.
764
+ function asClaimAsset(
765
+ Instruction memory instruction
766
+ ) internal pure returns (ClaimAssetParams memory params) {
767
+ _assertVariant(instruction, InstructionVariant.ClaimAsset);
768
+ bytes memory payload = instruction.payload;
769
+ uint256 pos;
770
+ uint256 bytesRead;
771
+
772
+ (params.assets, bytesRead) = AssetsCodec.decodeAt(payload, pos);
773
+ pos += bytesRead;
774
+
775
+ (params.ticket, bytesRead) = LocationCodec.decodeAt(payload, pos);
776
+ pos += bytesRead;
777
+ }
778
+
779
+ /// @notice Extracts the decoded `TrapParams` from a `Trap` instruction. Reverts if the instruction is not of type `Trap`.
780
+ /// @param instruction The `Instruction` struct to decode, which must have type `Trap`.
781
+ /// @return params The decoded `TrapParams` extracted from the instruction payload.
782
+ function asTrap(
783
+ Instruction memory instruction
784
+ ) internal pure returns (TrapParams memory params) {
785
+ _assertVariant(instruction, InstructionVariant.Trap);
786
+ uint256 value;
787
+ uint256 bytesRead;
788
+ (value, bytesRead) = Compact.decode(instruction.payload);
789
+ params.code = UnsignedUtils.toU64(value);
790
+ }
791
+
792
+ /// @notice Extracts the decoded `SubscribeVersionParams` from a `SubscribeVersion` instruction. Reverts if the instruction is not of type `SubscribeVersion`.
793
+ /// @param instruction The `Instruction` struct to decode, which must have type `SubscribeVersion`.
794
+ /// @return params The decoded `SubscribeVersionParams` extracted from the instruction payload.
795
+ function asSubscribeVersion(
796
+ Instruction memory instruction
797
+ ) internal pure returns (SubscribeVersionParams memory params) {
798
+ _assertVariant(instruction, InstructionVariant.SubscribeVersion);
799
+ bytes memory payload = instruction.payload;
800
+ uint256 pos;
801
+ uint256 bytesRead;
802
+ uint256 queryIdRaw;
803
+
804
+ (queryIdRaw, bytesRead) = Compact.decodeAt(payload, pos);
805
+ params.queryId = QueryId.wrap(UnsignedUtils.toU64(queryIdRaw));
806
+ pos += bytesRead;
807
+
808
+ (params.maxResponseWeight, bytesRead) = WeightCodec.decodeAt(
809
+ payload,
810
+ pos
811
+ );
812
+ pos += bytesRead;
813
+ }
814
+
815
+ /// @notice Validates a `UnsubscribeVersion` instruction payload. Reverts if the instruction is not of type `UnsubscribeVersion` or the payload is invalid.
816
+ /// @param instruction The `Instruction` struct to validate, which must have type `UnsubscribeVersion`.
817
+ function asUnsubscribeVersion(
818
+ Instruction memory instruction
819
+ ) internal pure {
820
+ _assertVariant(instruction, InstructionVariant.UnsubscribeVersion);
821
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
822
+ }
823
+
824
+ /// @notice Extracts the decoded `BurnAssetParams` from a `BurnAsset` instruction. Reverts if the instruction is not of type `BurnAsset`.
825
+ /// @param instruction The `Instruction` struct to decode, which must have type `BurnAsset`.
826
+ /// @return params The decoded `BurnAssetParams` extracted from the instruction payload.
827
+ function asBurnAsset(
828
+ Instruction memory instruction
829
+ ) internal pure returns (BurnAssetParams memory params) {
830
+ _assertVariant(instruction, InstructionVariant.BurnAsset);
831
+ uint256 bytesRead;
832
+ (params.assets, bytesRead) = AssetsCodec.decode(instruction.payload);
833
+ }
834
+
835
+ /// @notice Extracts the decoded `ExpectAssetParams` from a `ExpectAsset` instruction. Reverts if the instruction is not of type `ExpectAsset`.
836
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExpectAsset`.
837
+ /// @return params The decoded `ExpectAssetParams` extracted from the instruction payload.
838
+ function asExpectAsset(
839
+ Instruction memory instruction
840
+ ) internal pure returns (ExpectAssetParams memory params) {
841
+ _assertVariant(instruction, InstructionVariant.ExpectAsset);
842
+ uint256 bytesRead;
843
+ (params.assets, bytesRead) = AssetsCodec.decode(instruction.payload);
844
+ }
845
+
846
+ /// @notice Extracts the decoded `ExpectOriginParams` from a `ExpectOrigin` instruction. Reverts if the instruction is not of type `ExpectOrigin`.
847
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExpectOrigin`.
848
+ /// @return params The decoded `ExpectOriginParams` extracted from the instruction payload.
849
+ function asExpectOrigin(
850
+ Instruction memory instruction
851
+ ) internal pure returns (ExpectOriginParams memory params) {
852
+ _assertVariant(instruction, InstructionVariant.ExpectOrigin);
853
+ bytes memory payload = instruction.payload;
854
+ uint256 pos;
855
+ uint256 bytesRead;
856
+
857
+ params.hasOrigin = Bool.decodeAt(payload, pos);
858
+ pos += 1;
859
+
860
+ if (params.hasOrigin) {
861
+ (params.origin, bytesRead) = LocationCodec.decodeAt(payload, pos);
862
+ pos += bytesRead;
863
+ }
864
+ }
865
+
866
+ /// @notice Extracts the decoded `ExpectErrorParams` from a `ExpectError` instruction. Reverts if the instruction is not of type `ExpectError`.
867
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExpectError`.
868
+ /// @return params The decoded `ExpectErrorParams` extracted from the instruction payload.
869
+ function asExpectError(
870
+ Instruction memory instruction
871
+ ) internal pure returns (ExpectErrorParams memory params) {
872
+ _assertVariant(instruction, InstructionVariant.ExpectError);
873
+ bytes memory payload = instruction.payload;
874
+ uint256 pos;
875
+ uint256 bytesRead;
876
+ uint256 value;
877
+
878
+ params.hasError = Bool.decodeAt(payload, pos);
879
+ pos += 1;
880
+
881
+ if (params.hasError) {
882
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
883
+ params.index = UnsignedUtils.toU32(value);
884
+ pos += bytesRead;
885
+
886
+ (params.err, bytesRead) = XcmErrorCodec.decodeAt(payload, pos);
887
+ pos += bytesRead;
888
+ }
889
+ }
890
+
891
+ /// @notice Extracts the decoded `ExpectTransactStatusParams` from a `ExpectTransactStatus` instruction. Reverts if the instruction is not of type `ExpectTransactStatus`.
892
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExpectTransactStatus`.
893
+ /// @return params The decoded `ExpectTransactStatusParams` extracted from the instruction payload.
894
+ function asExpectTransactStatus(
895
+ Instruction memory instruction
896
+ ) internal pure returns (ExpectTransactStatusParams memory params) {
897
+ _assertVariant(instruction, InstructionVariant.ExpectTransactStatus);
898
+ uint256 bytesRead;
899
+ (params.transactStatus, bytesRead) = MaybeErrorCodeCodec.decode(
900
+ instruction.payload
901
+ );
902
+ }
903
+
904
+ /// @notice Extracts the decoded `QueryPalletParams` from a `QueryPallet` instruction. Reverts if the instruction is not of type `QueryPallet`.
905
+ /// @param instruction The `Instruction` struct to decode, which must have type `QueryPallet`.
906
+ /// @return params The decoded `QueryPalletParams` extracted from the instruction payload.
907
+ function asQueryPallet(
908
+ Instruction memory instruction
909
+ ) internal pure returns (QueryPalletParams memory params) {
910
+ _assertVariant(instruction, InstructionVariant.QueryPallet);
911
+ bytes memory payload = instruction.payload;
912
+ uint256 pos;
913
+ uint256 bytesRead;
914
+
915
+ (params.moduleName, bytesRead) = Bytes.decodeAt(payload, pos);
916
+ pos += bytesRead;
917
+
918
+ (params.responseInfo, bytesRead) = QueryResponseInfoCodec.decodeAt(
919
+ payload,
920
+ pos
921
+ );
922
+ pos += bytesRead;
923
+ }
924
+
925
+ /// @notice Extracts the decoded `ExpectPalletParams` from a `ExpectPallet` instruction. Reverts if the instruction is not of type `ExpectPallet`.
926
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExpectPallet`.
927
+ /// @return params The decoded `ExpectPalletParams` extracted from the instruction payload.
928
+ function asExpectPallet(
929
+ Instruction memory instruction
930
+ ) internal pure returns (ExpectPalletParams memory params) {
931
+ _assertVariant(instruction, InstructionVariant.ExpectPallet);
932
+ bytes memory payload = instruction.payload;
933
+ uint256 pos;
934
+ uint256 bytesRead;
935
+ uint256 value;
936
+
937
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
938
+ params.index = UnsignedUtils.toU32(value);
939
+ pos += bytesRead;
940
+
941
+ (params.name, bytesRead) = Bytes.decodeAt(payload, pos);
942
+ pos += bytesRead;
943
+
944
+ (params.moduleName, bytesRead) = Bytes.decodeAt(payload, pos);
945
+ pos += bytesRead;
946
+
947
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
948
+ params.crateMajor = UnsignedUtils.toU32(value);
949
+ pos += bytesRead;
950
+
951
+ (value, bytesRead) = Compact.decodeAt(payload, pos);
952
+ params.minCrateMinor = UnsignedUtils.toU32(value);
953
+ pos += bytesRead;
954
+ }
955
+
956
+ /// @notice Extracts the decoded `ReportTransactStatusParams` from a `ReportTransactStatus` instruction. Reverts if the instruction is not of type `ReportTransactStatus`.
957
+ /// @param instruction The `Instruction` struct to decode, which must have type `ReportTransactStatus`.
958
+ /// @return params The decoded `ReportTransactStatusParams` extracted from the instruction payload.
959
+ function asReportTransactStatus(
960
+ Instruction memory instruction
961
+ ) internal pure returns (ReportTransactStatusParams memory params) {
962
+ _assertVariant(instruction, InstructionVariant.ReportTransactStatus);
963
+ uint256 bytesRead;
964
+ (params.responseInfo, bytesRead) = QueryResponseInfoCodec.decode(
965
+ instruction.payload
966
+ );
967
+ }
968
+
969
+ /// @notice Validates a `ClearTransactStatus` instruction payload. Reverts if the instruction is not of type `ClearTransactStatus` or the payload is invalid.
970
+ /// @param instruction The `Instruction` struct to validate, which must have type `ClearTransactStatus`.
971
+ function asClearTransactStatus(
972
+ Instruction memory instruction
973
+ ) internal pure {
974
+ _assertVariant(instruction, InstructionVariant.ClearTransactStatus);
975
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
976
+ }
977
+
978
+ /// @notice Extracts the decoded `UniversalOriginParams` from a `UniversalOrigin` instruction. Reverts if the instruction is not of type `UniversalOrigin`.
979
+ /// @param instruction The `Instruction` struct to decode, which must have type `UniversalOrigin`.
980
+ /// @return params The decoded `UniversalOriginParams` extracted from the instruction payload.
981
+ function asUniversalOrigin(
982
+ Instruction memory instruction
983
+ ) internal pure returns (UniversalOriginParams memory params) {
984
+ _assertVariant(instruction, InstructionVariant.UniversalOrigin);
985
+ uint256 bytesRead;
986
+ (params.junction, bytesRead) = JunctionCodec.decode(
987
+ instruction.payload
988
+ );
989
+ }
990
+
991
+ /// @notice Extracts the decoded `ExportMessageParams` from a `ExportMessage` instruction. Reverts if the instruction is not of type `ExportMessage`.
992
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExportMessage`.
993
+ /// @return params The decoded `ExportMessageParams` extracted from the instruction payload.
994
+ function asExportMessage(
995
+ Instruction memory instruction
996
+ ) internal pure returns (ExportMessageParams memory params) {
997
+ _assertVariant(instruction, InstructionVariant.ExportMessage);
998
+ bytes memory payload = instruction.payload;
999
+ uint256 pos;
1000
+ uint256 bytesRead;
1001
+
1002
+ (params.network, bytesRead) = NetworkIdCodec.decodeAt(payload, pos);
1003
+ pos += bytesRead;
1004
+
1005
+ (params.destination, bytesRead) = JunctionsCodec.decodeAt(payload, pos);
1006
+ pos += bytesRead;
1007
+
1008
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
1009
+ }
1010
+
1011
+ /// @notice Extracts the decoded `LockAssetParams` from a `LockAsset` instruction. Reverts if the instruction is not of type `LockAsset`.
1012
+ /// @param instruction The `Instruction` struct to decode, which must have type `LockAsset`.
1013
+ /// @return params The decoded `LockAssetParams` extracted from the instruction payload.
1014
+ function asLockAsset(
1015
+ Instruction memory instruction
1016
+ ) internal pure returns (LockAssetParams memory params) {
1017
+ _assertVariant(instruction, InstructionVariant.LockAsset);
1018
+ bytes memory payload = instruction.payload;
1019
+ uint256 pos;
1020
+ uint256 bytesRead;
1021
+
1022
+ (params.asset, bytesRead) = AssetCodec.decodeAt(payload, pos);
1023
+ pos += bytesRead;
1024
+
1025
+ (params.unlocker, bytesRead) = LocationCodec.decodeAt(payload, pos);
1026
+ pos += bytesRead;
1027
+ }
1028
+
1029
+ /// @notice Extracts the decoded `UnlockAssetParams` from a `UnlockAsset` instruction. Reverts if the instruction is not of type `UnlockAsset`.
1030
+ /// @param instruction The `Instruction` struct to decode, which must have type `UnlockAsset`.
1031
+ /// @return params The decoded `UnlockAssetParams` extracted from the instruction payload.
1032
+ function asUnlockAsset(
1033
+ Instruction memory instruction
1034
+ ) internal pure returns (UnlockAssetParams memory params) {
1035
+ _assertVariant(instruction, InstructionVariant.UnlockAsset);
1036
+ bytes memory payload = instruction.payload;
1037
+ uint256 pos;
1038
+ uint256 bytesRead;
1039
+
1040
+ (params.asset, bytesRead) = AssetCodec.decodeAt(payload, pos);
1041
+ pos += bytesRead;
1042
+
1043
+ (params.target, bytesRead) = LocationCodec.decodeAt(payload, pos);
1044
+ pos += bytesRead;
1045
+ }
1046
+
1047
+ /// @notice Extracts the decoded `NoteUnlockableParams` from a `NoteUnlockable` instruction. Reverts if the instruction is not of type `NoteUnlockable`.
1048
+ /// @param instruction The `Instruction` struct to decode, which must have type `NoteUnlockable`.
1049
+ /// @return params The decoded `NoteUnlockableParams` extracted from the instruction payload.
1050
+ function asNoteUnlockable(
1051
+ Instruction memory instruction
1052
+ ) internal pure returns (NoteUnlockableParams memory params) {
1053
+ _assertVariant(instruction, InstructionVariant.NoteUnlockable);
1054
+ bytes memory payload = instruction.payload;
1055
+ uint256 pos;
1056
+ uint256 bytesRead;
1057
+
1058
+ (params.asset, bytesRead) = AssetCodec.decodeAt(payload, pos);
1059
+ pos += bytesRead;
1060
+
1061
+ (params.owner, bytesRead) = LocationCodec.decodeAt(payload, pos);
1062
+ pos += bytesRead;
1063
+ }
1064
+
1065
+ /// @notice Extracts the decoded `RequestUnlockParams` from a `RequestUnlock` instruction. Reverts if the instruction is not of type `RequestUnlock`.
1066
+ /// @param instruction The `Instruction` struct to decode, which must have type `RequestUnlock`.
1067
+ /// @return params The decoded `RequestUnlockParams` extracted from the instruction payload.
1068
+ function asRequestUnlock(
1069
+ Instruction memory instruction
1070
+ ) internal pure returns (RequestUnlockParams memory params) {
1071
+ _assertVariant(instruction, InstructionVariant.RequestUnlock);
1072
+ bytes memory payload = instruction.payload;
1073
+ uint256 pos;
1074
+ uint256 bytesRead;
1075
+
1076
+ (params.asset, bytesRead) = AssetCodec.decodeAt(payload, pos);
1077
+ pos += bytesRead;
1078
+
1079
+ (params.locker, bytesRead) = LocationCodec.decodeAt(payload, pos);
1080
+ pos += bytesRead;
1081
+ }
1082
+
1083
+ /// @notice Extracts the decoded `SetFeesModeParams` from a `SetFeesMode` instruction. Reverts if the instruction is not of type `SetFeesMode`.
1084
+ /// @param instruction The `Instruction` struct to decode, which must have type `SetFeesMode`.
1085
+ /// @return params The decoded `SetFeesModeParams` extracted from the instruction payload.
1086
+ function asSetFeesMode(
1087
+ Instruction memory instruction
1088
+ ) internal pure returns (SetFeesModeParams memory params) {
1089
+ _assertVariant(instruction, InstructionVariant.SetFeesMode);
1090
+ if (instruction.payload.length != 1) revert InvalidInstructionPayload();
1091
+ params.jitWithdraw = Bool.decode(instruction.payload);
1092
+ }
1093
+
1094
+ /// @notice Extracts the decoded `SetTopicParams` from a `SetTopic` instruction. Reverts if the instruction is not of type `SetTopic`.
1095
+ /// @param instruction The `Instruction` struct to decode, which must have type `SetTopic`.
1096
+ /// @return params The decoded `SetTopicParams` extracted from the instruction payload.
1097
+ function asSetTopic(
1098
+ Instruction memory instruction
1099
+ ) internal pure returns (SetTopicParams memory params) {
1100
+ _assertVariant(instruction, InstructionVariant.SetTopic);
1101
+ if (instruction.payload.length != 32)
1102
+ revert InvalidInstructionPayload();
1103
+ params.topic = Bytes32.decode(instruction.payload);
1104
+ }
1105
+
1106
+ /// @notice Validates a `ClearTopic` instruction payload. Reverts if the instruction is not of type `ClearTopic` or the payload is invalid.
1107
+ /// @param instruction The `Instruction` struct to validate, which must have type `ClearTopic`.
1108
+ function asClearTopic(Instruction memory instruction) internal pure {
1109
+ _assertVariant(instruction, InstructionVariant.ClearTopic);
1110
+ if (instruction.payload.length != 0) revert InvalidInstructionPayload();
1111
+ }
1112
+
1113
+ /// @notice Extracts the decoded `AliasOriginParams` from a `AliasOrigin` instruction. Reverts if the instruction is not of type `AliasOrigin`.
1114
+ /// @param instruction The `Instruction` struct to decode, which must have type `AliasOrigin`.
1115
+ /// @return params The decoded `AliasOriginParams` extracted from the instruction payload.
1116
+ function asAliasOrigin(
1117
+ Instruction memory instruction
1118
+ ) internal pure returns (AliasOriginParams memory params) {
1119
+ _assertVariant(instruction, InstructionVariant.AliasOrigin);
1120
+ uint256 bytesRead;
1121
+ (params.location, bytesRead) = LocationCodec.decode(
1122
+ instruction.payload
1123
+ );
1124
+ }
1125
+
1126
+ /// @notice Extracts the decoded `UnpaidExecutionParams` from a `UnpaidExecution` instruction. Reverts if the instruction is not of type `UnpaidExecution`.
1127
+ /// @param instruction The `Instruction` struct to decode, which must have type `UnpaidExecution`.
1128
+ /// @return params The decoded `UnpaidExecutionParams` extracted from the instruction payload.
1129
+ function asUnpaidExecution(
1130
+ Instruction memory instruction
1131
+ ) internal pure returns (UnpaidExecutionParams memory params) {
1132
+ _assertVariant(instruction, InstructionVariant.UnpaidExecution);
1133
+ bytes memory payload = instruction.payload;
1134
+ uint256 pos;
1135
+ uint256 bytesRead;
1136
+
1137
+ (params.weightLimit, bytesRead) = WeightLimitCodec.decodeAt(
1138
+ payload,
1139
+ pos
1140
+ );
1141
+ pos += bytesRead;
1142
+
1143
+ params.hasCheckOrigin = Bool.decodeAt(payload, pos);
1144
+ pos += 1;
1145
+
1146
+ if (params.hasCheckOrigin) {
1147
+ (params.checkOrigin, bytesRead) = LocationCodec.decodeAt(
1148
+ payload,
1149
+ pos
1150
+ );
1151
+ pos += bytesRead;
1152
+ }
1153
+ }
1154
+
1155
+ /// @notice Extracts the decoded `PayFeesParams` from a `PayFees` instruction. Reverts if the instruction is not of type `PayFees`.
1156
+ /// @param instruction The `Instruction` struct to decode, which must have type `PayFees`.
1157
+ /// @return params The decoded `PayFeesParams` extracted from the instruction payload.
1158
+ function asPayFees(
1159
+ Instruction memory instruction
1160
+ ) internal pure returns (PayFeesParams memory params) {
1161
+ _assertVariant(instruction, InstructionVariant.PayFees);
1162
+ uint256 bytesRead;
1163
+ (params.asset, bytesRead) = AssetCodec.decode(instruction.payload);
1164
+ }
1165
+
1166
+ /// @notice Extracts the decoded `InitiateTransferParams` from a `InitiateTransfer` instruction. Reverts if the instruction is not of type `InitiateTransfer`.
1167
+ /// @param instruction The `Instruction` struct to decode, which must have type `InitiateTransfer`.
1168
+ /// @return params The decoded `InitiateTransferParams` extracted from the instruction payload.
1169
+ function asInitiateTransfer(
1170
+ Instruction memory instruction
1171
+ ) internal pure returns (InitiateTransferParams memory params) {
1172
+ _assertVariant(instruction, InstructionVariant.InitiateTransfer);
1173
+ bytes memory payload = instruction.payload;
1174
+ uint256 pos;
1175
+ uint256 bytesRead;
1176
+ uint256 assetsCount;
1177
+
1178
+ (params.destination, bytesRead) = LocationCodec.decodeAt(payload, pos);
1179
+ pos += bytesRead;
1180
+
1181
+ params.hasRemoteFees = Bool.decodeAt(payload, pos);
1182
+ pos += 1;
1183
+
1184
+ if (params.hasRemoteFees) {
1185
+ (params.remoteFees, bytesRead) = AssetTransferFilterCodec.decodeAt(
1186
+ payload,
1187
+ pos
1188
+ );
1189
+ pos += bytesRead;
1190
+ }
1191
+
1192
+ params.preserveOrigin = Bool.decodeAt(payload, pos);
1193
+ pos += 1;
1194
+
1195
+ (assetsCount, bytesRead) = Compact.decodeAt(payload, pos);
1196
+ if (assetsCount > MAX_ASSET_TRANSFER_FILTERS) {
1197
+ revert InvalidInstructionPayload();
1198
+ }
1199
+ pos += bytesRead;
1200
+
1201
+ params.assets = new AssetTransferFilter[](assetsCount);
1202
+ for (uint256 i = 0; i < assetsCount; ++i) {
1203
+ (params.assets[i], bytesRead) = AssetTransferFilterCodec.decodeAt(
1204
+ payload,
1205
+ pos
1206
+ );
1207
+ pos += bytesRead;
1208
+ }
1209
+
1210
+ (params.remoteXcm, bytesRead) = Bytes.decodeAt(payload, pos);
1211
+ pos += bytesRead;
1212
+ }
1213
+
1214
+ /// @notice Extracts the decoded `ExecuteWithOriginParams` from a `ExecuteWithOrigin` instruction. Reverts if the instruction is not of type `ExecuteWithOrigin`.
1215
+ /// @param instruction The `Instruction` struct to decode, which must have type `ExecuteWithOrigin`.
1216
+ /// @return params The decoded `ExecuteWithOriginParams` extracted from the instruction payload.
1217
+ function asExecuteWithOrigin(
1218
+ Instruction memory instruction
1219
+ ) internal pure returns (ExecuteWithOriginParams memory params) {
1220
+ _assertVariant(instruction, InstructionVariant.ExecuteWithOrigin);
1221
+ bytes memory payload = instruction.payload;
1222
+ uint256 pos;
1223
+ uint256 bytesRead;
1224
+
1225
+ params.hasDescendantOrigin = Bool.decodeAt(payload, pos);
1226
+ pos += 1;
1227
+
1228
+ if (params.hasDescendantOrigin) {
1229
+ (params.descendantOrigin, bytesRead) = JunctionsCodec.decodeAt(
1230
+ payload,
1231
+ pos
1232
+ );
1233
+ pos += bytesRead;
1234
+ }
1235
+
1236
+ (params.xcm, pos) = _decodeXcmAt(payload, pos);
1237
+ }
1238
+
1239
+ /// @notice Extracts the decoded `SetHintsParams` from a `SetHints` instruction. Reverts if the instruction is not of type `SetHints`.
1240
+ /// @param instruction The `Instruction` struct to decode, which must have type `SetHints`.
1241
+ /// @return params The decoded `SetHintsParams` extracted from the instruction payload.
1242
+ function asSetHints(
1243
+ Instruction memory instruction
1244
+ ) internal pure returns (SetHintsParams memory params) {
1245
+ _assertVariant(instruction, InstructionVariant.SetHints);
1246
+ bytes memory payload = instruction.payload;
1247
+ uint256 pos;
1248
+ uint256 bytesRead;
1249
+ uint256 hintsCount;
1250
+
1251
+ (hintsCount, bytesRead) = Compact.decodeAt(payload, pos);
1252
+ if (hintsCount > HINT_NUM_VARIANTS) {
1253
+ revert InvalidInstructionPayload();
1254
+ }
1255
+ pos += bytesRead;
1256
+
1257
+ params.hints = new Hint[](hintsCount);
1258
+ for (uint256 i = 0; i < hintsCount; ++i) {
1259
+ (params.hints[i], bytesRead) = HintCodec.decodeAt(payload, pos);
1260
+ pos += bytesRead;
1261
+ }
1262
+ }
1263
+
308
1264
  /// @notice Returns the encoded size of an XCM byte sequence at offset.
309
1265
  /// @dev XCM encodes as `Vec<Instruction>`: compact count followed by encoded instructions.
310
1266
  function _xcmEncodedSizeAt(
@@ -318,4 +1274,22 @@ library InstructionCodec {
318
1274
  }
319
1275
  return pos - offset;
320
1276
  }
1277
+
1278
+ function _assertVariant(
1279
+ Instruction memory instruction,
1280
+ InstructionVariant expectedType
1281
+ ) private pure {
1282
+ if (instruction.variant != expectedType) {
1283
+ revert InvalidInstructionVariant(uint8(instruction.variant));
1284
+ }
1285
+ }
1286
+
1287
+ function _decodeXcmAt(
1288
+ bytes memory payload,
1289
+ uint256 offset
1290
+ ) private pure returns (bytes memory xcm, uint256 nextOffset) {
1291
+ uint256 xcmLength = _xcmEncodedSizeAt(payload, offset);
1292
+ xcm = BytesUtils.copy(payload, offset, xcmLength);
1293
+ nextOffset = offset + xcmLength;
1294
+ }
321
1295
  }