use anyhow::{bail, Result};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use sov_modules_api::WorkingSet;
use crate::token::Token;
use crate::Bank;
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
#[serde(bound = "C::Address: Serialize + DeserializeOwned")]
pub struct BankConfig<C: sov_modules_api::Context> {
pub tokens: Vec<TokenConfig<C>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
#[serde(bound = "C::Address: Serialize + DeserializeOwned")]
pub struct TokenConfig<C: sov_modules_api::Context> {
pub token_name: String,
pub address_and_balances: Vec<(C::Address, u64)>,
pub authorized_minters: Vec<C::Address>,
pub salt: u64,
}
pub(crate) const DEPLOYER: [u8; 32] = [0; 32];
impl<C: sov_modules_api::Context> Bank<C> {
pub(crate) fn init_module(
&self,
config: &<Self as sov_modules_api::Module>::Config,
working_set: &mut WorkingSet<C>,
) -> Result<()> {
let parent_prefix = self.tokens.prefix();
for token_config in config.tokens.iter() {
let (token_address, token) = Token::<C>::create(
&token_config.token_name,
&token_config.address_and_balances,
&token_config.authorized_minters,
&DEPLOYER,
token_config.salt,
parent_prefix,
working_set,
)?;
if self.tokens.get(&token_address, working_set).is_some() {
bail!("Token address {} already exists", token_address);
}
self.tokens.set(&token_address, &token, working_set);
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use sov_modules_api::default_context::DefaultContext;
use sov_modules_api::{AddressBech32, Spec};
use super::*;
#[test]
fn test_config_serialization() {
let address: <DefaultContext as Spec>::Address = AddressBech32::from_str(
"sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94",
)
.unwrap()
.into();
let config = BankConfig::<DefaultContext> {
tokens: vec![TokenConfig {
token_name: "sov-demo-token".to_owned(),
address_and_balances: vec![(address, 100000000)],
authorized_minters: vec![address],
salt: 0,
}],
};
let data = r#"
{
"tokens":[
{
"token_name":"sov-demo-token",
"address_and_balances":[["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94",100000000]],
"authorized_minters":["sov1l6n2cku82yfqld30lanm2nfw43n2auc8clw7r5u5m6s7p8jrm4zqrr8r94"]
,"salt":0
}
]
}"#;
let parsed_config: BankConfig<DefaultContext> = serde_json::from_str(data).unwrap();
assert_eq!(config, parsed_config)
}
}