Skip to content
This repository was archived by the owner on Oct 30, 2023. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions contracts/native/ans-host/src/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,7 @@ pub fn list_pool_entries(
let pairing = &e.as_ref().unwrap().0;
dex_filter.as_ref().map_or(true, |f| f == pairing.dex())
})
// TODO: is this necessary?
.map(|e| e.map(|(k, v)| (k, v)))
.take(limit)
.collect();
res?
};
Expand Down
13 changes: 12 additions & 1 deletion packages/abstract-core/src/objects/entry/ans_entry_convertor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,27 @@ impl AnsEntryConvertor<LpToken> {
}

impl AnsEntryConvertor<PoolMetadata> {
/// Get the [`LpToken`] struct for this pool.
pub fn lp_token(self) -> LpToken {
LpToken {
dex: self.entry.dex,
assets: self.entry.assets,
}
}

/// Get the LP token Asset for this pool.
pub fn lp_token_asset(self) -> AssetEntry {
AnsEntryConvertor::new(self.lp_token()).asset_entry()
}
/// Get an [`DexAssetPairing`] for this pool.
pub fn dex_asset_pairing(self) -> AbstractResult<DexAssetPairing> {
let mut assets = self.entry.assets;

Ok(DexAssetPairing::new(
assets.pop().unwrap(),
assets.pop().unwrap(),
self.entry.dex.as_str(),
))
}
}

impl AnsEntryConvertor<AssetEntry> {
Expand Down
2 changes: 1 addition & 1 deletion packages/abstract-core/src/objects/entry/asset_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub const CHAIN_DELIMITER: &str = ">";
/// An unchecked ANS asset entry. This is a string that is formatted as
/// `src_chain>[intermediate_chain>]asset_name`
#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Default,
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Default, Hash,
)]
pub struct AssetEntry(pub(crate) String);

Expand Down
8 changes: 6 additions & 2 deletions packages/abstract-core/src/objects/entry/contract_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use std::{
};

/// Key to get the Address of a contract
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord)]
#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Hash,
)]
pub struct UncheckedContractEntry {
pub protocol: String,
pub contract: String,
Expand Down Expand Up @@ -55,7 +57,9 @@ impl TryFrom<String> for UncheckedContractEntry {

/// Key to get the Address of a contract
/// Use [`UncheckedContractEntry`] to construct this type.
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, JsonSchema, Eq, PartialOrd, Ord)]
#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, JsonSchema, Eq, PartialOrd, Ord, Hash,
)]
pub struct ContractEntry {
pub protocol: String,
pub contract: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ type DexName = String;
/// The key for an asset pairing
/// Consists of the two assets and the dex name
/// TODO: what if we made keys equal based on the two assets either way?
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord)]
#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Hash,
)]
pub struct DexAssetPairing((AssetEntry, AssetEntry, DexName));

