solidity-scale-codec 2.1.1 → 2.1.2

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