rose_wasm/
grpc.rs

1use rose_grpc_proto::pb::common::v1::{Base58Hash, Base58Pubkey, PageRequest};
2use rose_grpc_proto::pb::common::v2 as pb_common_v2;
3use rose_grpc_proto::pb::public::v2::*;
4use tonic_web_wasm_client::Client;
5use wasm_bindgen::prelude::*;
6
7#[wasm_bindgen]
8pub struct GrpcClient {
9    endpoint: String,
10}
11
12#[wasm_bindgen]
13impl GrpcClient {
14    #[wasm_bindgen(constructor)]
15    pub fn new(endpoint: String) -> Self {
16        Self { endpoint }
17    }
18
19    /// Get balance for a wallet address
20    #[wasm_bindgen(js_name = getBalanceByAddress)]
21    pub async fn get_balance_by_address(&self, address: String) -> Result<JsValue, JsValue> {
22        let client = Client::new(self.endpoint.clone());
23        let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
24
25        let request = WalletGetBalanceRequest {
26            selector: Some(wallet_get_balance_request::Selector::Address(
27                Base58Pubkey { key: address },
28            )),
29            page: Some(PageRequest {
30                client_page_items_limit: 0,
31                page_token: String::new(),
32                max_bytes: 0,
33            }),
34        };
35
36        let response = grpc_client
37            .wallet_get_balance(request)
38            .await
39            .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
40            .into_inner();
41
42        match response.result {
43            Some(wallet_get_balance_response::Result::Balance(balance)) => {
44                serde_wasm_bindgen::to_value(&balance)
45                    .map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
46            }
47            Some(wallet_get_balance_response::Result::Error(e)) => {
48                Err(JsValue::from_str(&format!("Server error: {}", e.message)))
49            }
50            None => Err(JsValue::from_str("Empty response from server")),
51        }
52    }
53
54    /// Get balance for a first name
55    #[wasm_bindgen(js_name = getBalanceByFirstName)]
56    pub async fn get_balance_by_first_name(&self, first_name: String) -> Result<JsValue, JsValue> {
57        let client = Client::new(self.endpoint.clone());
58        let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
59
60        let request = WalletGetBalanceRequest {
61            selector: Some(wallet_get_balance_request::Selector::FirstName(
62                Base58Hash { hash: first_name },
63            )),
64            page: Some(PageRequest {
65                client_page_items_limit: 0,
66                page_token: String::new(),
67                max_bytes: 0,
68            }),
69        };
70
71        let response = grpc_client
72            .wallet_get_balance(request)
73            .await
74            .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
75            .into_inner();
76
77        match response.result {
78            Some(wallet_get_balance_response::Result::Balance(balance)) => {
79                serde_wasm_bindgen::to_value(&balance)
80                    .map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
81            }
82            Some(wallet_get_balance_response::Result::Error(e)) => {
83                Err(JsValue::from_str(&format!("Server error: {}", e.message)))
84            }
85            None => Err(JsValue::from_str("Empty response from server")),
86        }
87    }
88
89    /// Send a transaction
90    #[wasm_bindgen(js_name = sendTransaction)]
91    pub async fn send_transaction(&self, raw_tx: JsValue) -> Result<JsValue, JsValue> {
92        let client = Client::new(self.endpoint.clone());
93        let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
94
95        let pb_raw_tx: pb_common_v2::RawTransaction = serde_wasm_bindgen::from_value(raw_tx)
96            .map_err(|e| JsValue::from_str(&format!("Deserialization error: {}", e)))?;
97
98        // Extract the tx_id from the raw transaction
99        let pb_tx_id = pb_raw_tx.id;
100
101        let request = WalletSendTransactionRequest {
102            tx_id: pb_tx_id,
103            raw_tx: Some(pb_raw_tx),
104        };
105
106        let response = grpc_client
107            .wallet_send_transaction(request)
108            .await
109            .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
110            .into_inner();
111
112        match response.result {
113            Some(wallet_send_transaction_response::Result::Ack(_)) => {
114                Ok(JsValue::from_str("Transaction acknowledged"))
115            }
116            Some(wallet_send_transaction_response::Result::Error(e)) => {
117                Err(JsValue::from_str(&format!("Server error: {}", e.message)))
118            }
119            None => Err(JsValue::from_str("Empty response from server")),
120        }
121    }
122
123    /// Check if a transaction was accepted
124    #[wasm_bindgen(js_name = transactionAccepted)]
125    pub async fn transaction_accepted(&self, tx_id: String) -> Result<bool, JsValue> {
126        let client = Client::new(self.endpoint.clone());
127        let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
128
129        let request = TransactionAcceptedRequest {
130            tx_id: Some(Base58Hash { hash: tx_id }),
131        };
132
133        let response = grpc_client
134            .transaction_accepted(request)
135            .await
136            .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
137            .into_inner();
138
139        match response.result {
140            Some(transaction_accepted_response::Result::Accepted(accepted)) => Ok(accepted),
141            Some(transaction_accepted_response::Result::Error(e)) => {
142                Err(JsValue::from_str(&format!("Server error: {}", e.message)))
143            }
144            None => Err(JsValue::from_str("Empty response from server")),
145        }
146    }
147}