impl DexAssetPairing {
Expand Down
9 changes: 7 additions & 2 deletions packages/abstract-core/src/objects/pool/pool_id.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
use crate::{error::AbstractError, AbstractResult};
use cosmwasm_std::{Addr, Api, StdError};
use cw_address_like::AddressLike;
use std::{fmt, str::FromStr};

#[cosmwasm_schema::cw_serde]
#[non_exhaustive]
pub enum PoolAddressBase<T> {
#[derive(Eq, Hash, PartialOrd, Ord)]
pub enum PoolAddressBase<T: AddressLike> {
SeparateAddresses { swap: T, liquidity: T },
Contract(T),
Id(u64),
}

impl<T> PoolAddressBase<T> {
impl<T> PoolAddressBase<T>
where
T: AddressLike,
{
pub fn contract<C: Into<T>>(contract: C) -> Self {
Self::Contract(contract.into())
}
Expand Down
2 changes: 1 addition & 1 deletion packages/abstract-core/src/objects/pool/pool_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{fmt, str::FromStr};

type DexName = String;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Hash)]
pub struct PoolMetadata {
pub dex: DexName,
pub pool_type: PoolType,
Expand Down
2 changes: 1 addition & 1 deletion packages/abstract-core/src/objects/pool/pool_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{fmt, str::FromStr};

#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, Hash)]
#[non_exhaustive]
pub enum PoolType {
ConstantProduct,
Expand Down
2 changes: 1 addition & 1 deletion packages/abstract-core/src/objects/pool/unique_pool_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use std::{array::TryFromSliceError, convert::TryInto, fmt::Display};

#[derive(
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Copy,
Deserialize, Serialize, Clone, Debug, PartialEq, Eq, JsonSchema, PartialOrd, Ord, Copy, Hash,
)]
pub struct UniquePoolId(u64);

Expand Down
5 changes: 3 additions & 2 deletions scripts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ version = { workspace = true }
edition = { workspace = true }

[lib]

name = "ans_helper"
path = "src/lib.rs"

[dependencies]
cosmwasm-std = { workspace = true }
Expand All @@ -26,7 +27,7 @@ tokio = { workspace = true }
log = "0.4.14"
anyhow = { workspace = true }
serde_json = "1.0.79"
reqwest = { version = "0.11.9" }
reqwest = "0.11.9"
dotenv = "0.15.0"
env_logger = "0.10.0"

Expand Down
101 changes: 101 additions & 0 deletions scripts/src/assets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use crate::EntryDif;
use cw_asset::AssetInfoBase;

use cw_orch::prelude::*;

use abstract_core::ans_host::*;
use abstract_interface::{AbstractInterfaceError, AnsHost};

use serde_json::{from_value, Value};
use std::collections::HashMap;

pub fn get_scraped_entries(
chain_name: &String,
chain_id: &String,
) -> Result<HashMap<String, AssetInfoBase<String>>, AbstractInterfaceError> {
let raw_scraped_entries = crate::get_scraped_json_data("assets");

let parsed_scraped_entries: Vec<Vec<Value>> =
from_value(raw_scraped_entries[chain_name][chain_id].clone()).unwrap();

let scraped_entries_vec: Vec<(String, AssetInfoBase<String>)> = parsed_scraped_entries
.into_iter()
.map(|v| {
let asset_info: AssetInfoBase<String> = from_value(v[1].clone()).unwrap();
(v[0].as_str().unwrap().to_owned(), asset_info)
})
.collect();

Ok(scraped_entries_vec.into_iter().collect())
}

pub fn get_on_chain_entries(
ans_host: &AnsHost<Daemon>,
) -> Result<HashMap<String, AssetInfoBase<String>>, AbstractInterfaceError> {
let mut on_chain_entries = HashMap::new();
let mut last_asset = None;
loop {
let AssetListResponse { assets } = ans_host.asset_list(None, None, last_asset)?;
if assets.is_empty() {
break;
}
last_asset = assets.last().map(|(entry, _)| entry.to_string());
on_chain_entries.extend(assets.into_iter().map(|(a, b)| (a.to_string(), b.into())));
}

Ok(on_chain_entries)
}

pub fn update(
ans_host: &AnsHost<Daemon>,
diff: EntryDif<String, AssetInfoBase<String>>,
) -> Result<(), AbstractInterfaceError> {

let to_add: Vec<_> = diff.1.into_iter().collect();
let to_remove: Vec<_> = diff.0.into_iter().collect();

// add the assets
ans_host.execute_chunked(&to_add, 25, |chunk| ExecuteMsg::UpdateAssetAddresses {
to_add: chunk.to_vec(),
to_remove: vec![],
})?;

// remove the assets
ans_host.execute_chunked(&to_remove, 25, |chunk| ExecuteMsg::UpdateAssetAddresses {
to_add: vec![],
to_remove: chunk.to_vec(),
})?;

Ok(())
}

// fn update_channels(ans: &AnsHost<Daemon>) -> Result<(), crate::CwOrchError> {
// let path = env::var("ANS_HOST_CHANNELS").unwrap();
// 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_name = &ans.get_chain().state().chain_data.chain_name;
// let chain_id = ans.get_chain().state().chain_data.chain_id.to_string();
// let channels = json
// .get(chain_name)
// .unwrap()
// .get(chain_id)
// .ok_or_else(|| CwOrchError::StdErr("network not found".into()))?;

// let channels = channels.as_object().unwrap();
// let channels_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();

// ans.execute_chunked(&channels_to_add, 25, |chunk| ExecuteMsg::UpdateChannels {
// to_add: chunk.to_vec(),
// to_remove: vec![],
// })?;

// Ok(())
// }
79 changes: 73 additions & 6 deletions scripts/src/bin/update_ans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,28 @@ use cw_orch::{
use tokio::runtime::Runtime;

pub const ABSTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
const MNEMONIC: &str = "clock post desk civil pottery foster expand merit dash seminar song memory figure uniform spice circle try happy obvious trash crime hybrid hood cushion";

// Run "cargo run --example download_wasms" in the `abstract-interfaces` package before deploying!
fn full_deploy(networks: Vec<ChainInfo>) -> anyhow::Result<()> {
fn update_ans(networks: Vec<ChainInfo>) -> anyhow::Result<()> {
let rt = Runtime::new()?;
for network in networks {
let chain = DaemonBuilder::default()
.handle(rt.handle())
.chain(network)
.mnemonic(MNEMONIC)
.build()?;

let deployment = Abstract::load_from(chain)?;
// Take the assets, contracts, and pools from resources and upload them to the ans host
let ans_host = deployment.ans_host;
ans_host.update_all()?;

// First we get all values
let scraped_entries = ans_helper::get_scraped_entries(&ans_host)?;
let on_chain_entries = ans_helper::get_on_chain_entries(&ans_host)?;

// Then we create a diff between the 2 objects
let diff = ans_helper::diff(scraped_entries, on_chain_entries)?;

// Finally we upload on-chain
ans_helper::update(&ans_host, diff)?;
}
Ok(())
}
Expand All @@ -49,7 +55,7 @@ fn main() {

let networks = args.network_ids.iter().map(|n| parse_network(n)).collect();

if let Err(ref err) = full_deploy(networks) {
if let Err(ref err) = update_ans(networks) {
log::error!("{}", err);
err.chain()
.skip(1)
Expand All @@ -64,3 +70,64 @@ fn main() {
::std::process::exit(1);
}
}

// pub fn update_assets(ans_host: &AnsHost<Daemon>) -> Result<(), AbstractInterfaceError> {
// let scraped_entries = get_scraped_json_data("assets");
// let chain_name = &ans_host.get_chain().state().chain_data.chain_name;
// let chain_id = ans_host.get_chain().state().chain_data.chain_id.to_string();

// println!("scraped_entries: {:?}", scraped_entries[chain_name][chain_id.clone()]);

// let scraped_entries: Vec<Vec<Value>> =
// from_value(scraped_entries[chain_name][chain_id].clone()).unwrap();

// let scraped_entries_vec: Vec<(String, String)> = scraped_entries.into_iter().map(|v| {
// let asset_info: AssetInfo = from_value(v[1].clone()).unwrap();
// (v[0].as_str().unwrap().to_owned(), asset_info.to_string())
// }).collect::<Vec<_>>();

// println!("scraped_entries: {:?}", scraped_entries_vec[0]);
// let scraped_entries = HashMap::<String, String>::from_iter(scraped_entries_vec.into_iter());

// // get all the assets
// let mut on_chain_entries = HashMap::new();
// let mut last_asset = None;
// loop {
// let AssetListResponse { assets } = ans_host.asset_list(None, None, last_asset)?;
// if assets.is_empty() {
// break;
// }
// last_asset = assets.last().map(|(entry, _)| entry.to_string());
// on_chain_entries.extend(assets.into_iter().map(|(a, b)| (a.to_string(), b)));
// }

// // Merge the keys of the two stores.
// let on_chain_binding = on_chain_entries.keys().collect::<HashSet<_>>();
// let scraped_binding = scraped_entries.keys().collect::<HashSet<_>>();
// let union_keys = on_chain_binding
// .union(&scraped_binding)
// .to_owned()
// .collect::<Vec<_>>();

// let mut assets_to_remove: Vec<String> = vec![];
// let mut assets_to_add: Vec<(String, cw_asset::AssetInfoBase<String>)> = vec![];

// for entry in union_keys {
// if !scraped_entries.contains_key(entry.as_str()) {
// // remove the key
// assets_to_remove.push(entry.to_string())
// }

// if !on_chain_entries.contains_key(*entry) {
// // add the key
// assets_to_add.push((
// (*entry).to_owned(),
// AssetInfoUnchecked::from_str(scraped_entries.get(*entry).unwrap()).unwrap(),
// ))
// }
// }

// println!("Removing {} assets", assets_to_remove.len());
// println!("Removing assets: {:?}", assets_to_remove);
// println!("Adding {} assets", assets_to_add.len());
// println!("Adding assets: {:?}", assets_to_add);
Loading