Skip to content

Commit

Permalink
implement spot api
Browse files Browse the repository at this point in the history
  • Loading branch information
dennohpeter committed May 8, 2024
1 parent b81642c commit 9b91d0d
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 6 deletions.
7 changes: 7 additions & 0 deletions examples/info/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod perps;
mod spot;

fn main() {
perps::main();
spot::main();
}
4 changes: 2 additions & 2 deletions examples/info.rs → examples/info/perps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use uuid::Uuid;
const SEP: &str = "\n---";

#[tokio::main]
async fn main() {
pub async fn main() {
// Key was randomly generated for testing and shouldn't be used with any real funds
let wallet: Arc<LocalWallet> = Arc::new(
"e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
Expand All @@ -37,7 +37,7 @@ async fn main() {

let now = now.as_millis() as u64;

println!("Info API Examples");
println!("Info Perps API Examples");

metadata(&info).await;
mids(&info).await;
Expand Down
47 changes: 47 additions & 0 deletions examples/info/spot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::sync::Arc;

use ethers::{
signers::{LocalWallet, Signer},
types::Address,
};
use hyperliquid::{types::Chain, Hyperliquid, Info};

const SEP: &str = "\n---";

#[tokio::main]
pub async fn main() {
// Key was randomly generated for testing and shouldn't be used with any real funds
let wallet: Arc<LocalWallet> = Arc::new(
"e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
.parse()
.unwrap(),
);

let user = wallet.address();

let info = Hyperliquid::new(Chain::Dev);

println!("Info Spot API Examples");

spot_meta(&info).await;
spot_meta_and_asset_ctxs(&info).await;
spot_clearinghouse_state(&info, user).await;
}

async fn spot_meta(info: &Info) {
let spot_meta = info.spot_meta().await.unwrap();
println!("{SEP}\nSpot Metadata \n{:?}{SEP}", spot_meta);
}

async fn spot_meta_and_asset_ctxs(info: &Info) {
let spot_asset_ctxs = info.spot_meta_and_asset_ctxs().await.unwrap();
println!(
"Spot Asset Contexts \n{:?}{SEP}",
serde_json::to_string(&spot_asset_ctxs)
);
}

async fn spot_clearinghouse_state(info: &Info, user: Address) {
let states = info.spot_clearinghouse_state(user).await.unwrap();
println!("User spot state for {user} \n{:?}{SEP}", states);
}
28 changes: 26 additions & 2 deletions src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::{
request::{CandleSnapshotRequest, Request},
response::{
AssetContext, CandleSnapshot, FrontendOpenOrders, FundingHistory, L2Book,
OpenOrder, OrderStatus, RecentTrades, SubAccount, Universe, UserFill, UserFunding,
UserState,
OpenOrder, OrderStatus, RecentTrades, SpotMeta, SpotMetaAndAssetCtxs, SubAccount,
Universe, UserFill, UserFunding, UserSpotState, UserState,
},
},
Chain, Oid, API,
Expand Down Expand Up @@ -238,3 +238,27 @@ impl Info {
.await
}
}

impl Info {
/// Retrieve spot metadata
pub async fn spot_meta(&self) -> Result<SpotMeta> {
self.client.post(&API::Info, &Request::SpotMeta).await
}

/// Retrieve spot asset contexts
pub async fn spot_meta_and_asset_ctxs(&self) -> Result<Vec<SpotMetaAndAssetCtxs>> {
self.client
.post(&API::Info, &Request::SpotMetaAndAssetCtxs)
.await
}

/// Retrieve a user's token balances
///
/// # Arguments
/// * `user` - The user's address in 42-character hexadecimal format; e.g. `0x0000000000000000000000000000000000000000`
pub async fn spot_clearinghouse_state(&self, user: Address) -> Result<UserSpotState> {
self.client
.post(&API::Info, &Request::SpotClearinghouseState { user })
.await
}
}
70 changes: 68 additions & 2 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ pub mod info {
SubAccounts {
user: Address,
},

SpotMeta,

SpotMetaAndAssetCtxs,

SpotClearinghouseState {
user: Address,
},
}
}

Expand All @@ -257,8 +265,8 @@ pub mod info {
#[serde(rename_all = "camelCase")]
pub struct Asset {
pub name: String,
pub sz_decimals: u32,
pub max_leverage: u32,
pub sz_decimals: u64,
pub max_leverage: u64,
pub only_isolated: bool,
}

Expand Down Expand Up @@ -516,6 +524,64 @@ pub mod info {
pub name: String,
pub sub_account_user: Address,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SpotAsset {
pub index: u64,
pub is_canonical: bool,
pub name: String,
pub sz_decimals: u64,
pub token_id: String,
pub wei_decimals: u64,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SpotUniverse {
pub index: u64,
pub is_canonical: bool,
pub name: String,
pub tokens: Vec<u64>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SpotMeta {
pub tokens: Vec<SpotAsset>,
pub universe: Vec<SpotUniverse>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SpotCtx {
pub circulating_supply: String,
pub coin: String,
pub day_ntl_vlm: String,
pub mark_px: String,
pub mid_px: Option<String>,
pub prev_day_px: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum SpotMetaAndAssetCtxs {
Meta(SpotMeta),
Ctx(Vec<SpotCtx>),
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Balance {
pub coin: String,
pub hold: String,
pub total: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UserSpotState {
pub balances: Vec<Balance>,
}
}
}

Expand Down

0 comments on commit 9b91d0d

Please sign in to comment.