Skip to content

Commit

Permalink
adding staking chain info (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
dougEfresh committed May 2, 2024
1 parent 8abc420 commit 1642450
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "fireblocks-sdk"
resolver = "2"
version = "0.2.2"
version = "0.3.0"
authors = ["Doug Chimento <dchimento@gmail.com>"]
description = "Rust implementation of the Fireblocks SDK"
readme = "README.md"
Expand Down
12 changes: 8 additions & 4 deletions src/api/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::api::{WalletCreate, WalletCreateAsset};
use crate::types::{WalletContainer, WalletCreateAssetResponse};
use crate::Client;
use crate::Result;
use std::fmt::{Debug, Display};

impl Client {
#[tracing::instrument(level = "debug", skip(self))]
Expand All @@ -12,13 +13,16 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn contract(&self, id: &str) -> Result<WalletContainer> {
let u = self.build_url(&format!("contracts/{id}"))?.0;
let u = self.build_url(format!("contracts/{id}"))?.0;
self.get(u).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn contract_asset(&self, id: &str, asset: &str, address: &str) -> Result<WalletCreateAssetResponse> {
let u = self.build_url(&format!("contracts/{id}/{asset}"))?.0;
pub async fn contract_asset<T>(&self, id: &str, asset: T, address: &str) -> Result<WalletCreateAssetResponse>
where
T: AsRef<str> + Display + Debug,
{
let u = self.build_url(format!("contracts/{id}/{asset}"))?.0;
let w = WalletCreateAsset { address: String::from(address), tag: "fireblocks-sdk-rs".to_string() };
self.post(u, Some(&w)).await
}
Expand All @@ -32,7 +36,7 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn contract_delete(&self, id: &str) -> Result<()> {
let u = self.build_url(&format!("contracts/{id}"))?.0;
let u = self.build_url(format!("contracts/{id}"))?.0;
self.delete(u).await
}
}
12 changes: 8 additions & 4 deletions src/api/external_wallets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::api::{WalletCreate, WalletCreateAsset};
use crate::types::{WalletContainer, WalletCreateAssetResponse};
use crate::Client;
use crate::Result;
use std::fmt::{Debug, Display};

impl Client {
#[tracing::instrument(level = "debug", skip(self))]
Expand All @@ -12,13 +13,16 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn external_wallet(&self, id: &str) -> Result<WalletContainer> {
let u = self.build_url(&format!("external_wallets/{id}"))?.0;
let u = self.build_url(format!("external_wallets/{id}"))?.0;
self.get(u).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn external_wallet_asset(&self, id: &str, asset: &str, address: &str) -> Result<WalletCreateAssetResponse> {
let u = self.build_url(&format!("external_wallets/{id}/{asset}"))?.0;
pub async fn external_wallet_asset<T>(&self, id: &str, asset: T, address: &str) -> Result<WalletCreateAssetResponse>
where
T: AsRef<str> + Display + Debug,
{
let u = self.build_url(format!("external_wallets/{id}/{asset}"))?.0;
let w = WalletCreateAsset { address: String::from(address), tag: "fireblocks-sdk-rs".to_string() };
self.post(u, Some(&w)).await
}
Expand All @@ -32,7 +36,7 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn external_wallet_delete(&self, id: &str) -> Result<()> {
let u = self.build_url(&format!("external_wallets/{id}"))?.0;
let u = self.build_url(format!("external_wallets/{id}"))?.0;
self.delete(u).await
}
}
22 changes: 19 additions & 3 deletions src/api/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use crate::client::Client;
use crate::{
types::{
asset::SupportedAsset,
staking::{StakingPosition, StakingPositionsSummary},
staking::{StakingChainInfo, StakingPosition, StakingPositionsSummary},
},
Result,
Asset, Result,
};
use std::fmt::{Debug, Display};

impl Client {
#[tracing::instrument(level = "debug", skip(self))]
Expand All @@ -15,11 +16,26 @@ impl Client {
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn staking_chains(&self) -> Result<Vec<String>> {
pub async fn staking_chains(&self) -> Result<Vec<Asset>> {
let u = self.build_url("staking/chains")?.0;
self.get(u).await
}

/// Get info about your stake
///
/// See
///
/// * [`StakingChainInfo`]
/// * [getChainInfo](https://docs.fireblocks.com/api/swagger-ui/#/Staking%20(Beta)/getChainInfo)
#[tracing::instrument(level = "debug", skip(self))]
pub async fn staking_chain_info<T>(&self, chain: T) -> Result<StakingChainInfo>
where
T: AsRef<str> + Display + Debug,
{
let u = self.build_url(format!("staking/chains/{chain}/chainInfo"))?.0;
self.get(u).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn staking_positions(&self) -> Result<Vec<StakingPosition>> {
let u = self.build_url("staking/positions")?.0;
Expand Down
6 changes: 3 additions & 3 deletions src/api/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Client {
/// [getTransaction](https://docs.fireblocks.com/api/swagger-ui/#/Transactions/getTransaction)
#[tracing::instrument(level = "debug", skip(self))]
pub async fn get_transaction(&self, id: &str) -> crate::Result<Transaction> {
let u = self.build_url(&format!("transactions/{id}"))?.0;
let u = self.build_url(format!("transactions/{id}"))?.0;
self.get(u).await
}

Expand All @@ -130,7 +130,7 @@ impl Client {
interval: time::Duration,
callback: impl Fn(&Transaction) + Send + Sync,
) -> crate::Result<Transaction> {
let u = self.build_url(&format!("transactions/{id}"))?.0;
let u = self.build_url(format!("transactions/{id}"))?.0;
let mut total_time = time::Duration::from_millis(0);
loop {
if let Ok(result) = self.get::<Transaction>(u.clone()).await {
Expand Down Expand Up @@ -162,7 +162,7 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn estimate_fee(&self, asset: &str) -> crate::Result<EstimateFee> {
let u = self.build_url(&format!("estimate_network_fee?assetId={asset}"))?.0;
let u = self.build_url(format!("estimate_network_fee?assetId={asset}"))?.0;
self.get(u).await
}
}
14 changes: 7 additions & 7 deletions src/api/vaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl Client {
T: AsRef<str> + Display + Debug,
{
let p = format!("vault/accounts/{vault_id}/{asset_id}");
let u = self.build_url(&p)?.0;
let u = self.build_url(p)?.0;
self.post(u, None as Option<&()>).await
}

Expand All @@ -44,7 +44,7 @@ impl Client {
T: AsRef<str> + Display + Debug,
{
let p = format!("vault/accounts/{vault_id}/{asset_id}/addresses");
let u = self.build_url(&p)?.0;
let u = self.build_url(p)?.0;
self.get(u).await
}

Expand All @@ -58,14 +58,14 @@ impl Client {
V: AsRef<str>,
{
let p = format!("vault/accounts/{vault_id}/{asset_id}/addresses_paginated");
let u = self.build_url_params(&p, Some(paging))?.0;
let u = self.build_url_params(p, Some(paging))?.0;
self.get(u).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn vault(&self, vault_id: i32) -> Result<Account> {
let p = format!("vault/accounts/{vault_id}");
let u = self.build_url(&p)?.0;
let u = self.build_url(p)?.0;
self.get(u).await
}

Expand Down Expand Up @@ -110,17 +110,17 @@ impl Client {
struct Rename {
name: String,
}
let u = self.build_url(&format!("vault/accounts/{vault_id}"))?.0;
let u = self.build_url(format!("vault/accounts/{vault_id}"))?.0;
let name_req = &Rename { name: String::from(name) };
self.put(u, Some(name_req)).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn vault_hide(&self, vault_id: i32, hide: bool) -> Result<()> {
let u = if hide {
self.build_url(&format!("vault/accounts/{vault_id}/hide"))?.0
self.build_url(format!("vault/accounts/{vault_id}/hide"))?.0
} else {
self.build_url(&format!("vault/accounts/{vault_id}/unhide"))?.0
self.build_url(format!("vault/accounts/{vault_id}/unhide"))?.0
};
let (_, id) = self.post::<Success, ()>(u, None).await?;
Ok(((), id))
Expand Down
4 changes: 2 additions & 2 deletions src/api/wallet_connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ impl Client {

#[tracing::instrument(level = "debug", skip(self))]
pub async fn wallet_connection_delete(&self, id: &str) -> crate::Result<()> {
let u = self.build_url(&format!("connections/wc/{id}"))?.0;
let u = self.build_url(format!("connections/wc/{id}"))?.0;
self.delete(u).await
}

#[tracing::instrument(level = "debug", skip(self))]
pub async fn wallet_connection_approve(&self, id: &str, approve: bool) -> crate::Result<()> {
let u = self.build_url(&format!("connections/wc/{id}"))?.0;
let u = self.build_url(format!("connections/wc/{id}"))?.0;
self.put(u, Some(&WalletApprove { approve })).await
}
}
8 changes: 4 additions & 4 deletions src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl AsRef<str> for Asset {
Self::SOL(Network::Main) => "SOL",
Self::SOL(Network::Test) => "SOL_TEST",
Self::ETH(EthNetwork::Main) => "ETH",
Self::ETH(EthNetwork::Test) => "ETH_TEST5",
Self::ETH(EthNetwork::Test) => "ETH_TEST6",
Self::Unknown(ref s) => s,
}
}
Expand Down Expand Up @@ -137,7 +137,7 @@ impl FromStr for Asset {
"DOGE" => Ok(ASSET_DOGE),
"DOGE_TEST" => Ok(ASSET_DOGE_TEST),
"ETH" => Ok(ASSET_ETH),
"ETH_TEST5" => Ok(ASSET_ETH_TEST),
"ETH_TEST6" => Ok(ASSET_ETH_TEST),
_ => Ok(Self::Unknown(String::from(s))),
}
}
Expand Down Expand Up @@ -172,7 +172,7 @@ mod tests {
let a = Asset::from_str("ETH")?;
assert_eq!(a, ASSET_ETH);

let a = Asset::from_str("ETH_TEST5")?;
let a = Asset::from_str("ETH_TEST6")?;
assert_eq!(a, ASSET_ETH_TEST);

let a = Asset::from_str("UNKNOWN")?;
Expand All @@ -186,7 +186,7 @@ mod tests {
assert_eq!("DOGE", ASSET_DOGE.as_ref());
assert_eq!("DOGE_TEST", ASSET_DOGE_TEST.as_ref());
assert_eq!("ETH", ASSET_ETH.as_ref());
assert_eq!("ETH_TEST5", ASSET_ETH_TEST.as_ref());
assert_eq!("ETH_TEST6", ASSET_ETH_TEST.as_ref());

assert_eq!(Asset::Unknown("blah".to_owned()).to_string(), "blah");
assert_eq!(ASSET_BTC.to_string(), "BTC");
Expand Down
10 changes: 7 additions & 3 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use reqwest::{Method, RequestBuilder, StatusCode};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::borrow::Borrow;
use std::fmt::Debug;
use std::fmt::{Debug, Display};
use std::sync::Arc;
use std::time::Duration;
use tracing::debug;
Expand Down Expand Up @@ -187,11 +187,15 @@ impl Client {
r
}

pub(crate) fn build_url(&self, path: &str) -> crate::Result<Url> {
pub(crate) fn build_url(&self, path: impl AsRef<str> + Display) -> crate::Result<Url> {
self.build_url_params::<Vec<(&str, &str)>, &str, &str>(path, None)
}

pub(crate) fn build_url_params<I, K, V>(&self, path: &str, params: Option<I>) -> crate::Result<Url>
pub(crate) fn build_url_params<I, K, V>(
&self,
path: impl AsRef<str> + Display,
params: Option<I>,
) -> crate::Result<Url>
where
I: IntoIterator,
I::Item: Borrow<(K, V)>,
Expand Down
10 changes: 7 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ mod tests {
use crate::assets::{ASSET_BTC_TEST, ASSET_SOL_TEST};
use crate::paged_client::{PagedClient, TransactionStream};
use crate::types::*;
use crate::{Client, ClientBuilder, ASSET_ETH_TEST};
use crate::{Client, ClientBuilder, ASSET_ETH, ASSET_ETH_TEST, ASSET_SOL};
use bigdecimal::BigDecimal;
use chrono::{TimeZone, Utc};
use color_eyre::eyre::format_err;
Expand Down Expand Up @@ -322,7 +322,7 @@ mod tests {

let (addr_response, _) = config
.client()
.contract_asset(&contract_response.id, "ETH_TEST5", "0x9bb4d44e6963260a1850926e8f6beb8d5803836f")
.contract_asset(&contract_response.id, ASSET_ETH_TEST, "0x9bb4d44e6963260a1850926e8f6beb8d5803836f")
.await?;
assert_eq!(addr_response.id, ASSET_ETH_TEST);

Expand All @@ -345,7 +345,7 @@ mod tests {
assert!(!contract_response.id.is_empty());

let addr_response = c
.external_wallet_asset(&contract_response.id, "ETH_TEST5", "0x9bb4d44e6963260a1850926e8f6beb8d5803836f")
.external_wallet_asset(&contract_response.id, ASSET_ETH_TEST, "0x9bb4d44e6963260a1850926e8f6beb8d5803836f")
.await?
.0;
assert_eq!(addr_response.id, ASSET_ETH_TEST);
Expand Down Expand Up @@ -438,6 +438,10 @@ mod tests {
assert!(!chains.is_empty());
c.staking_positions().await?;
c.staking_positions_summary().await?;

for chain in [ASSET_SOL, ASSET_SOL_TEST, ASSET_ETH, ASSET_ETH_TEST] {
c.staking_chain_info(&chain).await?;
}
Ok(())
}

Expand Down
32 changes: 27 additions & 5 deletions src/types/staking.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::types::deserialize_str_u64;
use crate::Asset;
use bigdecimal::BigDecimal;
use chrono::{DateTime, Utc};
use serde::Deserialize;

use crate::types::deserialize_str_u64;

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct StakingPosition {
/// The unique identifier of the staking position
pub id: String,
Expand Down Expand Up @@ -64,7 +63,6 @@ pub struct StakingPosition {

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct StakingAmountSummary {
#[serde(rename = "chainDescriptor")]
pub chain: String,
Expand All @@ -73,8 +71,32 @@ pub struct StakingAmountSummary {

#[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
pub struct StakingPositionsSummary {
pub active: Vec<StakingAmountSummary>,
pub inactive: Vec<StakingAmountSummary>,
}

#[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct StakingAmounts {
pub active: Vec<StakingAmountSummary>,
pub inactive: Vec<StakingAmountSummary>,
}

#[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct StakingAdditionalInfo {
estimated_annual_reward: BigDecimal,
lockup_period: u64,
activation_period: u64,
}

#[derive(Debug, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct StakingChainInfo {
chain_descriptor: Asset,
current_epoch: u64,
epoch_elapsed: f64,
epoch_duration: u64,
additional_info: StakingAdditionalInfo,
}

0 comments on commit 1642450

Please sign in to comment.