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