I have a custom pallet that is tightly coupled to the utility pallet. I am trying to call the batch function to perform a batch of balance transfers. The tests of the utility pallet (that create their own test runtime) construct a Vec of utility batch RuntimeCalls with the syntax:
Utility::batch(
RuntimeOrigin::root(),
vec![
RuntimeCall::Balances(BalancesCall::force_transfer {
source: 1,
dest: 2,
value: 5
}),
RuntimeCall::Balances(BalancesCall::force_transfer {
source: 1,
dest: 2,
value: 5
}),
]
);
If I use this in my (tightly coupled to utility pallet) custom pallet like so, :
let disp_result =
pallet_utility::Pallet::<T>::batch(
origin,
vec![
RuntimeCall::Balances(Call::force_transfer {
source: 1,
dest: 2,
value: 5
}),
RuntimeCall::Balances(Call::force_transfer {
source: 1,
dest: 2,
value: 5
}),
]
);
the rust compiler gives me the error:
error[E0433]: failed to resolve: use of undeclared type `RuntimeCall`
--> pallets/clipbet2/src/lib.rs:364:6
|
364 | RuntimeCall::Balances(Call::force_transfer {
| ^^^^^^^^^^^ use of undeclared type `RuntimeCall`
If I specify the pallet Config such as: pallet::Config::RuntimeCall::Balances(Call::force_transfer
The compiler gives me:
error[E0223]: ambiguous associated type
--> pallets/clipbet2/src/lib.rs:364:6
|
364 | pallet::Config::RuntimeCall::Balances(Call::force_transfer {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as pallet::Config>::RuntimeCall`
I realize it doesn't make sense to use the config trait and generics (such as <T as Config>::RuntimeCall
) as I'm using the concrete Balances RuntimeCall to edit it's specific set of parameters.
How can I get this to work?
A whole pallet (that does nothing - with all irrelevant code removed) may look like this:
#![cfg_attr(not(feature = "std"), no_std)]
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: frame_system::Config + pallet_utility::Config + pallet_balances::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
SomethingStored { something: u32, who: T::AccountId },
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(10_000)]
pub fn do_something(origin: OriginFor<T>) -> DispatchResult {
let disp_result =
pallet_utility::Pallet::<T>::batch(
origin,
vec![
RuntimeCall::Balances(pallet_balances::Call::transfer {
dest: 2,
value: 5
}),
RuntimeCall::Balances(pallet_balances::Call::transfer {
dest: 2,
value: 5
}),
]
);
Ok(())
}
}
}
pallet_utility::Pallet::<T>::batch(origin, call);
where origin and call are supplied directly from the front end template parameters.transfer
function of your underlyingCurrency
just like in the Lottery.