1use iris_grpc_proto::pb::common::v1::{Base58Hash, Base58Pubkey, PageRequest};
2use iris_grpc_proto::pb::common::v2 as pb_common_v2;
3use iris_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 #[wasm_bindgen(js_name = getBalanceByAddress)]
21 pub async fn get_balance_by_address(
22 &self,
23 address: String,
24 ) -> Result<pb_common_v2::Balance, JsValue> {
25 let client = Client::new(self.endpoint.clone());
26 let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
27
28 let request = WalletGetBalanceRequest {
29 selector: Some(wallet_get_balance_request::Selector::Address(
30 Base58Pubkey { key: address },
31 )),
32 page: Some(PageRequest {
33 client_page_items_limit: 0,
34 page_token: String::new(),
35 max_bytes: 0,
36 }),
37 };
38
39 let response = grpc_client
40 .wallet_get_balance(request)
41 .await
42 .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
43 .into_inner();
44
45 match response.result {
46 Some(wallet_get_balance_response::Result::Balance(balance)) => Ok(balance),
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 #[wasm_bindgen(js_name = getBalanceByFirstName)]
56 pub async fn get_balance_by_first_name(
57 &self,
58 first_name: String,
59 ) -> Result<pb_common_v2::Balance, JsValue> {
60 let client = Client::new(self.endpoint.clone());
61 let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
62
63 let request = WalletGetBalanceRequest {
64 selector: Some(wallet_get_balance_request::Selector::FirstName(
65 Base58Hash { hash: first_name },
66 )),
67 page: Some(PageRequest {
68 client_page_items_limit: 0,
69 page_token: String::new(),
70 max_bytes: 0,
71 }),
72 };
73
74 let response = grpc_client
75 .wallet_get_balance(request)
76 .await
77 .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
78 .into_inner();
79
80 match response.result {
81 Some(wallet_get_balance_response::Result::Balance(balance)) => Ok(balance),
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 #[wasm_bindgen(js_name = sendTransaction)]
91 pub async fn send_transaction(
92 &self,
93 raw_tx: pb_common_v2::RawTransaction,
94 ) -> Result<String, JsValue> {
95 let client = Client::new(self.endpoint.clone());
96 let mut grpc_client = nockchain_service_client::NockchainServiceClient::new(client);
97
98 let pb_tx_id = raw_tx.id;
100
101 let request = WalletSendTransactionRequest {
102 tx_id: pb_tx_id,
103 raw_tx: Some(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(String::from("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 #[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
148 #[cfg(feature = "private-api")]
150 #[wasm_bindgen(js_name = peek)]
151 pub async fn peek(&self, pid: i32, path: iris_ztd::Noun) -> Result<iris_ztd::Noun, JsValue> {
152 let client = Client::new(self.endpoint.clone());
153 let mut grpc_client =
154 iris_grpc_proto::pb::private::v1::nock_app_service_client::NockAppServiceClient::new(
155 client,
156 );
157
158 let path_jam = iris_ztd::jam(path);
159 let request = iris_grpc_proto::pb::private::v1::PeekRequest {
160 pid,
161 path: path_jam,
162 };
163
164 let response = grpc_client
165 .peek(request)
166 .await
167 .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
168 .into_inner();
169
170 match response.result {
171 Some(iris_grpc_proto::pb::private::v1::peek_response::Result::Data(data)) => {
172 iris_ztd::cue(&data)
173 .ok_or_else(|| JsValue::from_str("Failed to cue noun from peek response"))
174 }
175 Some(iris_grpc_proto::pb::private::v1::peek_response::Result::Error(err)) => {
176 Err(JsValue::from_str(&format!("Server error: {}", err.message)))
177 }
178 None => Err(JsValue::from_str("Empty response from server")),
179 }
180 }
181
182 #[cfg(feature = "private-api")]
184 #[wasm_bindgen(js_name = poke)]
185 pub async fn poke(
186 &self,
187 pid: i32,
188 wire: iris_grpc_proto::pb::common::v1::Wire,
189 payload: iris_ztd::Noun,
190 ) -> Result<(), JsValue> {
191 let client = Client::new(self.endpoint.clone());
192 let mut grpc_client =
193 iris_grpc_proto::pb::private::v1::nock_app_service_client::NockAppServiceClient::new(
194 client,
195 );
196
197 let payload_jam = iris_ztd::jam(payload);
198 let request = iris_grpc_proto::pb::private::v1::PokeRequest {
199 pid,
200 wire: Some(wire),
201 payload: payload_jam,
202 };
203
204 let response = grpc_client
205 .poke(request)
206 .await
207 .map_err(|e| JsValue::from_str(&format!("gRPC error: {}", e)))?
208 .into_inner();
209
210 match response.result {
211 Some(iris_grpc_proto::pb::private::v1::poke_response::Result::Acknowledged(true)) => {
212 Ok(())
213 }
214 Some(iris_grpc_proto::pb::private::v1::poke_response::Result::Acknowledged(false)) => {
215 Err(JsValue::from_str("Poke not acknowledged"))
216 }
217 Some(iris_grpc_proto::pb::private::v1::poke_response::Result::Error(err)) => {
218 Err(JsValue::from_str(&format!("Server error: {}", err.message)))
219 }
220 None => Err(JsValue::from_str("Empty response from server")),
221 }
222 }
223}