use serde::Deserialize;
use serde_json::json;
use serde_with::serde_as;
use crate::rebased::RpcClient;
use crate::rebased::client::{RawRpcResponse, RpcResult};
use super::super::bigint::BigInt;
use super::super::serde::SequenceNumber as AsSequenceNumber;
use super::super::types::{IotaAddress, ObjectDigest, SequenceNumber, TransactionDigest};
use super::super::{ObjectID, ObjectRef};
pub trait CoinReadApi {
async fn get_coins(
&self,
owner: IotaAddress,
coin_type: Option<String>,
cursor: Option<ObjectID>,
limit: Option<usize>,
) -> RpcResult<CoinPage>;
async fn get_balance(
&self,
owner: IotaAddress,
coin_type: Option<String>,
) -> RpcResult<Balance>;
}
impl CoinReadApi for RpcClient {
async fn get_coins(
&self,
owner: IotaAddress,
coin_type: Option<String>,
cursor: Option<ObjectID>,
limit: Option<usize>,
) -> RpcResult<CoinPage> {
let request_body = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "iotax_getCoins",
"params": [
json!(owner.to_string()),
json!(coin_type.unwrap_or_else(|| "0x2::iota::IOTA".to_string())),
json!(cursor),
json!(limit)
]
});
let response = self.client.post(self.url.clone()).json(&request_body).send().await?;
let body: RawRpcResponse<CoinPage> = response.json().await?;
body.into_result()
}
async fn get_balance(
&self,
owner: IotaAddress,
coin_type: Option<String>,
) -> RpcResult<Balance> {
let request_body = json!({
"jsonrpc": "2.0",
"id": 1,
"method": "iotax_getBalance",
"params": [
owner.to_string(),
coin_type.unwrap_or_else(|| "0x2::iota::IOTA".to_string())
]
});
let response = self.client.post(self.url.clone()).json(&request_body).send().await?;
let body: RawRpcResponse<Balance> = response.json().await?;
body.into_result()
}
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Page<T, C> {
pub data: Vec<T>,
pub next_cursor: Option<C>,
pub has_next_page: bool,
}
pub type CoinPage = Page<Coin, ObjectID>;
#[serde_as]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Coin {
pub coin_type: String,
pub coin_object_id: ObjectID,
#[serde_as(as = "AsSequenceNumber")]
pub version: SequenceNumber,
pub digest: ObjectDigest,
#[serde_as(as = "BigInt<u64>")]
pub balance: u64,
pub previous_transaction: TransactionDigest,
}
impl Coin {
pub fn obj_ref(&self) -> ObjectRef {
(self.coin_object_id, self.version, self.digest)
}
}
#[serde_as]
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Balance {
pub coin_type: String,
pub coin_object_count: usize,
#[serde_as(as = "BigInt<u128>")]
pub total_balance: u128,
}