#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
mod call;
mod genesis;
#[cfg(feature = "native")]
mod query;
#[cfg(feature = "native")]
pub use query::*;
mod token;
pub mod utils;
pub use call::*;
pub use genesis::*;
use sov_modules_api::{CallResponse, Error, GasUnit, ModuleInfo, WorkingSet};
use token::Token;
pub use token::{Amount, Coins};
pub use utils::{get_genesis_token_address, get_token_address};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BankGasConfig<GU: GasUnit> {
pub create_token: GU,
pub transfer: GU,
pub burn: GU,
pub mint: GU,
pub freeze: GU,
}
#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))]
#[derive(ModuleInfo, Clone)]
pub struct Bank<C: sov_modules_api::Context> {
#[address]
pub(crate) address: C::Address,
#[gas]
pub(crate) gas: BankGasConfig<C::GasUnit>,
#[state]
pub(crate) tokens: sov_modules_api::StateMap<C::Address, Token<C>>,
}
impl<C: sov_modules_api::Context> sov_modules_api::Module for Bank<C> {
type Context = C;
type Config = BankConfig<C>;
type CallMessage = call::CallMessage<C>;
fn genesis(&self, config: &Self::Config, working_set: &mut WorkingSet<C>) -> Result<(), Error> {
Ok(self.init_module(config, working_set)?)
}
fn call(
&self,
msg: Self::CallMessage,
context: &Self::Context,
working_set: &mut WorkingSet<C>,
) -> Result<sov_modules_api::CallResponse, Error> {
match msg {
call::CallMessage::CreateToken {
salt,
token_name,
initial_balance,
minter_address,
authorized_minters,
} => {
self.charge_gas(working_set, &self.gas.create_token)?;
self.create_token(
token_name,
salt,
initial_balance,
minter_address,
authorized_minters,
context,
working_set,
)?;
Ok(CallResponse::default())
}
call::CallMessage::Transfer { to, coins } => {
self.charge_gas(working_set, &self.gas.create_token)?;
Ok(self.transfer(to, coins, context, working_set)?)
}
call::CallMessage::Burn { coins } => {
self.charge_gas(working_set, &self.gas.burn)?;
Ok(self.burn_from_eoa(coins, context, working_set)?)
}
call::CallMessage::Mint {
coins,
minter_address,
} => {
self.charge_gas(working_set, &self.gas.mint)?;
self.mint_from_eoa(&coins, &minter_address, context, working_set)?;
Ok(CallResponse::default())
}
call::CallMessage::Freeze { token_address } => {
self.charge_gas(working_set, &self.gas.freeze)?;
Ok(self.freeze(token_address, context, working_set)?)
}
}
}
}