From 04e757a7beb3de481219d8d2334347e2490d9da5 Mon Sep 17 00:00:00 2001 From: findolor Date: Thu, 28 Nov 2024 15:18:19 +0300 Subject: [PATCH] add additional order bindings --- crates/js_api/src/subgraph/order.rs | 50 +++++ crates/subgraph/src/types/common.rs | 10 +- crates/subgraph/src/vol.rs | 26 ++- packages/orderbook/test/js_api/order.test.ts | 208 ++++++++++++++++++- 4 files changed, 279 insertions(+), 15 deletions(-) diff --git a/crates/js_api/src/subgraph/order.rs b/crates/js_api/src/subgraph/order.rs index ecd50b9ff..56affda09 100644 --- a/crates/js_api/src/subgraph/order.rs +++ b/crates/js_api/src/subgraph/order.rs @@ -27,3 +27,53 @@ pub async fn get_order(url: &str, id: &str) -> Result, + end_timestamp: Option, +) -> Result { + let client = OrderbookSubgraphClient::new(Url::parse(url)?); + let volumes = client + .order_vaults_volume(Id::new(order_id), start_timestamp, end_timestamp) + .await?; + Ok(to_value(&volumes)?) +} + +/// Get the list of trades for an order +/// Returns a list of Trade structs +#[wasm_bindgen(js_name = "getOrderTradesList")] +pub async fn get_order_trades_list( + url: &str, + order_id: &str, + pagination_args: PaginationArgs, + start_timestamp: Option, + end_timestamp: Option, +) -> Result { + let client = OrderbookSubgraphClient::new(Url::parse(url)?); + let trades = client + .order_trades_list( + Id::new(order_id), + pagination_args, + start_timestamp, + end_timestamp, + ) + .await?; + Ok(to_value(&trades)?) +} + +/// Get details for a specific trade +/// Returns a Trade struct +#[wasm_bindgen(js_name = "getOrderTradeDetail")] +pub async fn get_order_trade_detail( + url: &str, + trade_id: &str, +) -> Result { + let client = OrderbookSubgraphClient::new(Url::parse(url)?); + let trade = client.order_trade_detail(Id::new(trade_id)).await?; + Ok(to_value(&trade)?) +} diff --git a/crates/subgraph/src/types/common.rs b/crates/subgraph/src/types/common.rs index cd09b1aa5..b3c55eca2 100644 --- a/crates/subgraph/src/types/common.rs +++ b/crates/subgraph/src/types/common.rs @@ -315,17 +315,21 @@ pub struct TradeEvent { } #[derive(cynic::QueryFragment, Debug, Clone, Serialize)] +#[cfg_attr(target_family = "wasm", derive(Tsify))] #[typeshare] #[serde(rename_all = "camelCase")] pub struct Trade { pub id: Bytes, - pub trade_event: TradeEvent, - pub output_vault_balance_change: TradeVaultBalanceChange, pub order: TradeStructPartialOrder, - pub input_vault_balance_change: TradeVaultBalanceChange, + pub trade_event: TradeEvent, + #[cfg_attr(target_family = "wasm", tsify(type = "SgBigInt"))] pub timestamp: BigInt, pub orderbook: Orderbook, + pub output_vault_balance_change: TradeVaultBalanceChange, + pub input_vault_balance_change: TradeVaultBalanceChange, } +#[cfg(target_family = "wasm")] +impl_all_wasm_traits!(Trade); #[derive(cynic::QueryFragment, Debug, Clone, Serialize)] #[cfg_attr(target_family = "wasm", derive(Tsify))] diff --git a/crates/subgraph/src/vol.rs b/crates/subgraph/src/vol.rs index a88798249..20bf9c1b7 100644 --- a/crates/subgraph/src/vol.rs +++ b/crates/subgraph/src/vol.rs @@ -4,21 +4,27 @@ use serde::{Deserialize, Serialize}; use std::str::FromStr; use typeshare::typeshare; +#[cfg(target_family = "wasm")] +use rain_orderbook_bindings::{impl_all_wasm_traits, wasm_traits::prelude::*}; + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(target_family = "wasm", derive(Tsify))] #[serde(rename_all = "camelCase")] #[typeshare] pub struct VaultVolume { - id: String, - token: Erc20, - #[typeshare(typescript(type = "string"))] - total_in: U256, - #[typeshare(typescript(type = "string"))] - total_out: U256, - #[typeshare(typescript(type = "string"))] - total_vol: U256, - #[typeshare(typescript(type = "string"))] - net_vol: I256, + pub id: String, + pub token: Erc20, + #[cfg_attr(target_family = "wasm", tsify(type = "string"))] + pub total_in: U256, + #[cfg_attr(target_family = "wasm", tsify(type = "string"))] + pub total_out: U256, + #[cfg_attr(target_family = "wasm", tsify(type = "string"))] + pub total_vol: U256, + #[cfg_attr(target_family = "wasm", tsify(type = "string"))] + pub net_vol: I256, } +#[cfg(target_family = "wasm")] +impl_all_wasm_traits!(VaultVolume); /// Get the vaults volume from array of trades pub fn get_vaults_vol(trades: &[Trade]) -> Result, ParseError> { diff --git a/packages/orderbook/test/js_api/order.test.ts b/packages/orderbook/test/js_api/order.test.ts index 094a6d93c..7244f0086 100644 --- a/packages/orderbook/test/js_api/order.test.ts +++ b/packages/orderbook/test/js_api/order.test.ts @@ -1,8 +1,19 @@ import assert from "assert"; import { getLocal } from "mockttp"; import { describe, it, beforeEach, afterEach } from "vitest"; -import { Order, OrderWithSubgraphName } from "../../dist/types/js_api.js"; -import { getOrders, getOrder } from "../../dist/cjs/js_api.js"; +import { + Order, + OrderWithSubgraphName, + Trade, + VaultVolume, +} from "../../dist/types/js_api.js"; +import { + getOrders, + getOrder, + getOrderVaultsVolume, + getOrderTradesList, + getOrderTradeDetail, +} from "../../dist/cjs/js_api.js"; const order1 = { id: "order1", @@ -137,6 +148,114 @@ const order2 = { trades: [], }; +const mockTrade = { + id: "trade1", + order: { + id: "order1", + orderHash: "0x1", + }, + tradeEvent: { + sender: "0x0000000000000000000000000000000000000000", + transaction: { + id: "0x0000000000000000000000000000000000000000", + from: "0x0000000000000000000000000000000000000000", + blockNumber: "0", + timestamp: "0", + }, + }, + timestamp: "0", + orderbook: { + id: "0x0000000000000000000000000000000000000000", + }, + outputVaultBalanceChange: { + id: "0x0000000000000000000000000000000000000000", + __typename: "TradeVaultBalanceChange", + amount: "-7", + newVaultBalance: "93", + oldVaultBalance: "100", + vault: { + id: "0x0000000000000000000000000000000000000000", + vaultId: "1", + token: { + id: "0x0000000000000000000000000000000000000000", + address: "0x0000000000000000000000000000000000000000", + name: "T1", + symbol: "T1", + decimals: "18", + }, + }, + timestamp: "0", + transaction: { + id: "0x0000000000000000000000000000000000000000", + from: "0x0000000000000000000000000000000000000000", + blockNumber: "0", + timestamp: "0", + }, + orderbook: { + id: "0x0000000000000000000000000000000000000000", + }, + }, + inputVaultBalanceChange: { + id: "0x0000000000000000000000000000000000000000", + __typename: "TradeVaultBalanceChange", + amount: "5", + newVaultBalance: "105", + oldVaultBalance: "100", + vault: { + id: "0x0000000000000000000000000000000000000000", + vaultId: "2", + token: { + id: "0x0000000000000000000000000000000000000000", + address: "0x0000000000000000000000000000000000000000", + name: "T2", + symbol: "T2", + decimals: "6", + }, + }, + timestamp: "0", + transaction: { + id: "0x0000000000000000000000000000000000000000", + from: "0x0000000000000000000000000000000000000000", + blockNumber: "0", + timestamp: "0", + }, + orderbook: { + id: "0x0000000000000000000000000000000000000000", + }, + }, +}; + +const mockVaultVolume = [ + { + id: "1", + token: { + id: "0x0000000000000000000000000000000000000000", + address: "0x0000000000000000000000000000000000000000", + name: "T1", + symbol: "T1", + decimals: "18", + }, + totalIn: "10", + totalOut: "7", + totalVol: "17", + netVol: "3", + }, + { + id: "2", + token: { + id: "0x0000000000000000000000000000000000000000", + address: "0x0000000000000000000000000000000000000000", + name: "T2", + symbol: "T2", + decimals: "6", + }, + totalIn: "5", + totalOut: "2", + totalVol: "7", + netVol: "3", + }, +]; + describe("Rain Orderbook JS API Package Bindgen Tests - Order", async function () { const mockServer = getLocal(); beforeEach(() => mockServer.start(8082)); @@ -190,4 +309,89 @@ describe("Rain Orderbook JS API Package Bindgen Tests - Order", async function ( assert.fail("expected to resolve, but failed"); } }); + + it("should fetch order vaults volume", async () => { + await mockServer.forPost("/sg1").thenReply( + 200, + JSON.stringify({ + data: { trades: [mockTrade], vaultVolumes: mockVaultVolume }, + }) + ); + + try { + const result: VaultVolume[] = await getOrderVaultsVolume( + mockServer.url + "/sg1", + "order1", + undefined, + undefined + ); + assert.equal(result.length, 2); + assert.equal(result[0].id, "1"); + assert.equal(result[0].totalVol, "17"); + assert.equal(result[1].id, "2"); + assert.equal(result[1].totalVol, "7"); + } catch (e) { + console.log(e); + assert.fail("expected to resolve, but failed"); + } + }); + + it("should fetch order trades list", async () => { + await mockServer + .forPost("/sg1") + .thenReply(200, JSON.stringify({ data: { trades: [mockTrade] } })); + + try { + const result: Trade[] = await getOrderTradesList( + mockServer.url + "/sg1", + "order1", + { + page: 1, + pageSize: 10, + }, + undefined, + undefined + ); + assert.equal(result.length, 1); + assert.equal(result[0].id, mockTrade.id); + assert.equal(result[0].order.id, mockTrade.order.id); + assert.equal( + result[0].outputVaultBalanceChange.amount, + mockTrade.outputVaultBalanceChange.amount + ); + assert.equal( + result[0].inputVaultBalanceChange.amount, + mockTrade.inputVaultBalanceChange.amount + ); + } catch (e) { + console.log(e); + assert.fail("expected to resolve, but failed"); + } + }); + + it("should fetch order trade detail", async () => { + await mockServer + .forPost("/sg1") + .thenReply(200, JSON.stringify({ data: { trade: mockTrade } })); + + try { + const result: Trade = await getOrderTradeDetail( + mockServer.url + "/sg1", + mockTrade.id + ); + assert.equal(result.id, mockTrade.id); + assert.equal(result.order.id, mockTrade.order.id); + assert.equal( + result.outputVaultBalanceChange.amount, + mockTrade.outputVaultBalanceChange.amount + ); + assert.equal( + result.inputVaultBalanceChange.amount, + mockTrade.inputVaultBalanceChange.amount + ); + } catch (e) { + console.log(e); + assert.fail("expected to resolve, but failed"); + } + }); });