use crate::nyxd::contract_traits::NymContractsProvider;
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
use crate::signing::signer::OfflineSigner;
use async_trait::async_trait;
use nym_geolocation_contract_common::{
AgentPermissions, EntryKey, ExecuteMsg as GeolocationExecuteMsg, LocationPayload, Measurement,
NymNodeLocation, Subject,
};
use nym_mixnet_contract_common::NodeId;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait GeolocationSigningClient {
async fn execute_geolocation_contract(
&self,
fee: Option<Fee>,
msg: GeolocationExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>;
async fn submit_measurements(
&self,
measurements: Vec<Measurement>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::SubmitMeasurements { measurements };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::SubmitMeasurements".into(),
vec![],
)
.await
}
async fn relay_self_declarations(
&self,
declarations: Vec<NymNodeLocation>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::RelaySelfDeclarations { declarations };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::RelaySelfDeclarations".into(),
vec![],
)
.await
}
async fn set_location_override(
&self,
subject: Subject,
payload: LocationPayload,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::SetOverride { subject, payload };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::SetOverride".into(),
vec![],
)
.await
}
async fn remove_location_override(
&self,
subject: Subject,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::RemoveOverride { subject };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::RemoveOverride".into(),
vec![],
)
.await
}
async fn set_whitelisted_agent(
&self,
agent: String,
permissions: AgentPermissions,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::SetWhitelistedAgent { agent, permissions };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::SetWhitelistedAgent".into(),
vec![],
)
.await
}
async fn remove_whitelisted_agent(
&self,
agent: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::RemoveWhitelistedAgent { agent };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::RemoveWhitelistedAgent".into(),
vec![],
)
.await
}
async fn remove_geolocation_entries(
&self,
keys: Vec<EntryKey>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::RemoveEntries { keys };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::RemoveEntries".into(),
vec![],
)
.await
}
async fn update_admin(
&self,
admin: String,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::UpdateAdmin { admin };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::UpdateAdmin".into(),
vec![],
)
.await
}
async fn update_geolocation_config(
&self,
max_skew_secs: Option<u64>,
max_batch_size: Option<u32>,
max_payload_size: Option<u32>,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::UpdateConfig {
max_skew_secs,
max_batch_size,
max_payload_size,
};
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::UpdateConfig".into(),
vec![],
)
.await
}
async fn on_nym_node_unbond(
&self,
node_id: NodeId,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let msg = GeolocationExecuteMsg::OnNymNodeUnbond { node_id };
self.execute_geolocation_contract(
fee,
msg,
"GeolocationExecuteMsg::OnNymNodeUnbond".into(),
vec![],
)
.await
}
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<C> GeolocationSigningClient for C
where
C: SigningCosmWasmClient + NymContractsProvider + Sync,
NyxdError: From<<Self as OfflineSigner>::Error>,
{
async fn execute_geolocation_contract(
&self,
fee: Option<Fee>,
msg: GeolocationExecuteMsg,
memo: String,
funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError> {
let contract_address = &self
.geolocation_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("geolocation contract"))?;
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier())));
let signer_address = &self.signer_addresses()[0];
self.execute(signer_address, contract_address, &msg, fee, memo, funds)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
#[allow(dead_code)]
fn all_execute_variants_are_covered<C: GeolocationSigningClient + Send + Sync>(
client: C,
msg: GeolocationExecuteMsg,
) {
match msg {
GeolocationExecuteMsg::SubmitMeasurements { measurements } => {
client.submit_measurements(measurements, None).ignore()
}
GeolocationExecuteMsg::RelaySelfDeclarations { declarations } => {
client.relay_self_declarations(declarations, None).ignore()
}
GeolocationExecuteMsg::SetOverride { subject, payload } => client
.set_location_override(subject, payload, None)
.ignore(),
GeolocationExecuteMsg::RemoveOverride { subject } => {
client.remove_location_override(subject, None).ignore()
}
GeolocationExecuteMsg::SetWhitelistedAgent { agent, permissions } => client
.set_whitelisted_agent(agent, permissions, None)
.ignore(),
GeolocationExecuteMsg::RemoveWhitelistedAgent { agent } => {
client.remove_whitelisted_agent(agent, None).ignore()
}
GeolocationExecuteMsg::RemoveEntries { keys } => {
client.remove_geolocation_entries(keys, None).ignore()
}
GeolocationExecuteMsg::UpdateAdmin { admin } => {
client.update_admin(admin, None).ignore()
}
GeolocationExecuteMsg::UpdateConfig {
max_skew_secs,
max_batch_size,
max_payload_size,
} => client
.update_geolocation_config(max_skew_secs, max_batch_size, max_payload_size, None)
.ignore(),
GeolocationExecuteMsg::OnNymNodeUnbond { node_id } => {
client.on_nym_node_unbond(node_id, None).ignore()
}
};
}
}