1use parity_scale_codec::{Decode, Encode};
20use precompile_utils::prelude::*;
21use sp_core::{H256, U256};
22use sp_std::vec::Vec;
23
24#[derive(Encode, Decode, Debug)]
27pub enum VersionedLocation {
28 #[codec(index = 1)] V2(deprecated_xcm_v2::MultiLocationV2),
30 #[codec(index = 3)]
31 V3(xcm::v3::MultiLocation),
32 #[codec(index = 4)]
33 V4(xcm::v4::Location),
34 #[codec(index = 5)]
35 V5(xcm::v5::Location),
36}
37
38impl TryFrom<VersionedLocation> for xcm::latest::Location {
39 type Error = ();
40
41 fn try_from(value: VersionedLocation) -> Result<Self, Self::Error> {
42 match value {
43 VersionedLocation::V2(location) => {
44 xcm::VersionedLocation::V3(location.try_into()?).try_into()
45 }
46 VersionedLocation::V3(location) => xcm::VersionedLocation::V3(location).try_into(),
47 VersionedLocation::V4(location) => xcm::VersionedLocation::V4(location).try_into(),
48 VersionedLocation::V5(location) => xcm::VersionedLocation::V5(location).try_into(),
49 }
50 }
51}
52
53#[derive(Encode, Decode, Debug)]
57pub struct XcmRoutingUserAction {
58 pub destination: VersionedLocation,
59}
60
61#[derive(Encode, Decode, Debug)]
64pub struct XcmRoutingUserActionWithFee {
65 pub destination: VersionedLocation,
66 pub fee: U256,
67}
68
69#[derive(Encode, Decode, Debug)]
72#[non_exhaustive]
73pub enum VersionedUserAction {
74 V1(XcmRoutingUserAction),
75 V2(XcmRoutingUserActionWithFee),
76}
77
78#[derive(Debug, solidity::Codec)]
84pub struct WormholeVM {
85 pub version: u8,
86 pub timestamp: u32,
87 pub nonce: u32,
88 pub emitter_chain_id: u16,
89 pub emitter_address: H256,
90 pub sequence: u64,
91 pub consistency_level: u8,
92 pub payload: BoundedBytes<crate::GetCallDataLimit>,
93
94 pub guardian_set_index: u32,
95 pub signatures: Vec<WormholeSignature>, pub hash: H256,
97}
98
99#[derive(Debug, solidity::Codec)]
101pub struct WormholeSignature {
102 pub r: U256,
103 pub s: U256,
104 pub v: u8,
105 pub guardian_index: u8,
106}
107
108#[derive(Debug, solidity::Codec)]
112pub struct WormholeTransferWithPayloadData {
113 pub payload_id: u8,
114 pub amount: U256,
115 pub token_address: H256,
116 pub token_chain: u16,
117 pub to: H256,
118 pub to_chain: u16,
119 pub from_address: H256,
120 pub payload: BoundedBytes<crate::GetCallDataLimit>,
121}
122
123mod deprecated_xcm_v2 {
125 use super::*;
126
127 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
128 pub struct MultiLocationV2 {
129 pub parents: u8,
130 pub interior: JunctionsV2,
131 }
132
133 impl TryFrom<MultiLocationV2> for xcm::v3::MultiLocation {
134 type Error = ();
135
136 fn try_from(value: MultiLocationV2) -> Result<Self, Self::Error> {
137 Ok(xcm::v3::MultiLocation::new(
138 value.parents,
139 xcm::v3::Junctions::try_from(value.interior)?,
140 ))
141 }
142 }
143
144 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
145 pub enum JunctionsV2 {
146 Here,
148 X1(JunctionV2),
150 X2(JunctionV2, JunctionV2),
152 X3(JunctionV2, JunctionV2, JunctionV2),
154 X4(JunctionV2, JunctionV2, JunctionV2, JunctionV2),
156 X5(JunctionV2, JunctionV2, JunctionV2, JunctionV2, JunctionV2),
158 X6(
160 JunctionV2,
161 JunctionV2,
162 JunctionV2,
163 JunctionV2,
164 JunctionV2,
165 JunctionV2,
166 ),
167 X7(
169 JunctionV2,
170 JunctionV2,
171 JunctionV2,
172 JunctionV2,
173 JunctionV2,
174 JunctionV2,
175 JunctionV2,
176 ),
177 X8(
179 JunctionV2,
180 JunctionV2,
181 JunctionV2,
182 JunctionV2,
183 JunctionV2,
184 JunctionV2,
185 JunctionV2,
186 JunctionV2,
187 ),
188 }
189
190 impl TryFrom<JunctionsV2> for xcm::v3::Junctions {
191 type Error = ();
192
193 fn try_from(value: JunctionsV2) -> Result<Self, Self::Error> {
194 use JunctionsV2::*;
195 Ok(match value {
196 Here => Self::Here,
197 X1(j1) => Self::X1(j1.try_into()?),
198 X2(j1, j2) => Self::X2(j1.try_into()?, j2.try_into()?),
199 X3(j1, j2, j3) => Self::X3(j1.try_into()?, j2.try_into()?, j3.try_into()?),
200 X4(j1, j2, j3, j4) => Self::X4(
201 j1.try_into()?,
202 j2.try_into()?,
203 j3.try_into()?,
204 j4.try_into()?,
205 ),
206 X5(j1, j2, j3, j4, j5) => Self::X5(
207 j1.try_into()?,
208 j2.try_into()?,
209 j3.try_into()?,
210 j4.try_into()?,
211 j5.try_into()?,
212 ),
213 X6(j1, j2, j3, j4, j5, j6) => Self::X6(
214 j1.try_into()?,
215 j2.try_into()?,
216 j3.try_into()?,
217 j4.try_into()?,
218 j5.try_into()?,
219 j6.try_into()?,
220 ),
221 X7(j1, j2, j3, j4, j5, j6, j7) => Self::X7(
222 j1.try_into()?,
223 j2.try_into()?,
224 j3.try_into()?,
225 j4.try_into()?,
226 j5.try_into()?,
227 j6.try_into()?,
228 j7.try_into()?,
229 ),
230 X8(j1, j2, j3, j4, j5, j6, j7, j8) => Self::X8(
231 j1.try_into()?,
232 j2.try_into()?,
233 j3.try_into()?,
234 j4.try_into()?,
235 j5.try_into()?,
236 j6.try_into()?,
237 j7.try_into()?,
238 j8.try_into()?,
239 ),
240 })
241 }
242 }
243
244 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
245 pub enum JunctionV2 {
246 Parachain(#[codec(compact)] u32),
250 AccountId32 { network: NetworkIdV2, id: [u8; 32] },
255 AccountIndex64 {
260 network: NetworkIdV2,
261 #[codec(compact)]
262 index: u64,
263 },
264 AccountKey20 { network: NetworkIdV2, key: [u8; 20] },
269 PalletInstance(u8),
273 GeneralIndex(#[codec(compact)] u128),
279 GeneralKey(sp_runtime::WeakBoundedVec<u8, sp_core::ConstU32<32>>),
285 OnlyChild,
289 }
292
293 impl TryFrom<JunctionV2> for xcm::v3::Junction {
294 type Error = ();
295
296 fn try_from(value: JunctionV2) -> Result<Self, ()> {
297 use JunctionV2::*;
298 Ok(match value {
299 Parachain(id) => Self::Parachain(id),
300 AccountId32 { network, id } => Self::AccountId32 {
301 network: network.into(),
302 id,
303 },
304 AccountIndex64 { network, index } => Self::AccountIndex64 {
305 network: network.into(),
306 index,
307 },
308 AccountKey20 { network, key } => Self::AccountKey20 {
309 network: network.into(),
310 key,
311 },
312 PalletInstance(index) => Self::PalletInstance(index),
313 GeneralIndex(id) => Self::GeneralIndex(id),
314 GeneralKey(key) => match key.len() {
315 len @ 0..=32 => Self::GeneralKey {
316 length: len as u8,
317 data: {
318 let mut data = [0u8; 32];
319 data[..len].copy_from_slice(&key[..]);
320 data
321 },
322 },
323 _ => return Err(()),
324 },
325 OnlyChild => Self::OnlyChild,
326 })
327 }
328 }
329
330 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
331 pub enum NetworkIdV2 {
332 Any,
334 Named(sp_runtime::WeakBoundedVec<u8, sp_core::ConstU32<32>>),
336 Polkadot,
338 Kusama,
340 }
341
342 impl From<NetworkIdV2> for Option<xcm::v3::NetworkId> {
343 fn from(old: NetworkIdV2) -> Option<xcm::v3::NetworkId> {
344 use NetworkIdV2::*;
345 match old {
346 Any => None,
347 Named(_) => None,
348 Polkadot => Some(xcm::v3::NetworkId::Polkadot),
349 Kusama => Some(xcm::v3::NetworkId::Kusama),
350 }
351 }
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 use super::*;
358
359 #[test]
360 fn test_versioned_user_action_decode() {
361 let encoded_payload = hex::decode(
364 "0001010200c91f0100c862582c20ec0a5429c6d2239da9908f4b6c93ab4e2589784f8a5452f65f0e45",
365 )
366 .unwrap();
367
368 let _versioned_user_action = VersionedUserAction::decode(&mut &encoded_payload[..])
370 .expect("Failed to decode VersionedUserAction");
371 }
372}