Skip to content

Commit a730f79

Browse files
authored
XcmTransfer Trait (#892)
* Add more methods on XcmTransfer trait * Add Transferred for XcmTransfer * fix tests * fix clippy
1 parent 6df51b3 commit a730f79

File tree

2 files changed

+104
-30
lines changed

2 files changed

+104
-30
lines changed

traits/src/xcm_transfer.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,67 @@
1-
use frame_support::dispatch::DispatchResult;
1+
use frame_support::dispatch::DispatchError;
2+
use sp_std::vec::Vec;
23
use xcm::v3::prelude::*;
34

5+
pub struct Transferred<AccountId> {
6+
pub sender: AccountId,
7+
pub assets: MultiAssets,
8+
pub fee: MultiAsset,
9+
pub dest: MultiLocation,
10+
}
11+
412
/// Abstraction over cross-chain token transfers.
513
pub trait XcmTransfer<AccountId, Balance, CurrencyId> {
6-
/// Transfer native currencies.
14+
/// Transfer local assets with given `CurrencyId` and `Amount`.
715
fn transfer(
816
who: AccountId,
917
currency_id: CurrencyId,
1018
amount: Balance,
1119
dest: MultiLocation,
1220
dest_weight_limit: WeightLimit,
13-
) -> DispatchResult;
21+
) -> Result<Transferred<AccountId>, DispatchError>;
1422

15-
/// Transfer `MultiAsset`
16-
fn transfer_multi_asset(
23+
/// Transfer `MultiAsset` assets.
24+
fn transfer_multiasset(
1725
who: AccountId,
1826
asset: MultiAsset,
1927
dest: MultiLocation,
2028
dest_weight_limit: WeightLimit,
21-
) -> DispatchResult;
29+
) -> Result<Transferred<AccountId>, DispatchError>;
2230

23-
/// Transfer `MultiAssetWithFee`
31+
/// Transfer native currencies specifying the fee and amount as separate.
32+
fn transfer_with_fee(
33+
who: AccountId,
34+
currency_id: CurrencyId,
35+
amount: Balance,
36+
fee: Balance,
37+
dest: MultiLocation,
38+
dest_weight_limit: WeightLimit,
39+
) -> Result<Transferred<AccountId>, DispatchError>;
40+
41+
/// Transfer `MultiAsset` specifying the fee and amount as separate.
2442
fn transfer_multiasset_with_fee(
2543
who: AccountId,
2644
asset: MultiAsset,
2745
fee: MultiAsset,
2846
dest: MultiLocation,
2947
dest_weight_limit: WeightLimit,
30-
) -> DispatchResult;
48+
) -> Result<Transferred<AccountId>, DispatchError>;
49+
50+
/// Transfer several currencies specifying the item to be used as fee.
51+
fn transfer_multicurrencies(
52+
who: AccountId,
53+
currencies: Vec<(CurrencyId, Balance)>,
54+
fee_item: u32,
55+
dest: MultiLocation,
56+
dest_weight_limit: WeightLimit,
57+
) -> Result<Transferred<AccountId>, DispatchError>;
58+
59+
/// Transfer several `MultiAsset` specifying the item to be used as fee.
60+
fn transfer_multiassets(
61+
who: AccountId,
62+
assets: MultiAssets,
63+
fee: MultiAsset,
64+
dest: MultiLocation,
65+
dest_weight_limit: WeightLimit,
66+
) -> Result<Transferred<AccountId>, DispatchError>;
3167
}

xtokens/src/lib.rs

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use xcm_executor::traits::WeightBounds;
5555
pub use module::*;
5656
use orml_traits::{
5757
location::{Parse, Reserve},
58+
xcm_transfer::Transferred,
5859
GetByKey, XcmTransfer,
5960
};
6061

@@ -220,7 +221,7 @@ pub mod module {
220221
) -> DispatchResult {
221222
let who = ensure_signed(origin)?;
222223
let dest: MultiLocation = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
223-
Self::do_transfer(who, currency_id, amount, dest, dest_weight_limit)
224+
Self::do_transfer(who, currency_id, amount, dest, dest_weight_limit).map(|_| ())
224225
}
225226

226227
/// Transfer `MultiAsset`.
@@ -246,7 +247,7 @@ pub mod module {
246247
let who = ensure_signed(origin)?;
247248
let asset: MultiAsset = (*asset).try_into().map_err(|()| Error::<T>::BadVersion)?;
248249
let dest: MultiLocation = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
249-
Self::do_transfer_multiasset(who, asset, dest, dest_weight_limit)
250+
Self::do_transfer_multiasset(who, asset, dest, dest_weight_limit).map(|_| ())
250251
}
251252

