use send_wrapper::SendWrapper;
use tendermint_proto::google::protobuf::Any;
use wasm_bindgen::prelude::*;
use celestia_types::any::{IntoProtobufAny, JsAny};
use celestia_types::blob::BlobParams;
use celestia_types::block::Block;
use celestia_types::consts::appconsts::JsAppVersion;
use celestia_types::state::auth::{JsAuthParams, JsBaseAccount};
use celestia_types::state::{AbciQueryResponse, JsCoin, TxResponse};
use celestia_types::{Blob, ExtendedHeader};
use crate::grpc::{
ConfigResponse, GasInfo, GetTxResponse, JsBroadcastMode, TxPriority, TxStatusResponse,
};
use crate::js_client::GrpcClientBuilder;
use crate::tx::{JsTxConfig, JsTxInfo};
use crate::Result;
#[wasm_bindgen]
pub struct GrpcClient {
client: crate::GrpcClient,
}
#[wasm_bindgen]
impl GrpcClient {
#[wasm_bindgen(js_name = withUrl)]
pub fn with_url(url: String) -> GrpcClientBuilder {
crate::GrpcClientBuilder::new().url(url).into()
}
#[wasm_bindgen(js_name = getAuthParams)]
pub async fn get_auth_params(&self) -> Result<JsAuthParams> {
Ok(self.client.get_auth_params().await?.into())
}
#[wasm_bindgen(js_name = getAccount)]
pub async fn get_account(&self, account: &str) -> Result<JsBaseAccount> {
Ok(self.client.get_account(&account.parse()?).await?.into())
}
#[wasm_bindgen(js_name = getAccounts)]
pub async fn get_accounts(&self) -> Result<Vec<JsBaseAccount>> {
Ok(self
.client
.get_accounts()
.await?
.into_iter()
.map(Into::into)
.collect())
}
#[wasm_bindgen(js_name = getVerifiedBalance)]
pub async fn get_verified_balance(
&self,
address: &str,
header: &ExtendedHeader,
) -> Result<JsCoin> {
Ok(self
.client
.get_verified_balance(&address.parse()?, header)
.await?
.into())
}
#[wasm_bindgen(js_name = getBalance)]
pub async fn get_balance(&self, address: &str, denom: &str) -> Result<JsCoin> {
Ok(self
.client
.get_balance(&address.parse()?, denom)
.await?
.into())
}
#[wasm_bindgen(js_name = getAllBalances)]
pub async fn get_all_balances(&self, address: &str) -> Result<Vec<JsCoin>> {
Ok(self
.client
.get_all_balances(&address.parse()?)
.await?
.into_iter()
.map(Into::into)
.collect())
}
#[wasm_bindgen(js_name = getSpendableBalances)]
pub async fn get_spendable_balances(&self, address: &str) -> Result<Vec<JsCoin>> {
Ok(self
.client
.get_spendable_balances(&address.parse()?)
.await?
.into_iter()
.map(Into::into)
.collect())
}
#[wasm_bindgen(js_name = getTotalSupply)]
pub async fn get_total_supply(&self) -> Result<Vec<JsCoin>> {
Ok(self
.client
.get_total_supply()
.await?
.into_iter()
.map(Into::into)
.collect())
}
pub async fn get_node_config(&self) -> Result<ConfigResponse> {
self.client.get_node_config().await
}
#[wasm_bindgen(js_name = getLatestBlock)]
pub async fn get_latest_block(&self) -> Result<Block> {
self.client.get_latest_block().await
}
#[wasm_bindgen(js_name = getBlockByHeight)]
pub async fn get_block_by_height(&self, height: i64) -> Result<Block> {
self.client.get_block_by_height(height).await
}
#[wasm_bindgen(js_name = abciQuery)]
pub async fn abci_query(
&self,
data: Vec<u8>,
path: &str,
height: u64,
prove: bool,
) -> Result<AbciQueryResponse> {
self.client.abci_query(data, path, height, prove).await
}
#[wasm_bindgen(js_name = broadcastTx)]
pub async fn broadcast_tx(
&self,
tx_bytes: Vec<u8>,
mode: &JsBroadcastMode,
) -> Result<TxResponse> {
self.client.broadcast_tx(tx_bytes, (*mode).into()).await
}
#[wasm_bindgen(js_name = getTx)]
pub async fn get_tx(&self, hash: &str) -> Result<GetTxResponse> {
self.client.get_tx(hash.parse()?).await
}
pub async fn simulate(&self, tx_bytes: Vec<u8>) -> Result<GasInfo> {
self.client.simulate(tx_bytes).await
}
#[wasm_bindgen(js_name = getBlobParams)]
pub async fn get_blob_params(&self) -> Result<BlobParams> {
self.client.get_blob_params().await
}
#[wasm_bindgen(js_name = txStatus)]
pub async fn tx_status(&self, hash: &str) -> Result<TxStatusResponse> {
self.client.tx_status(hash.parse()?).await
}
#[wasm_bindgen(js_name = estimateGasPrice)]
pub async fn estimate_gas_price(&self, priority: TxPriority) -> Result<f64> {
self.client.estimate_gas_price(priority).await
}
#[wasm_bindgen(js_name = chainId, getter)]
pub async fn chain_id(&self) -> Result<String> {
Ok(self.client.chain_id().await?.to_string())
}
#[wasm_bindgen(js_name = appVersion, getter)]
pub async fn app_version(&self) -> Result<JsAppVersion> {
Ok(self.client.app_version().await?.into())
}
#[wasm_bindgen(js_name = submitBlobs)]
pub async fn submit_blobs(
&self,
blobs: Vec<Blob>,
tx_config: Option<JsTxConfig>,
) -> Result<JsTxInfo> {
let tx_config = tx_config.map(Into::into).unwrap_or_default();
let tx = self.client.submit_blobs(&blobs, tx_config).await?;
Ok(tx.into())
}
#[wasm_bindgen(js_name = submitMessage)]
pub async fn submit_message(
&self,
message: JsAny,
tx_config: Option<JsTxConfig>,
) -> Result<JsTxInfo> {
let tx_config = tx_config.map(Into::into).unwrap_or_default();
let tx = self
.client
.submit_message(SendJsAny::from(message), tx_config)
.await?;
Ok(tx.into())
}
}
impl From<crate::GrpcClient> for GrpcClient {
fn from(client: crate::GrpcClient) -> Self {
GrpcClient { client }
}
}
struct SendJsAny(SendWrapper<JsAny>);
impl From<JsAny> for SendJsAny {
fn from(value: JsAny) -> Self {
SendJsAny(SendWrapper::new(value))
}
}
impl IntoProtobufAny for SendJsAny {
fn into_any(self) -> Any {
self.0.take().into_any()
}
}