use inquire::{CustomType, Select};
#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
#[interactive_clap(input_context = crate::GlobalContext)]
#[interactive_clap(output_context = AddNetworkConnectionContext)]
pub struct AddNetworkConnection {
#[interactive_clap(long)]
network_name: String,
#[interactive_clap(long)]
connection_name: String,
#[interactive_clap(long)]
rpc_url: crate::types::url::Url,
#[interactive_clap(long)]
wallet_url: crate::types::url::Url,
#[interactive_clap(long)]
explorer_transaction_url: crate::types::url::Url,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
rpc_api_key: Option<crate::types::api_key::ApiKey>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
linkdrop_account_id: Option<crate::types::account_id::AccountId>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
near_social_db_contract_account_id: Option<crate::types::account_id::AccountId>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
faucet_url: Option<crate::types::url::Url>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
meta_transaction_relayer_url: Option<crate::types::url::Url>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
fastnear_url: Option<crate::types::url::Url>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
staking_pools_factory_account_id: Option<crate::types::account_id::AccountId>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
coingecko_url: Option<crate::types::url::Url>,
#[interactive_clap(long)]
#[interactive_clap(skip_default_input_arg)]
mpc_contract_account_id: Option<crate::types::account_id::AccountId>,
}
#[derive(Debug, Clone)]
pub struct AddNetworkConnectionContext;
impl AddNetworkConnectionContext {
pub fn from_previous_context(
previous_context: crate::GlobalContext,
scope: &<AddNetworkConnection as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
let mut config = previous_context.config;
config.network_connection.insert(
scope.connection_name.clone(),
crate::config::NetworkConfig {
network_name: scope.network_name.clone(),
rpc_url: scope.rpc_url.clone().into(),
wallet_url: scope.wallet_url.clone().into(),
explorer_transaction_url: scope.explorer_transaction_url.0.clone(),
rpc_api_key: scope.rpc_api_key.clone(),
linkdrop_account_id: scope
.linkdrop_account_id
.clone()
.map(|linkdrop_account_id| linkdrop_account_id.into()),
near_social_db_contract_account_id: scope
.near_social_db_contract_account_id
.clone()
.map(|near_social_db_contract_account_id| {
near_social_db_contract_account_id.into()
}),
faucet_url: scope.faucet_url.clone().map(|faucet_url| faucet_url.into()),
meta_transaction_relayer_url: scope
.meta_transaction_relayer_url
.clone()
.map(|meta_transaction_relayer_url| meta_transaction_relayer_url.into()),
fastnear_url: scope
.fastnear_url
.clone()
.map(|fastnear_url| fastnear_url.into()),
staking_pools_factory_account_id: scope
.staking_pools_factory_account_id
.clone()
.map(|staking_pools_factory_account_id| {
staking_pools_factory_account_id.into()
}),
coingecko_url: scope
.coingecko_url
.clone()
.map(|coingecko_url| coingecko_url.into()),
mpc_contract_account_id: scope
.mpc_contract_account_id
.clone()
.map(|mpc_contract_account_id| mpc_contract_account_id.into()),
},
);
eprintln!();
config.write_config_toml()?;
eprintln!(
"Network connection \"{}\" was successfully added to config.toml",
&scope.connection_name
);
Ok(Self)
}
}
impl AddNetworkConnection {
fn input_rpc_api_key(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::api_key::ApiKey>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, the RPC endpoint requires an API key")]
Yes,
#[strum(to_string = "No, the RPC endpoint does not require an API key")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter an API key?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let api_key: crate::types::api_key::ApiKey =
CustomType::new("Enter an API key:").prompt()?;
Ok(Some(api_key))
} else {
Ok(None)
}
}
fn input_linkdrop_account_id(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::account_id::AccountId>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(
to_string = "Yes, and I want to enter the name of the account hosting the program \"linkdrop\""
)]
Yes,
#[strum(to_string = "I don't know")]
No,
}
let select_choose_input = Select::new(
"Is there a \"linkdrop\" program on this network?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let account_id: crate::types::account_id::AccountId =
CustomType::new("What is the name of the account that hosts the linkdrop program? (e.g. on mainnet it is 'near', on testnet it is 'testnet')").prompt()?;
Ok(Some(account_id))
} else {
Ok(None)
}
}
fn input_near_social_db_contract_account_id(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::account_id::AccountId>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, and I want to enter the NEAR Social DB contract account ID")]
Yes,
#[strum(to_string = "No, I don't want to enter the NEAR Social DB contract account ID")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the NEAR Social DB contract account ID on this network?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let account_id: crate::types::account_id::AccountId =
CustomType::new("What is the NEAR Social DB contract account ID? (e.g. on mainnet it is 'social.near')").prompt()?;
Ok(Some(account_id))
} else {
Ok(None)
}
}
fn input_faucet_url(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::url::Url>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the URL of the faucet")]
Yes,
#[strum(to_string = "No, I don't want to enter the faucet URL")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the faucet URL?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let faucet_url: crate::types::url::Url =
CustomType::new("What is the faucet URL?").prompt()?;
Ok(Some(faucet_url))
} else {
Ok(None)
}
}
fn input_meta_transaction_relayer_url(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::url::Url>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the URL of the relayer")]
Yes,
#[strum(to_string = "No, I don't want to enter the relayer URL")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the meta transaction relayer URL?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let meta_transaction_relayer_url: crate::types::url::Url =
CustomType::new("What is the meta transaction relayer URL?").prompt()?;
Ok(Some(meta_transaction_relayer_url))
} else {
Ok(None)
}
}
fn input_fastnear_url(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::url::Url>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the FastNEAR API URL")]
Yes,
#[strum(to_string = "No, I don't want to enter the FastNEAR API URL")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the FastNEAR API URL?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let stake_delegators_api: crate::types::url::Url =
CustomType::new("What is the FastNEAR API URL?").prompt()?;
Ok(Some(stake_delegators_api))
} else {
Ok(None)
}
}
fn input_staking_pools_factory_account_id(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::account_id::AccountId>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the staking pools factory account ID")]
Yes,
#[strum(to_string = "No, I don't want to enter the staking pools factory account ID")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the staking pools factory account ID?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let account_id: crate::types::account_id::AccountId =
CustomType::new("What is the staking pools factory account ID?").prompt()?;
Ok(Some(account_id))
} else {
Ok(None)
}
}
fn input_coingecko_url(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::url::Url>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the CoinGecko API URL")]
Yes,
#[strum(to_string = "No, I don't want to enter the CoinGecko API URL")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the CoinGecko API URL?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let coingecko_api: crate::types::url::Url =
CustomType::new("What is the CoinGecko API URL?")
.with_starting_input("https://api.coingecko.com/")
.prompt()?;
Ok(Some(coingecko_api))
} else {
Ok(None)
}
}
fn input_mpc_contract_account_id(
_context: &crate::GlobalContext,
) -> color_eyre::eyre::Result<Option<crate::types::account_id::AccountId>> {
#[derive(strum_macros::Display)]
enum ConfirmOptions {
#[strum(to_string = "Yes, I want to enter the MPC contract account ID")]
Yes,
#[strum(to_string = "No, I don't want to enter the MPC contract account ID")]
No,
}
let select_choose_input = Select::new(
"Do you want to enter the MPC contract account ID?",
vec![ConfirmOptions::Yes, ConfirmOptions::No],
)
.prompt()?;
if let ConfirmOptions::Yes = select_choose_input {
let mpc_contract_account_id: crate::types::account_id::AccountId =
CustomType::new("What is the MPC (Multi-Party Computation) contract account ID?")
.prompt()?;
Ok(Some(mpc_contract_account_id))
} else {
Ok(None)
}
}
}