252253
/// Transfer native currencies specifying the fee and amount as
@@ -283,7 +284,7 @@ pub mod module {
283284
let who = ensure_signed(origin)?;
284285
let dest: MultiLocation = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
285286

286-
Self::do_transfer_with_fee(who, currency_id, amount, fee, dest, dest_weight_limit)
287+
Self::do_transfer_with_fee(who, currency_id, amount, fee, dest, dest_weight_limit).map(|_| ())
287288
}
288289

289290
/// Transfer `MultiAsset` specifying the fee and amount as separate.
@@ -321,7 +322,7 @@ pub mod module {
321322
let fee: MultiAsset = (*fee).try_into().map_err(|()| Error::<T>::BadVersion)?;
322323
let dest: MultiLocation = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
323324

324-
Self::do_transfer_multiasset_with_fee(who, asset, fee, dest, dest_weight_limit)
325+
Self::do_transfer_multiasset_with_fee(who, asset, fee, dest, dest_weight_limit).map(|_| ())
325326
}
326327

327328
/// Transfer several currencies specifying the item to be used as fee
@@ -351,7 +352,7 @@ pub mod module {
351352
let who = ensure_signed(origin)?;
352353
let dest: MultiLocation = (*dest).try_into().map_err(|()| Error::<T>::BadVersion)?;
353354

354-
Self::do_transfer_multicurrencies(who, currencies, fee_item, dest, dest_weight_limit)
355+
Self::do_transfer_multicurrencies(who, currencies, fee_item, dest, dest_weight_limit).map(|_| ())
355356
}
356357

357358
/// Transfer several `MultiAsset` specifying the item to be used as fee
@@ -385,7 +386,7 @@ pub mod module {
385386
// We first grab the fee
386387
let fee: &MultiAsset = assets.get(fee_item as usize).ok_or(Error::<T>::AssetIndexNonExistent)?;
387388

388-
Self::do_transfer_multiassets(who, assets.clone(), fee.clone(), dest, dest_weight_limit)
389+
Self::do_transfer_multiassets(who, assets.clone(), fee.clone(), dest, dest_weight_limit).map(|_| ())
389390
}
390391
}
391392

