Skip to content

Commit

Permalink
Implement tiers and checks for networks (#362)
Browse files Browse the repository at this point in the history
* Implement tiers and checks for networks

* Run formatter
  • Loading branch information
JonoPrest authored Nov 27, 2024
1 parent 741bc12 commit 8bfc4b0
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 108 deletions.
45 changes: 23 additions & 22 deletions codegenerator/cli/src/cli_args/interactive_init/evm_prompts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ use crate::{
};
use anyhow::{Context, Result};
use inquire::{validator::Validation, CustomType, Select, Text};
use std::{env, path::PathBuf, str::FromStr};
use serde::{Deserialize, Serialize};
use std::{env, fmt, path::PathBuf};
use strum::IntoEnumIterator;

fn prompt_abi_events_selection(events: Vec<ethers::abi::Event>) -> Result<Vec<ethers::abi::Event>> {
Expand Down Expand Up @@ -183,6 +184,21 @@ impl ContractImportArgs {
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
enum NetworkSelection {
EnterNetworkId,
Network(HypersyncNetwork),
}

impl fmt::Display for NetworkSelection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::EnterNetworkId => write!(f, "<Enter Network Id>"),
Self::Network(network) => write!(f, "{}", network.get_pretty_name()),
}
}
}

///Prompts for a Supported network or for the user to enter an
///id, if it is unsupported it requires an RPC url. If the rpc is already
///known it can be passed in as the first arg. Otherwise this will be prompted.
Expand All @@ -193,9 +209,6 @@ fn prompt_for_network_id(
opt_start_block: &Option<u64>,
already_selected_ids: Vec<u64>,
) -> Result<converters::NetworkKind> {
//The first option of the list, funnels the user to enter a u64
let enter_id = "<Enter Network Id>";

//Select one of our supported networks
let networks = HypersyncNetwork::iter()
//Don't allow selection of networks that have been previously
Expand All @@ -204,21 +217,21 @@ fn prompt_for_network_id(
let network_id = *n as u64;
!already_selected_ids.contains(&network_id)
})
.map(|n| n.to_string())
.map(|n| NetworkSelection::Network(n))
.collect::<Vec<_>>();

//User's options to either enter an id or select a supported network
let options = vec![vec![enter_id.to_string()], networks].concat();
let options = vec![vec![NetworkSelection::EnterNetworkId], networks].concat();

//Action prompt
let choose_from_networks = Select::new("Choose network:", options)
.prompt()
.context("Failed during prompt for network")?;

