Allow blockchain config to have sub-types
This commit is contained in:
parent
c4e5438ac2
commit
dc7d533c42
10 changed files with 56 additions and 29 deletions
|
@ -11,7 +11,7 @@ fn default_chain_sync_step() -> u64 { 1000 }
|
||||||
fn default_chain_reorg_max_depth() -> u64 { 10 }
|
fn default_chain_reorg_max_depth() -> u64 { 10 }
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
pub struct BlockchainConfig {
|
pub struct EthereumConfig {
|
||||||
// CAIP-2 chain ID
|
// CAIP-2 chain ID
|
||||||
pub chain_id: ChainId,
|
pub chain_id: ChainId,
|
||||||
// Additional information for clients
|
// Additional information for clients
|
||||||
|
@ -30,7 +30,7 @@ pub struct BlockchainConfig {
|
||||||
pub chain_reorg_max_depth: u64,
|
pub chain_reorg_max_depth: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockchainConfig {
|
impl EthereumConfig {
|
||||||
pub fn try_ethereum_chain_id(&self) -> Result<u32, ChainIdError> {
|
pub fn try_ethereum_chain_id(&self) -> Result<u32, ChainIdError> {
|
||||||
parse_caip2_chain_id(&self.chain_id)
|
parse_caip2_chain_id(&self.chain_id)
|
||||||
}
|
}
|
||||||
|
@ -39,3 +39,16 @@ impl BlockchainConfig {
|
||||||
self.try_ethereum_chain_id().unwrap()
|
self.try_ethereum_chain_id().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum BlockchainConfig {
|
||||||
|
Ethereum(EthereumConfig),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockchainConfig {
|
||||||
|
pub fn ethereum_config(&self) -> Option<&EthereumConfig> {
|
||||||
|
let Self::Ethereum(ethereum_config) = self;
|
||||||
|
Some(ethereum_config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -243,11 +243,13 @@ pub fn parse_config() -> Config {
|
||||||
check_directory_owner(&config.storage_dir);
|
check_directory_owner(&config.storage_dir);
|
||||||
config.try_instance_url().expect("invalid instance URI");
|
config.try_instance_url().expect("invalid instance URI");
|
||||||
if let Some(blockchain_config) = config.blockchain.as_ref() {
|
if let Some(blockchain_config) = config.blockchain.as_ref() {
|
||||||
blockchain_config.try_ethereum_chain_id().unwrap();
|
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
|
||||||
if !blockchain_config.contract_dir.exists() {
|
ethereum_config.try_ethereum_chain_id().unwrap();
|
||||||
|
if !ethereum_config.contract_dir.exists() {
|
||||||
panic!("contract directory does not exist");
|
panic!("contract directory does not exist");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
if config.ipfs_api_url.is_some() != config.ipfs_gateway_url.is_some() {
|
if config.ipfs_api_url.is_some() != config.ipfs_gateway_url.is_some() {
|
||||||
panic!("both ipfs_api_url and ipfs_gateway_url must be set");
|
panic!("both ipfs_api_url and ipfs_gateway_url must be set");
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,6 @@ mod blockchain;
|
||||||
mod environment;
|
mod environment;
|
||||||
mod main;
|
mod main;
|
||||||
|
|
||||||
pub use blockchain::BlockchainConfig;
|
pub use blockchain::EthereumConfig;
|
||||||
pub use environment::Environment;
|
pub use environment::Environment;
|
||||||
pub use main::{parse_config, Config, Instance};
|
pub use main::{parse_config, Config, Instance};
|
||||||
|
|
|
@ -8,7 +8,7 @@ use web3::{
|
||||||
transports::Http,
|
transports::Http,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::config::BlockchainConfig;
|
use crate::config::EthereumConfig;
|
||||||
use super::api::connect;
|
use super::api::connect;
|
||||||
use super::errors::EthereumError;
|
use super::errors::EthereumError;
|
||||||
use super::sync::{
|
use super::sync::{
|
||||||
|
@ -96,7 +96,7 @@ pub struct Blockchain {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_contracts(
|
pub async fn get_contracts(
|
||||||
config: &BlockchainConfig,
|
config: &EthereumConfig,
|
||||||
storage_dir: &Path,
|
storage_dir: &Path,
|
||||||
) -> Result<Blockchain, EthereumError> {
|
) -> Result<Blockchain, EthereumError> {
|
||||||
let web3 = connect(&config.api_url)?;
|
let web3 = connect(&config.api_url)?;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use web3::{
|
||||||
types::{BlockNumber, FilterBuilder},
|
types::{BlockNumber, FilterBuilder},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::config::BlockchainConfig;
|
use crate::config::EthereumConfig;
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
use crate::ipfs::utils::parse_ipfs_url;
|
use crate::ipfs::utils::parse_ipfs_url;
|
||||||
|
@ -127,7 +127,7 @@ pub async fn process_nft_events(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_mint_signature(
|
pub fn create_mint_signature(
|
||||||
blockchain_config: &BlockchainConfig,
|
blockchain_config: &EthereumConfig,
|
||||||
user_address: &str,
|
user_address: &str,
|
||||||
token_uri: &str,
|
token_uri: &str,
|
||||||
) -> Result<SignatureData, EthereumError> {
|
) -> Result<SignatureData, EthereumError> {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::activitypub::builders::{
|
||||||
remove_person::prepare_remove_person,
|
remove_person::prepare_remove_person,
|
||||||
};
|
};
|
||||||
use crate::activitypub::identifiers::LocalActorCollection;
|
use crate::activitypub::identifiers::LocalActorCollection;
|
||||||
use crate::config::{BlockchainConfig, Instance};
|
use crate::config::{EthereumConfig, Instance};
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::{ConversionError, DatabaseError};
|
use crate::errors::{ConversionError, DatabaseError};
|
||||||
use crate::models::notifications::queries::{
|
use crate::models::notifications::queries::{
|
||||||
|
@ -245,7 +245,7 @@ pub async fn check_subscriptions(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_subscription_signature(
|
pub fn create_subscription_signature(
|
||||||
blockchain_config: &BlockchainConfig,
|
blockchain_config: &EthereumConfig,
|
||||||
user_address: &str,
|
user_address: &str,
|
||||||
price: u64,
|
price: u64,
|
||||||
) -> Result<SignatureData, EthereumError> {
|
) -> Result<SignatureData, EthereumError> {
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -53,11 +53,15 @@ async fn main() -> std::io::Result<()> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain {
|
let maybe_blockchain = if let Some(blockchain_config) = &config.blockchain {
|
||||||
|
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
|
||||||
// Create blockchain interface
|
// Create blockchain interface
|
||||||
get_contracts(blockchain_config, &config.storage_dir).await
|
get_contracts(ethereum_config, &config.storage_dir).await
|
||||||
.map(Some).unwrap()
|
.map(Some).unwrap()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
};
|
};
|
||||||
let maybe_contract_set = maybe_blockchain.clone()
|
let maybe_contract_set = maybe_blockchain.clone()
|
||||||
.map(|blockchain| blockchain.contract_set);
|
.map(|blockchain| blockchain.contract_set);
|
||||||
|
@ -148,12 +152,14 @@ async fn main() -> std::io::Result<()> {
|
||||||
.service(nodeinfo::get_nodeinfo)
|
.service(nodeinfo::get_nodeinfo)
|
||||||
.service(nodeinfo::get_nodeinfo_2_0);
|
.service(nodeinfo::get_nodeinfo_2_0);
|
||||||
if let Some(blockchain_config) = &config.blockchain {
|
if let Some(blockchain_config) = &config.blockchain {
|
||||||
|
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
|
||||||
// Serve artifacts if available
|
// Serve artifacts if available
|
||||||
app = app.service(actix_files::Files::new(
|
app = app.service(actix_files::Files::new(
|
||||||
"/contracts",
|
"/contracts",
|
||||||
&blockchain_config.contract_dir,
|
ðereum_config.contract_dir,
|
||||||
));
|
));
|
||||||
}
|
};
|
||||||
|
};
|
||||||
app
|
app
|
||||||
})
|
})
|
||||||
.workers(num_workers)
|
.workers(num_workers)
|
||||||
|
|
|
@ -293,14 +293,16 @@ async fn authorize_subscription(
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &**get_database_client(&db_pool).await?;
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let blockchain_config = config.blockchain.as_ref()
|
let ethereum_config = config.blockchain.as_ref()
|
||||||
|
.ok_or(HttpError::NotSupported)?
|
||||||
|
.ethereum_config()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.ok_or(HttpError::NotSupported)?;
|
||||||
// Wallet address must be public, because subscribers should be able
|
// Wallet address must be public, because subscribers should be able
|
||||||
// to verify that payments are actually sent to the recipient.
|
// to verify that payments are actually sent to the recipient.
|
||||||
let wallet_address = current_user.public_wallet_address()
|
let wallet_address = current_user.public_wallet_address()
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let signature = create_subscription_signature(
|
let signature = create_subscription_signature(
|
||||||
blockchain_config,
|
ethereum_config,
|
||||||
&wallet_address,
|
&wallet_address,
|
||||||
query_params.price,
|
query_params.price,
|
||||||
).map_err(|_| HttpError::InternalError)?;
|
).map_err(|_| HttpError::InternalError)?;
|
||||||
|
|
|
@ -41,6 +41,8 @@ fn get_full_api_version(version: &str) -> String {
|
||||||
|
|
||||||
impl InstanceInfo {
|
impl InstanceInfo {
|
||||||
pub fn create(config: &Config, maybe_blockchain: Option<&ContractSet>) -> Self {
|
pub fn create(config: &Config, maybe_blockchain: Option<&ContractSet>) -> Self {
|
||||||
|
let ethereum_config = config.blockchain.as_ref()
|
||||||
|
.and_then(|conf| conf.ethereum_config());
|
||||||
let blockchain_features = maybe_blockchain.map(|contract_set| {
|
let blockchain_features = maybe_blockchain.map(|contract_set| {
|
||||||
BlockchainFeatures {
|
BlockchainFeatures {
|
||||||
minter: contract_set.collectible.is_some(),
|
minter: contract_set.collectible.is_some(),
|
||||||
|
@ -56,14 +58,14 @@ impl InstanceInfo {
|
||||||
registrations: config.registrations_open,
|
registrations: config.registrations_open,
|
||||||
login_message: config.login_message.clone(),
|
login_message: config.login_message.clone(),
|
||||||
post_character_limit: config.post_character_limit,
|
post_character_limit: config.post_character_limit,
|
||||||
blockchain_id: config.blockchain.as_ref()
|
blockchain_id: ethereum_config
|
||||||
.map(|val| val.chain_id.to_string()),
|
.map(|val| val.chain_id.to_string()),
|
||||||
blockchain_explorer_url: config.blockchain.as_ref()
|
blockchain_explorer_url: ethereum_config
|
||||||
.and_then(|val| val.explorer_url.clone()),
|
.and_then(|val| val.explorer_url.clone()),
|
||||||
blockchain_contract_address: config.blockchain.as_ref()
|
blockchain_contract_address: ethereum_config
|
||||||
.map(|val| val.contract_address.clone()),
|
.map(|val| val.contract_address.clone()),
|
||||||
blockchain_features: blockchain_features,
|
blockchain_features: blockchain_features,
|
||||||
blockchain_info: config.blockchain.as_ref()
|
blockchain_info: ethereum_config
|
||||||
.and_then(|val| val.chain_info.clone()),
|
.and_then(|val| val.chain_info.clone()),
|
||||||
ipfs_gateway_url: config.ipfs_gateway_url.clone(),
|
ipfs_gateway_url: config.ipfs_gateway_url.clone(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,7 +425,9 @@ async fn get_signature(
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &**get_database_client(&db_pool).await?;
|
let db_client = &**get_database_client(&db_pool).await?;
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let blockchain_config = config.blockchain.as_ref()
|
let ethereum_config = config.blockchain.as_ref()
|
||||||
|
.ok_or(HttpError::NotSupported)?
|
||||||
|
.ethereum_config()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.ok_or(HttpError::NotSupported)?;
|
||||||
// Wallet address must be public because minting exposes it
|
// Wallet address must be public because minting exposes it
|
||||||
let wallet_address = current_user.public_wallet_address()
|
let wallet_address = current_user.public_wallet_address()
|
||||||
|
@ -440,7 +442,7 @@ async fn get_signature(
|
||||||
.ok_or(HttpError::PermissionError)?;
|
.ok_or(HttpError::PermissionError)?;
|
||||||
let token_uri = get_ipfs_url(&ipfs_cid);
|
let token_uri = get_ipfs_url(&ipfs_cid);
|
||||||
let signature = create_mint_signature(
|
let signature = create_mint_signature(
|
||||||
blockchain_config,
|
ethereum_config,
|
||||||
&wallet_address,
|
&wallet_address,
|
||||||
&token_uri,
|
&token_uri,
|
||||||
).map_err(|_| HttpError::InternalError)?;
|
).map_err(|_| HttpError::InternalError)?;
|
||||||
|
|
Loading…
Reference in a new issue