@@ -396,7 +397,7 @@ pub mod module {
396397
amount: T::Balance,
397398
dest: MultiLocation,
398399
dest_weight_limit: WeightLimit,
399-
) -> DispatchResult {
400+
) -> Result<Transferred<T::AccountId>, DispatchError> {
400401
let location: MultiLocation =
401402
T::CurrencyIdConvert::convert(currency_id).ok_or(Error::<T>::NotCrossChainTransferableCurrency)?;
402403

@@ -417,7 +418,7 @@ pub mod module {
417418
fee: T::Balance,
418419
dest: MultiLocation,
419420
dest_weight_limit: WeightLimit,
420-
) -> DispatchResult {
421+
) -> Result<Transferred<T::AccountId>, DispatchError> {
421422
let location: MultiLocation =
422423
T::CurrencyIdConvert::convert(currency_id).ok_or(Error::<T>::NotCrossChainTransferableCurrency)?;
423424

@@ -444,7 +445,7 @@ pub mod module {
444445
asset: MultiAsset,
445446
dest: MultiLocation,
446447
dest_weight_limit: WeightLimit,
447-
) -> DispatchResult {
448+
) -> Result<Transferred<T::AccountId>, DispatchError> {
448449
Self::do_transfer_multiassets(who, vec![asset.clone()].into(), asset, dest, dest_weight_limit)
449450
}
450451

@@ -454,15 +455,13 @@ pub mod module {
454455
fee: MultiAsset,
455456
dest: MultiLocation,
456457
dest_weight_limit: WeightLimit,
457-
) -> DispatchResult {
458+
) -> Result<Transferred<T::AccountId>, DispatchError> {
458459
// Push contains saturated addition, so we should be able to use it safely
459460
let mut assets = MultiAssets::new();
460461
assets.push(asset);
461462
assets.push(fee.clone());
462463

463-
Self::do_transfer_multiassets(who, assets, fee, dest, dest_weight_limit)?;
464-
465-
Ok(())
464+
Self::do_transfer_multiassets(who, assets, fee, dest, dest_weight_limit)
466465
}
467466

468467
fn do_transfer_multicurrencies(
@@ -471,7 +470,7 @@ pub mod module {
471470
fee_item: u32,
472471
dest: MultiLocation,
473472
dest_weight_limit: WeightLimit,
474-
) -> DispatchResult {
473+
) -> Result<Transferred<T::AccountId>, DispatchError> {
475474
ensure!(
476475
currencies.len() <= T::MaxAssetsForTransfer::get(),
477476
Error::<T>::TooManyAssetsBeingSent
@@ -513,7 +512,7 @@ pub mod module {
513512
fee: MultiAsset,
514513
dest: MultiLocation,
515514
dest_weight_limit: WeightLimit,
516-
) -> DispatchResult {
515+
) -> Result<Transferred<T::AccountId>, DispatchError> {
517516
ensure!(
518517
assets.len() <= T::MaxAssetsForTransfer::get(),
519518
Error::<T>::TooManyAssetsBeingSent
@@ -621,13 +620,18 @@ pub mod module {
621620
}
622621

623622
Self::deposit_event(Event::<T>::TransferredMultiAssets {
623+
sender: who.clone(),
624+
assets: assets.clone(),
625+
fee: fee.clone(),
626+
dest,
627+
});
628+
629+
Ok(Transferred {
624630
sender: who,
625631
assets,
626632
fee,
627633
dest,
628-
});
629-
630-
Ok(())
634+
})
631635
}
632636

633637
/// Execute and send xcm with given assets and fee to dest chain or
@@ -947,30 +951,64 @@ pub mod module {
947951
amount: T::Balance,
948952
dest: MultiLocation,
949953
dest_weight_limit: WeightLimit,
950-
) -> DispatchResult {
954+
) -> Result<Transferred<T::AccountId>, DispatchError> {
951955
Self::do_transfer(who, currency_id, amount, dest, dest_weight_limit)
952956
}
953957

954958
#[require_transactional]
955-
fn transfer_multi_asset(
959+
fn transfer_multiasset(
956960
who: T::AccountId,
957961
asset: MultiAsset,
958962
dest: MultiLocation,
959963
dest_weight_limit: WeightLimit,
960-
) -> DispatchResult {
964+
) -> Result<Transferred<T::AccountId>, DispatchError> {
961965
Self::do_transfer_multiasset(who, asset, dest, dest_weight_limit)
962966
}
963967

968+
#[require_transactional]
969+
fn transfer_with_fee(
970+
who: T::AccountId,
971+
currency_id: T::CurrencyId,
972+
amount: T::Balance,
973+
fee: T::Balance,
974+
dest: MultiLocation,
975+
dest_weight_limit: WeightLimit,
976+
) -> Result<Transferred<T::AccountId>, DispatchError> {
977+
Self::do_transfer_with_fee(who, currency_id, amount, fee, dest, dest_weight_limit)
978+
}
979+
964980
#[require_transactional]
965981
fn transfer_multiasset_with_fee(
966982
who: T::AccountId,
967983
asset: MultiAsset,
968984
fee: MultiAsset,
969985
dest: MultiLocation,
970986
dest_weight_limit: WeightLimit,
971-
) -> DispatchResult {
987+
) -> Result<Transferred<T::AccountId>, DispatchError> {
972988
Self::do_transfer_multiasset_with_fee(who, asset, fee, dest, dest_weight_limit)
973989
}
990+
991+
#[require_transactional]
992+
fn transfer_multicurrencies(
993+
who: T::AccountId,
994+
currencies: Vec<(T::CurrencyId, T::Balance)>,
995+
fee_item: u32,
996+
dest: MultiLocation,
997+
dest_weight_limit: WeightLimit,
998+
) -> Result<Transferred<T::AccountId>, DispatchError> {
999+
Self::do_transfer_multicurrencies(who, currencies, fee_item, dest, dest_weight_limit)
1000+
}
1001+
1002+
#[require_transactional]
1003+
fn transfer_multiassets(
1004+
who: T::AccountId,
1005+
assets: MultiAssets,
1006+
fee: MultiAsset,
1007+
dest: MultiLocation,
1008+
dest_weight_limit: WeightLimit,
1009+
) -> Result<Transferred<T::AccountId>, DispatchError> {
1010+
Self::do_transfer_multiassets(who, assets, fee, dest, dest_weight_limit)
1011+
}
9741012
}
9751013
}
9761014

0 commit comments

Comments
 (0)