1#![cfg_attr(not(feature = "std"), no_std)]
4#![allow(clippy::large_enum_variant)]
5
6use frame_support::{pallet_prelude::*, traits::EnsureOrigin};
7use frame_system::pallet_prelude::*;
8use sp_std::boxed::Box;
9use xcm::{v5::prelude::*, VersionedLocation, VersionedXcm};
10
11pub use module::*;
12
13#[frame_support::pallet]
14pub mod module {
15 use super::*;
16
17 #[pallet::config]
18 pub trait Config: frame_system::Config + pallet_xcm::Config {
19 type SovereignOrigin: EnsureOrigin<<Self as frame_system::Config>::RuntimeOrigin>;
23 }
24
25 #[pallet::pallet]
26 pub struct Pallet<T>(_);
27
28 #[pallet::event]
29 #[pallet::generate_deposit(pub(super) fn deposit_event)]
30 pub enum Event<T: Config> {
31 Sent { to: Location, message: Xcm<()> },
33 }
34
35 #[pallet::error]
36 pub enum Error<T> {
37 Unreachable,
40 SendFailure,
43 BadVersion,
46 }
47
48 #[pallet::call]
49 impl<T: Config> Pallet<T> {
50 #[pallet::call_index(0)]
52 #[pallet::weight(Weight::from_parts(100_000_000, 0))]
54 pub fn send_as_sovereign(
55 origin: OriginFor<T>,
56 dest: Box<VersionedLocation>,
57 message: Box<VersionedXcm<()>>,
58 ) -> DispatchResult {
59 let _ = T::SovereignOrigin::ensure_origin(origin)?;
60 let dest = Location::try_from(*dest).map_err(|()| Error::<T>::BadVersion)?;
61 let message: Xcm<()> = (*message).try_into().map_err(|()| Error::<T>::BadVersion)?;
62
63 pallet_xcm::Pallet::<T>::send_xcm(Here, dest.clone(), message.clone()).map_err(|e| match e {
64 SendError::Unroutable => Error::<T>::Unreachable,
65 _ => Error::<T>::SendFailure,
66 })?;
67 Self::deposit_event(Event::Sent { to: dest, message });
68 Ok(())
69 }
70 }
71}