1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use client_contracts::PosaLightClient;
use client_pangoro::client::PangoroClient;
use client_pangoro::component::PangoroClientComponent;
use relay_e2e::types::ethereum::FastEthereumAccount;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use subquery::types::BridgeName;
use subquery::{Subquery, SubqueryComponent, SubqueryConfig};
use thegraph_liketh::component::TheGraphLikeEthComponent;
use thegraph_liketh::config::TheGraphLikeEthConfig;
use thegraph_liketh::graph::TheGraphLikeEth;
use web3::contract::Options;
use web3::transports::Http;
use web3::types::{Address, U256};
use web3::Web3;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct BridgeConfig {
    pub pangoro_evm: PangoroEVMConfig,
    pub pangoro_substrate: PangoroSubstrateConfig,
    pub goerli: ChainInfoConfig,
    pub index: IndexConfig,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ChainInfoConfig {
    pub endpoint: String,
    pub execution_layer_endpoint: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub contract_address: Option<String>,
    pub account: String,
    pub private_key: String,
    pub inbound_address: String,
    pub outbound_address: String,
    pub fee_market_address: String,
    pub posa_light_client_address: String,
    pub gas: u64,
    pub gas_price: u64,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PangoroEVMConfig {
    pub endpoint: String,
    pub contract_address: String,
    pub execution_layer_contract_address: String,
    pub account: String,
    pub private_key: String,
    pub inbound_address: String,
    pub outbound_address: String,
    pub chain_message_committer_address: String,
    pub lane_message_committer_address: String,
    pub fee_market_address: String,
    pub gas: u64,
    pub gas_price: u64,
}

impl PangoroEVMConfig {
    pub fn to_fast_ethereum_account(&self) -> FastEthereumAccount {
        FastEthereumAccount::new(&self.private_key)
    }

    pub fn to_web3_client(&self) -> color_eyre::Result<Web3<Http>> {
        let transport = Http::new(&self.endpoint)?;
        let client = Web3::new(transport);
        Ok(client)
    }

    pub fn gas_option(&self) -> Options {
        Options {
            gas: Some(U256::from(self.gas)),
            gas_price: Some(U256::from(self.gas_price)),
            ..Default::default()
        }
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PangoroSubstrateConfig {
    pub endpoint: String,
    pub private_key: String,
}

impl ChainInfoConfig {
    pub fn to_posa_client(&self) -> color_eyre::Result<PosaLightClient> {
        let transport = Http::new(&self.execution_layer_endpoint)?;
        let client = Web3::new(transport);
        let address = Address::from_str(&self.posa_light_client_address)?;
        Ok(PosaLightClient::new(client, address)?)
    }

    pub fn to_ethereum_account(&self) -> FastEthereumAccount {
        FastEthereumAccount::new(&self.private_key)
    }

    pub fn to_web3_client(&self) -> color_eyre::Result<Web3<Http>> {
        let transport = Http::new(&self.execution_layer_endpoint)?;
        let client = Web3::new(transport);
        Ok(client)
    }

    pub fn gas_option(&self) -> Options {
        Options {
            gas: Some(U256::from(self.gas)),
            gas_price: Some(U256::from(self.gas_price)),
            ..Default::default()
        }
    }
}

impl From<PangoroSubstrateConfig> for client_pangoro::config::ClientConfig {
    fn from(config: PangoroSubstrateConfig) -> Self {
        client_pangoro::config::ClientConfig {
            endpoint: config.endpoint,
            relayer_private_key: config.private_key,
            relayer_real_account: None,
        }
    }
}

impl PangoroSubstrateConfig {
    pub async fn to_substrate_client(&self) -> color_eyre::Result<PangoroClient> {
        let config = self.clone().into();
        Ok(PangoroClientComponent::component(config).await?)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IndexConfig {
    pub pangoro: SubqueryConfig,
    pub pangoro_evm: TheGraphLikeEthConfig,
}

impl IndexConfig {
    pub fn to_pangoro_subquery(&self) -> Subquery {
        SubqueryComponent::component(self.pangoro.clone(), BridgeName::PangoroGoerli)
    }

    pub fn to_pangoro_thegraph(&self) -> color_eyre::Result<TheGraphLikeEth> {
        Ok(TheGraphLikeEthComponent::component(
            self.pangoro_evm.clone(),
            thegraph_liketh::types::LikethChain::Pangoro,
        )?)
    }
}