#![allow(unused)]
use crate::AccountAction;
use crate::{AbstractSdkResult, TransferInterface};
use abstract_core::objects::AnsAsset;
use cosmwasm_std::{Addr, CosmosMsg, Deps, StdResult, Uint128};
pub trait SplitterInterface: TransferInterface {
fn splitter<'a>(&'a self, deps: Deps<'a>) -> Splitter<Self> {
Splitter { base: self, deps }
}
}
impl<T> SplitterInterface for T where T: TransferInterface {}
#[derive(Clone)]
pub struct Splitter<'a, T: SplitterInterface> {
base: &'a T,
deps: Deps<'a>,
}
impl<'a, T: SplitterInterface> Splitter<'a, T> {
pub fn split(&self, asset: AnsAsset, receivers: &[Addr]) -> AbstractSdkResult<AccountAction> {
let receives_each = AnsAsset {
amount: asset
.amount
.multiply_ratio(Uint128::one(), Uint128::from(receivers.len() as u128)),
..asset
};
let bank = self.base.bank(self.deps);
receivers
.iter()
.map(|receiver| {
bank.transfer(vec![&receives_each], receiver)
})
.try_fold(AccountAction::new(), |mut acc, v| match v {
Ok(action) => {
acc.merge(action);
Ok(acc)
}
Err(e) => Err(e),
})
}
}
#[cfg(test)]
mod test {
use abstract_core::objects::AnsAsset;
use cosmwasm_std::{testing::mock_dependencies, Addr, CosmosMsg, Response, StdError, Uint128};
use crate::{
apis::splitter::SplitterInterface, mock_module::MockModule, AbstractSdkError, Execution,
ExecutorMsg,
};
fn split() -> Result<Response, AbstractSdkError> {
let deps = mock_dependencies();
let module = MockModule::new();
let asset = AnsAsset {
amount: Uint128::from(100u128),
name: "usd".into(),
};
let receivers = vec![
Addr::unchecked("receiver1"),
Addr::unchecked("receiver2"),
Addr::unchecked("receiver3"),
];
let split_funds = module.splitter(deps.as_ref()).split(asset, &receivers)?;
assert_eq!(split_funds.messages().len(), 3);
let msg: ExecutorMsg = module.executor(deps.as_ref()).execute(vec![split_funds])?;
Ok(Response::new().add_message(msg))
}
}