Skip to main content

hypercall/client/wallet_client/
onchain.rs

1use super::WalletClient;
2
3impl WalletClient {
4    /// Create account contract on the Exchange using alloy (must be called first)
5    pub async fn create_account_on_chain(
6        &self,
7        exchange_address: &str,
8        rpc_url: &str,
9    ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
10        use alloy::{
11            network::EthereumWallet, providers::ProviderBuilder, signers::local::PrivateKeySigner,
12            sol,
13        };
14
15        // Define the Exchange contract interface
16        sol! {
17            #[sol(rpc)]
18            contract Exchange {
19                function createAccount() external payable returns (address account);
20            }
21        }
22
23        tracing::info!(
24            "Creating account contract on-chain for wallet: {}",
25            self.wallet_address
26        );
27
28        use std::str::FromStr;
29
30        // Parse private key and create signer
31        let signer = PrivateKeySigner::from_str(&self.private_key)?;
32        let wallet = EthereumWallet::from(signer);
33
34        // Create provider with wallet
35        let provider = ProviderBuilder::new()
36            .with_gas_estimation()
37            .wallet(wallet)
38            .connect_http(rpc_url.parse()?);
39
40        // Create contract instance
41        let exchange_addr = exchange_address.parse()?;
42        let contract = Exchange::new(exchange_addr, &provider);
43
44        // Call createAccount with some ETH for gas
45        let call = contract
46            .createAccount()
47            .value(alloy::primitives::U256::from(1000000000000000u64)); // 0.001 ETH
48        let tx_hash = call.send().await?.get_receipt().await?.transaction_hash;
49
50        tracing::info!("✅ Account created on-chain, tx: {}", tx_hash);
51
52        Ok(format!("0x{:x}", tx_hash))
53    }
54
55    /// Add API wallet to account on-chain (must be called after createAccount)
56    pub async fn add_api_wallet_on_chain(
57        &self,
58        account_address: &str,
59        api_wallet_address: &str,
60        exchange_address: &str,
61        rpc_url: &str,
62    ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
63        use alloy::{
64            network::EthereumWallet, providers::ProviderBuilder, signers::local::PrivateKeySigner,
65            sol,
66        };
67
68        // Define the Exchange contract interface
69        sol! {
70            #[sol(rpc)]
71            contract Exchange {
72                function addApiWallet(address account, address apiWallet) external;
73            }
74        }
75
76        tracing::info!(
77            "Adding API wallet {} to account {} on-chain",
78            api_wallet_address,
79            account_address
80        );
81
82        use std::str::FromStr;
83
84        // Parse private key and create signer
85        let signer = PrivateKeySigner::from_str(&self.private_key)?;
86        let wallet = EthereumWallet::from(signer);
87
88        // Create provider with wallet
89        let provider = ProviderBuilder::new()
90            .with_gas_estimation()
91            .wallet(wallet)
92            .connect_http(rpc_url.parse()?);
93
94        // Create contract instance
95        let exchange_addr = exchange_address.parse()?;
96        let contract = Exchange::new(exchange_addr, &provider);
97
98        // Parse addresses
99        let account_addr = account_address.parse()?;
100        let api_wallet_addr = api_wallet_address.parse()?;
101
102        // Call addApiWallet
103        let call = contract.addApiWallet(account_addr, api_wallet_addr);
104        let tx_hash = call.send().await?.get_receipt().await?.transaction_hash;
105
106        tracing::info!("✅ API wallet added on-chain, tx: {}", tx_hash);
107
108        Ok(format!("0x{:x}", tx_hash))
109    }
110}