diff --git a/Cargo.lock b/Cargo.lock index 4f20214c7..0fb6cc04b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,6 +264,7 @@ dependencies = [ "random-string", "report", "reqwest 0.11.27", + "rewards", "router-api", "serde", "serde_json", diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index 7db154727..2b021a178 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -44,6 +44,7 @@ prost = "0.11.9" prost-types = "0.11.9" report = { workspace = true } reqwest = { version = "0.11.24", default-features = false } +rewards = { workspace = true } router-api = { workspace = true } serde = { version = "1.0.147", features = ["derive"] } serde_json = { workspace = true } diff --git a/ampd/src/commands/mod.rs b/ampd/src/commands/mod.rs index b3e0d5382..cd0e1bcea 100644 --- a/ampd/src/commands/mod.rs +++ b/ampd/src/commands/mod.rs @@ -26,6 +26,7 @@ pub mod deregister_chain_support; pub mod register_chain_support; pub mod register_public_key; pub mod send_tokens; +pub mod set_rewards_proxy; pub mod unbond_verifier; pub mod verifier_address; @@ -49,6 +50,8 @@ pub enum SubCommand { VerifierAddress, /// Send tokens from the verifier account to a specified address SendTokens(send_tokens::Args), + /// Set a proxy address to receive rewards, instead of receiving rewards at the verifier address + SetRewardsProxy(set_rewards_proxy::Args), } #[derive(Debug, Deserialize, Serialize, PartialEq)] @@ -64,6 +67,19 @@ impl Default for ServiceRegistryConfig { } } +#[derive(Debug, Deserialize, Serialize, PartialEq)] +pub struct RewardsConfig { + pub cosmwasm_contract: TMAddress, +} + +impl Default for RewardsConfig { + fn default() -> Self { + Self { + cosmwasm_contract: AccountId::new(PREFIX, &[0; 32]).unwrap().into(), + } + } +} + async fn verifier_pub_key(config: tofnd::Config) -> Result { MultisigClient::new(config.party_uid, config.url.clone()) .await diff --git a/ampd/src/commands/set_rewards_proxy.rs b/ampd/src/commands/set_rewards_proxy.rs new file mode 100644 index 000000000..70f2c90fe --- /dev/null +++ b/ampd/src/commands/set_rewards_proxy.rs @@ -0,0 +1,41 @@ +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmrs::tx::Msg; +use error_stack::Result; +use report::ResultCompatExt; +use rewards::msg::ExecuteMsg; +use router_api::Address; +use valuable::Valuable; + +use crate::commands::{broadcast_tx, verifier_pub_key}; +use crate::config::Config; +use crate::{Error, PREFIX}; + +#[derive(clap::Args, Debug, Valuable)] +pub struct Args { + pub proxy_address: Address, +} + +pub async fn run(config: Config, args: Args) -> Result, Error> { + let pub_key = verifier_pub_key(config.tofnd_config.clone()).await?; + + let msg = serde_json::to_vec(&ExecuteMsg::SetVerifierProxy { + proxy_address: args.proxy_address, + }) + .expect("register chain support msg should serialize"); + + let tx = MsgExecuteContract { + sender: pub_key.account_id(PREFIX).change_context(Error::Tofnd)?, + contract: config.rewards.cosmwasm_contract.as_ref().clone(), + msg, + funds: vec![], + } + .into_any() + .expect("failed to serialize proto message"); + + let tx_hash = broadcast_tx(config, tx, pub_key).await?.txhash; + + Ok(Some(format!( + "successfully broadcast set verifier proxy transaction, tx hash: {}", + tx_hash + ))) +} diff --git a/ampd/src/config.rs b/ampd/src/config.rs index 8bc2a3c42..2ae2b9efc 100644 --- a/ampd/src/config.rs +++ b/ampd/src/config.rs @@ -2,7 +2,7 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use serde::{Deserialize, Serialize}; -use crate::commands::ServiceRegistryConfig; +use crate::commands::{RewardsConfig, ServiceRegistryConfig}; use crate::handlers::config::deserialize_handler_configs; use crate::handlers::{self}; use crate::tofnd::Config as TofndConfig; @@ -21,6 +21,7 @@ pub struct Config { pub handlers: Vec, pub tofnd_config: TofndConfig, pub service_registry: ServiceRegistryConfig, + pub rewards: RewardsConfig, } impl Default for Config { @@ -33,6 +34,7 @@ impl Default for Config { tofnd_config: TofndConfig::default(), event_processor: event_processor::Config::default(), service_registry: ServiceRegistryConfig::default(), + rewards: RewardsConfig::default(), health_check_bind_addr: SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 3000), } } diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index b9183adac..7662f2935 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -68,6 +68,7 @@ async fn prepare_app(cfg: Config) -> Result, Error> { tofnd_config, event_processor, service_registry: _service_registry, + rewards: _rewards, health_check_bind_addr, } = cfg; diff --git a/ampd/src/main.rs b/ampd/src/main.rs index 5445cca7a..5e82902e2 100644 --- a/ampd/src/main.rs +++ b/ampd/src/main.rs @@ -6,7 +6,8 @@ use std::process::ExitCode; use ::config::{Config as cfg, Environment, File, FileFormat, FileSourceFile}; use ampd::commands::{ bond_verifier, claim_stake, daemon, deregister_chain_support, register_chain_support, - register_public_key, send_tokens, unbond_verifier, verifier_address, SubCommand, + register_public_key, send_tokens, set_rewards_proxy, unbond_verifier, verifier_address, + SubCommand, }; use ampd::config::Config; use ampd::Error; @@ -67,6 +68,7 @@ async fn main() -> ExitCode { Some(SubCommand::UnbondVerifier(args)) => unbond_verifier::run(cfg, args).await, Some(SubCommand::ClaimStake(args)) => claim_stake::run(cfg, args).await, Some(SubCommand::SendTokens(args)) => send_tokens::run(cfg, args).await, + Some(SubCommand::SetRewardsProxy(args)) => set_rewards_proxy::run(cfg, args).await, }; match result { diff --git a/ampd/src/tests/config_template.toml b/ampd/src/tests/config_template.toml index 4e6828eb6..ec18a1d91 100644 --- a/ampd/src/tests/config_template.toml +++ b/ampd/src/tests/config_template.toml @@ -89,3 +89,6 @@ key_uid = 'axelar' [service_registry] cosmwasm_contract = 'axelar1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqecnww6' + +[rewards] +cosmwasm_contract = 'axelar1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqecnww6' diff --git a/packages/router-api/src/primitives.rs b/packages/router-api/src/primitives.rs index 220f43272..315450baa 100644 --- a/packages/router-api/src/primitives.rs +++ b/packages/router-api/src/primitives.rs @@ -78,7 +78,7 @@ impl From for Vec { #[cw_serde] #[serde(try_from = "String")] -#[derive(Eq, Hash)] +#[derive(Eq, Hash, Valuable)] pub struct Address(nonempty::String); impl Deref for Address {