Skip to main content

hypercall/client/wallet_client/
directives.rs

1use super::WalletClient;
2use alloy::signers::local::PrivateKeySigner;
3use hypercall_types::{
4    directives::{self, ActionKey},
5    WalletAddress,
6};
7use sonic_rs::{json, Value};
8use std::str::FromStr;
9
10impl WalletClient {
11    pub async fn sign_directive(
12        &self,
13        action_key: ActionKey,
14        account: WalletAddress,
15        nonce: u64,
16        action: &sonic_rs::Value,
17        chain_id: u64,
18    ) -> Result<String, Box<dyn std::error::Error + Send + Sync>> {
19        let signer = PrivateKeySigner::from_str(&self.private_key)?;
20        directives::sign_directive_with_signer(
21            &signer,
22            action_key,
23            account.inner(),
24            nonce,
25            action,
26            chain_id,
27        )
28        .await
29        .map_err(|e| Self::input_error(e.to_string()))
30    }
31
32    pub async fn submit_directive(
33        &self,
34        base_url: &str,
35        action_key: ActionKey,
36        account: WalletAddress,
37        nonce: u64,
38        action: Value,
39        chain_id: u64,
40    ) -> Result<Value, Box<dyn std::error::Error + Send + Sync>> {
41        let sonic_action: sonic_rs::Value = action.clone();
42        let signature = self
43            .sign_directive(action_key, account, nonce, &sonic_action, chain_id)
44            .await?;
45
46        let request = json!({
47            "account": account,
48            "nonce": nonce,
49            "action": action,
50            "signature": signature,
51        });
52
53        let response = self
54            .http_client
55            .post(format!("{}/v1/actions/{}", base_url, action_key.as_str()))
56            .json(&request)
57            .send()
58            .await?;
59
60        let status = response.status();
61        let body = response.text().await?;
62        if !status.is_success() {
63            return Err(format!(
64                "Failed to submit directive '{}': {} - {}",
65                action_key.as_str(),
66                status,
67                body
68            )
69            .into());
70        }
71
72        Ok(sonic_rs::from_str(&body)?)
73    }
74}