let selected = match choose_from_networks.as_str() {
let selected = match choose_from_networks {
//If the user's choice evaluates to the enter network id option, prompt them for
//a network id
choice if choice == enter_id => {
NetworkSelection::EnterNetworkId => {
let network_id = CustomType::<u64>::new("Enter the network id:")
//Validate that this ID is not already selected
.with_validator(UniqueValueValidator::new(already_selected_ids))
Expand All @@ -233,10 +246,7 @@ fn prompt_for_network_id(
//If a supported network choice was selected. We should be able to
//parse it back to a supported network since it was serialized as a
//string
choice => converters::NetworkKind::Supported(
HypersyncNetwork::from_str(&choice)
.context("Unexpected input, not a supported network.")?,
),
NetworkSelection::Network(network) => converters::NetworkKind::Supported(network),
};

Ok(selected)
Expand Down Expand Up @@ -306,16 +316,7 @@ impl ExplorerImportArgs {
let chosen_network = match &self.blockchain {
Some(chain) => chain.clone(),
None => {
let options = NetworkWithExplorer::iter()
//Filter only our supported networks
.filter(|&n| {
HypersyncNetwork::iter()
//able to cast as u64 because networks enum
//uses repr(u64) attribute
.find(|&sn| n as u64 == sn as u64)
.is_some()
})
.collect();
let options = NetworkWithExplorer::iter().collect();

Select::new(
"Which blockchain would you like to import a contract from?",
Expand Down
105 changes: 96 additions & 9 deletions codegenerator/cli/src/config_parsing/chain_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ use anyhow::anyhow;

use clap::ValueEnum;
use serde::{Deserialize, Serialize};
use strum::FromRepr;
use std::fmt;
use strum::IntoEnumIterator;
use strum_macros::{Display, EnumIter, EnumString};
use subenum::subenum;

use crate::constants::DEFAULT_CONFIRMED_BLOCK_THRESHOLD;

#[subenum(NetworkWithExplorer, HypersyncNetwork, GraphNetwork, IgnoreFromTests)]
#[derive(strum::Display)]
#[subenum(NetworkWithExplorer, HypersyncNetwork, GraphNetwork)]
#[derive(
Clone,
Debug,
ValueEnum,
Serialize,
Deserialize,
EnumIter,
EnumString,
FromRepr,
strum::EnumIter,
strum::EnumString,
strum::FromRepr,
PartialEq,
Eq,
Display,
Hash,
Copy,
)]
Expand Down Expand Up @@ -154,7 +153,10 @@ pub enum Network {
#[subenum(GraphNetwork)]
Fuse = 122,

#[subenum(HypersyncNetwork, NetworkWithExplorer)]
#[subenum(
HypersyncNetwork(serde(rename = "galadriel-devnet (experimental)")),
NetworkWithExplorer
)]
GaladrielDevnet = 696969,

#[subenum(HypersyncNetwork, NetworkWithExplorer, GraphNetwork)]
Expand Down Expand Up @@ -207,7 +209,7 @@ pub enum Network {
#[subenum(HypersyncNetwork, NetworkWithExplorer)]
Metis = 1088,

#[subenum(IgnoreFromTests)]
#[subenum(HypersyncNetwork)]
MevCommit = 17864,

#[subenum(HypersyncNetwork, NetworkWithExplorer)]
Expand Down Expand Up @@ -457,11 +459,96 @@ impl Network {
}
}

#[derive(Deserialize, Debug, PartialEq, strum::Display)]
#[serde(rename_all = "UPPERCASE")]
pub enum ChainTier {
Gold,
Silver,
Bronze,
Experimental,
#[serde(alias = "HIDDEN")]
Internal,
}

impl ChainTier {
pub fn get_icon(&self) -> &str {
match self {
Self::Gold => "🥇",
Self::Silver => "🥈",
Self::Bronze => "🥉",
Self::Experimental => "🧪",
Self::Internal => "🔒",
}
}

pub fn is_public(&self) -> bool {
match self {
Self::Gold | Self::Silver | Self::Bronze | Self::Experimental => true,
Self::Internal => false,
}
}
}

impl HypersyncNetwork {
// This is a custom iterator that returns all the HypersyncNetwork enums that is made public accross crates (for convenience)
pub fn iter_hypersync_networks() -> impl Iterator<Item = HypersyncNetwork> {
HypersyncNetwork::iter()
}
pub fn get_tier(&self) -> ChainTier {
use ChainTier::*;
use HypersyncNetwork::*;
match self {
EthereumMainnet | Fantom | Zeta | Sepolia | OptimismSepolia | Metis | ZksyncEra
| Optimism | ArbitrumSepolia | ArbitrumNova | Avalanche | Polygon | Bsc | Mantle
| Zircuit | BaseSepolia => Gold,

Manta | Base | BerachainBartio | Boba | Blast | Cyber | Aurora | Harmony | Scroll
| Darwinia | Mode | Rsk | ShimmerEvm | Linea | NeonEvm | Amoy | Saakuru | Moonbeam
| Opbnb | Lisk | BlastSepolia | Celo | Chiliz | Fuji | ArbitrumOne | Merlin
| Holesky => Silver,

Zora | MoonbaseAlpha | Morph | LuksoTestnet | Kroma | GnosisChiado | XLayer | Lukso
| Gnosis | C1Milkomeda | Crab | Tangle | Sophon | Flare | PolygonZkevm | MevCommit => {
Bronze
}

SophonTestnet | MorphTestnet | GaladrielDevnet | CitreaTestnet | Goerli
| BscTestnet | B2Testnet | UnichainSepolia => Experimental,
}
}

pub fn get_plain_name(&self) -> String {
Network::from(*self).to_string()
}

pub fn get_pretty_name(&self) -> String {
let name = Network::from(*self).to_string();
let tier = self.get_tier();
let icon = tier.get_icon();
format!("{name} {icon}")
}
}

impl fmt::Display for HypersyncNetwork {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.get_pretty_name())
}
}

impl NetworkWithExplorer {
pub fn get_pretty_name(&self) -> String {
let network = Network::from(*self);
match HypersyncNetwork::try_from(network) {
Ok(hypersync_network) => hypersync_network.get_pretty_name(),
Err(_) => network.to_string(),
}
}
}

impl fmt::Display for NetworkWithExplorer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.get_pretty_name())
}
}

pub fn get_confirmed_block_threshold_from_id(id: u64) -> i32 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ impl Event {
Language::ReScript => format!("{int_var_name}->Belt.Int.toString"),
Language::TypeScript | Language::JavaScript => int_var_name,
};
let int_event_prop_as_string = |event_prop: &str| int_as_string(format!("event.{event_prop}"));
let int_event_prop_as_string =
|event_prop: &str| int_as_string(format!("event.{event_prop}"));
let chain_id_str = int_event_prop_as_string("chainId");

let block_number_field = match is_fuel {
Expand Down
Loading

0 comments on commit 8bfc4b0

Please sign in to comment.