Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preconfigured start - for dockerization #6

Merged
merged 2 commits into from
Dec 13, 2023
Merged
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
10 changes: 10 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ escalation_interval = "1m"
datadog_enabled = false
statsd_enabled = false

[predefined.network]
chain_id = 31337
http_url = "http://127.0.0.1:8545"
ws_url = "ws://127.0.0.1:8545"

[predefined.relayer]
id = "1b908a34-5dc1-4d2d-a146-5eb46e975830"
chain_id = 31337
key_id = "d10607662a85424f02a33fb1e6d095bd0ac7154396ff09762e41f82ff2233aaa"

[server]
host = "127.0.0.1:3000"
disable_auth = false
Expand Down
42 changes: 39 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,34 @@ pub struct TxSitterConfig {

#[serde(default)]
pub statsd_enabled: bool,

#[serde(default, skip_serializing_if = "Option::is_none")]
pub predefined: Option<Predefined>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct Predefined {
pub network: PredefinedNetwork,
pub relayer: PredefinedRelayer,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct PredefinedNetwork {
pub chain_id: u64,
pub name: String,
pub http_rpc: String,
pub ws_rpc: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct PredefinedRelayer {
pub id: String,
pub name: String,
pub key_id: String,
pub chain_id: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -101,10 +129,16 @@ pub enum KeysConfig {
#[serde(rename_all = "snake_case")]
pub struct KmsKeysConfig {}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct LocalKeysConfig {}

impl KeysConfig {
pub fn is_local(&self) -> bool {
matches!(self, Self::Local(_))
}
}

#[cfg(test)]
mod tests {
use indoc::indoc;
Expand Down Expand Up @@ -156,6 +190,7 @@ mod tests {
escalation_interval: Duration::from_secs(60 * 60),
datadog_enabled: false,
statsd_enabled: false,
predefined: None,
},
server: ServerConfig {
host: SocketAddr::from(([127, 0, 0, 1], 3000)),
Expand All @@ -166,7 +201,7 @@ mod tests {
"postgres://postgres:postgres@127.0.0.1:52804/database"
.to_string(),
),
keys: KeysConfig::Local(LocalKeysConfig {}),
keys: KeysConfig::Local(LocalKeysConfig::default()),
};

let toml = toml::to_string_pretty(&config).unwrap();
Expand All @@ -181,6 +216,7 @@ mod tests {
escalation_interval: Duration::from_secs(60 * 60),
datadog_enabled: false,
statsd_enabled: false,
predefined: None,
},
server: ServerConfig {
host: SocketAddr::from(([127, 0, 0, 1], 3000)),
Expand All @@ -194,7 +230,7 @@ mod tests {
password: "pass".to_string(),
database: "db".to_string(),
}),
keys: KeysConfig::Local(LocalKeysConfig {}),
keys: KeysConfig::Local(LocalKeysConfig::default()),
};

let toml = toml::to_string_pretty(&config).unwrap();
Expand Down
125 changes: 6 additions & 119 deletions src/keys.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
use aws_config::BehaviorVersion;
use aws_sdk_kms::types::{KeySpec, KeyUsageType};
use ethers::core::k256::ecdsa::SigningKey;
use ethers::signers::Wallet;
use eyre::{Context, ContextCompat};
pub use universal_signer::UniversalSigner;

use crate::aws::ethers_signer::AwsSigner;
use crate::config::{KmsKeysConfig, LocalKeysConfig};
pub mod kms_keys;
pub mod local_keys;
pub mod universal_signer;

mod universal_signer;
pub use kms_keys::KmsKeys;
pub use local_keys::LocalKeys;
pub use universal_signer::UniversalSigner;

#[async_trait::async_trait]
pub trait KeysSource: Send + Sync + 'static {
Expand All @@ -18,112 +14,3 @@ pub trait KeysSource: Send + Sync + 'static {
/// Loads the key using the provided id
async fn load_signer(&self, id: String) -> eyre::Result<UniversalSigner>;
}

pub struct KmsKeys {
kms_client: aws_sdk_kms::Client,
}

impl KmsKeys {
pub async fn new(_config: &KmsKeysConfig) -> eyre::Result<Self> {
let aws_config =
aws_config::load_defaults(BehaviorVersion::latest()).await;

let kms_client = aws_sdk_kms::Client::new(&aws_config);

Ok(Self { kms_client })
}
}

#[async_trait::async_trait]
impl KeysSource for KmsKeys {
async fn new_signer(&self) -> eyre::Result<(String, UniversalSigner)> {
let kms_key = self
.kms_client
.create_key()
.key_spec(KeySpec::EccSecgP256K1)
.key_usage(KeyUsageType::SignVerify)
.send()
.await
.context("AWS Error")?;

let key_id =
kms_key.key_metadata.context("Missing key metadata")?.key_id;

let signer = AwsSigner::new(
self.kms_client.clone(),
key_id.clone(),
1, // TODO: get chain id from provider
)
.await?;

Ok((key_id, UniversalSigner::Aws(signer)))
}

async fn load_signer(&self, id: String) -> eyre::Result<UniversalSigner> {
let signer = AwsSigner::new(
self.kms_client.clone(),
id.clone(),
1, // TODO: get chain id from provider
)
.await?;

Ok(UniversalSigner::Aws(signer))
}
}

pub struct LocalKeys {
rng: rand::rngs::OsRng,
}

impl LocalKeys {
pub fn new(_config: &LocalKeysConfig) -> Self {
Self {
rng: rand::rngs::OsRng,
}
}
}

#[async_trait::async_trait]
impl KeysSource for LocalKeys {
async fn new_signer(&self) -> eyre::Result<(String, UniversalSigner)> {
let signing_key = SigningKey::random(&mut self.rng.clone());

let key_id = signing_key.to_bytes().to_vec();
let key_id = hex::encode(key_id);

let signer = Wallet::from(signing_key);

Ok((key_id, UniversalSigner::Local(signer)))
}

async fn load_signer(&self, id: String) -> eyre::Result<UniversalSigner> {
let key_id = hex::decode(id)?;
let signing_key = SigningKey::from_slice(key_id.as_slice())?;

let signer = Wallet::from(signing_key);

Ok(UniversalSigner::Local(signer))
}
}

#[cfg(test)]
mod tests {
use ethers::signers::Signer;

use super::*;

#[tokio::test]
async fn local_roundtrip() -> eyre::Result<()> {
let keys_source = LocalKeys::new(&LocalKeysConfig {});

let (id, signer) = keys_source.new_signer().await?;

let address = signer.address();

let signer = keys_source.load_signer(id).await?;

assert_eq!(address, signer.address());

Ok(())
}
}
59 changes: 59 additions & 0 deletions src/keys/kms_keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use aws_config::BehaviorVersion;
use aws_sdk_kms::types::{KeySpec, KeyUsageType};
use eyre::{Context, ContextCompat};

use super::{KeysSource, UniversalSigner};
use crate::aws::ethers_signer::AwsSigner;
use crate::config::KmsKeysConfig;

pub struct KmsKeys {
kms_client: aws_sdk_kms::Client,
}

impl KmsKeys {
pub async fn new(_config: &KmsKeysConfig) -> eyre::Result<Self> {
let aws_config =
aws_config::load_defaults(BehaviorVersion::latest()).await;

let kms_client = aws_sdk_kms::Client::new(&aws_config);

Ok(Self { kms_client })
}
}

#[async_trait::async_trait]
impl KeysSource for KmsKeys {
async fn new_signer(&self) -> eyre::Result<(String, UniversalSigner)> {
let kms_key = self
.kms_client
.create_key()
.key_spec(KeySpec::EccSecgP256K1)
.key_usage(KeyUsageType::SignVerify)
.send()
.await
.context("AWS Error")?;

let key_id =
kms_key.key_metadata.context("Missing key metadata")?.key_id;

let signer = AwsSigner::new(
self.kms_client.clone(),
key_id.clone(),
1, // TODO: get chain id from provider
)
.await?;

Ok((key_id, UniversalSigner::Aws(signer)))
}

async fn load_signer(&self, id: String) -> eyre::Result<UniversalSigner> {
let signer = AwsSigner::new(
self.kms_client.clone(),
id.clone(),
1, // TODO: get chain id from provider
)
.await?;

Ok(UniversalSigner::Aws(signer))
}
}
69 changes: 69 additions & 0 deletions src/keys/local_keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use ethers::core::k256::ecdsa::SigningKey;
use ethers::signers::Wallet;

use super::universal_signer::UniversalSigner;
use super::KeysSource;
use crate::config::LocalKeysConfig;

pub struct LocalKeys {
rng: rand::rngs::OsRng,
}

impl LocalKeys {
pub fn new(_config: &LocalKeysConfig) -> Self {
Self {
rng: rand::rngs::OsRng,
}
}
}

#[async_trait::async_trait]
impl KeysSource for LocalKeys {
async fn new_signer(&self) -> eyre::Result<(String, UniversalSigner)> {
let signing_key = SigningKey::random(&mut self.rng.clone());

let key_id = signing_key.to_bytes().to_vec();
let key_id = hex::encode(key_id);

let signer = Wallet::from(signing_key);

Ok((key_id, UniversalSigner::Local(signer)))
}

async fn load_signer(&self, id: String) -> eyre::Result<UniversalSigner> {
let signing_key = signing_key_from_hex(&id)?;

let signer = Wallet::from(signing_key);

Ok(UniversalSigner::Local(signer))
}
}

pub fn signing_key_from_hex(s: &str) -> eyre::Result<SigningKey> {
let key_id = hex::decode(s)?;
let signing_key = SigningKey::from_slice(key_id.as_slice())?;

Ok(signing_key)
}

#[cfg(test)]
mod tests {
use ethers::signers::Signer;

use super::*;

#[tokio::test]
async fn local_roundtrip() -> eyre::Result<()> {
let keys_source = LocalKeys::new(&LocalKeysConfig::default());

let (id, signer) = keys_source.new_signer().await?;

let address = signer.address();

let signer = keys_source.load_signer(id).await?;

assert_eq!(address, signer.address());

Ok(())
}
}
Loading