1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use std::{cmp::min, env, fs::File};

use abstract_os::objects::UncheckedContractEntry;
use abstract_os::{memory::*, objects::UncheckedChannelEntry};

use cw_asset::AssetInfoUnchecked;

use serde_json::from_reader;

use crate::AbstractOS;
use boot_core::{BootError, Contract, Daemon, IndexResponse, TxHandler, TxResponse};

pub type Memory<Chain> = AbstractOS<Chain, ExecuteMsg, InstantiateMsg, QueryMsg, MigrateMsg>;

impl<Chain: TxHandler + Clone> Memory<Chain>
where
    TxResponse<Chain>: IndexResponse,
{
    pub fn new(name: &str, chain: &Chain) -> Self {
        Self(
            Contract::new(name, chain).with_wasm_path("memory"), // .with_mock(Box::new(
                                                                 //     ContractWrapper::new_with_empty(
                                                                 //         ::contract::execute,
                                                                 //         ::contract::instantiate,
                                                                 //         ::contract::query,
                                                                 //     ),
                                                                 // ))
        )
    }
}

impl Memory<Daemon> {
    pub fn update_all(&self) -> Result<(), BootError> {
        self.update_assets()?;
        self.update_contracts()?;
        Ok(())
    }

    pub fn update_assets(&self) -> Result<(), BootError> {
        let path = env::var("MEMORY_ASSETS")?;
        let file =
            File::open(&path).unwrap_or_else(|_| panic!("file should be present at {}", &path));
        let json: serde_json::Value = from_reader(file)?;
        let chain_id = self.0.chain().state.chain.chain_id;
        let network_id = self.0.chain().state.id.clone();
        let maybe_assets = json.get(chain_id).unwrap().get(network_id);

        match maybe_assets {
            Some(assets_value) => {
                let assets = assets_value.as_object().unwrap();
                let to_add: Vec<(String, AssetInfoUnchecked)> = assets
                    .iter()
                    .map(|(name, value)| {
                        let asset: AssetInfoUnchecked =
                            serde_json::from_value(value.clone()).unwrap();
                        (name.clone(), asset)
                    })
                    .collect();
                let mut i = 0;
                while i != to_add.len() - 1 {
                    let chunk = to_add.get(i..min(i + 25, to_add.len() - 1)).unwrap();
                    i += chunk.len();
                    self.execute(
                        &ExecuteMsg::UpdateAssetAddresses {
                            to_add: chunk.to_vec(),
                            to_remove: vec![],
                        },
                        None,
                    )?;
                }

                Ok(())
            }
            None => Err(BootError::StdErr("network not found".into())),
        }
    }

    pub fn update_channels(&self) -> Result<(), BootError> {
        let path = env::var("MEMORY_CHANNELS")?;
        let file =
            File::open(&path).unwrap_or_else(|_| panic!("file should be present at {}", &path));
        let json: serde_json::Value = from_reader(file)?;
        let chain_id = self.0.chain().state.chain.chain_id;
        let network_id = self.0.chain().state.id.clone();
        let maybe_channels = json.get(chain_id).unwrap().get(network_id);

        match maybe_channels {
            Some(channels_value) => {
                let channels = channels_value.as_object().unwrap();
                let to_add: Vec<(UncheckedChannelEntry, String)> = channels
                    .iter()
                    .map(|(name, value)| {
                        let id = value.as_str().unwrap().to_owned();
                        let key = UncheckedChannelEntry::try_from(name.clone()).unwrap();
                        (key, id)
                    })
                    .collect();
                let mut i = 0;
                while i < to_add.len() {
                    let chunk = to_add.get(i..min(i + 25, to_add.len())).unwrap();
                    i += chunk.len();
                    self.execute(
                        &ExecuteMsg::UpdateChannels {
                            to_add: chunk.to_vec(),
                            to_remove: vec![],
                        },
                        None,
                    )?;
                }

                Ok(())
            }
            None => Err(BootError::StdErr("network not found".into())),
        }
    }

    pub fn update_contracts(&self) -> Result<(), BootError> {
        let path = env::var("MEMORY_CONTRACTS")?;

        let file =
            File::open(&path).unwrap_or_else(|_| panic!("file should be present at {}", &path));
        let json: serde_json::Value = from_reader(file)?;
        let chain_id = self.0.chain().state.chain.chain_id;
        let network_id = self.0.chain().state.id.clone();
        let maybe_contracts = json.get(chain_id).unwrap().get(network_id);

        match maybe_contracts {
            Some(contracts_value) => {
                let contracts = contracts_value.as_object().unwrap();
                let to_add: Vec<(UncheckedContractEntry, String)> = contracts
                    .iter()
                    .map(|(name, value)| {
                        let id = value.as_str().unwrap().to_owned();
                        let key = UncheckedContractEntry::try_from(name.clone()).unwrap();
                        (key, id)
                    })
                    .collect();
                let mut i = 0;
                while i < to_add.len() {
                    let chunk = to_add.get(i..min(i + 25, to_add.len())).unwrap();
                    i += chunk.len();
                    self.0.execute(
                        &ExecuteMsg::UpdateContractAddresses {
                            to_add: chunk.to_vec(),
                            to_remove: vec![],
                        },
                        None,
                    )?;
                }

                Ok(())
            }
            None => Err(BootError::StdErr("network not found".into())),
        }
    }
}