From 3e288c4cfd4d3c1766bb353d027fbdbf11645c6b Mon Sep 17 00:00:00 2001 From: Jamie Harding Date: Mon, 10 Feb 2025 16:00:08 +0100 Subject: [PATCH 01/25] Add getTransaction --- crates/js_api/src/subgraph/mod.rs | 1 + crates/js_api/src/subgraph/transaction.rs | 16 ++++++++++ crates/subgraph/src/orderbook_client.rs | 14 +++++++++ crates/subgraph/src/types/mod.rs | 1 + crates/subgraph/src/types/transaction.rs | 12 +++++++ .../orderbook/test/js_api/transaction.test.ts | 31 +++++++++++++++++++ 6 files changed, 75 insertions(+) create mode 100644 crates/js_api/src/subgraph/transaction.rs create mode 100644 crates/subgraph/src/types/transaction.rs create mode 100644 packages/orderbook/test/js_api/transaction.test.ts diff --git a/crates/js_api/src/subgraph/mod.rs b/crates/js_api/src/subgraph/mod.rs index 3241b9c16..7df2bad7f 100644 --- a/crates/js_api/src/subgraph/mod.rs +++ b/crates/js_api/src/subgraph/mod.rs @@ -8,6 +8,7 @@ use thiserror::Error; use wasm_bindgen::{JsError, JsValue}; pub mod order; +pub mod transaction; pub mod vault; #[derive(Error, Debug)] diff --git a/crates/js_api/src/subgraph/transaction.rs b/crates/js_api/src/subgraph/transaction.rs new file mode 100644 index 000000000..d629860b4 --- /dev/null +++ b/crates/js_api/src/subgraph/transaction.rs @@ -0,0 +1,16 @@ +use cynic::Id; +use rain_orderbook_bindings::wasm_traits::prelude::*; +use rain_orderbook_subgraph_client::{OrderbookSubgraphClient, OrderbookSubgraphClientError}; +use reqwest::Url; + +/// Internal function to fetch a single transaction +/// Returns the Transaction struct +#[wasm_bindgen(js_name = "getTransaction")] +pub async fn get_sg_transaction( + url: &str, + id: &str, +) -> Result { + let client = OrderbookSubgraphClient::new(Url::parse(url)?); + let transaction = client.transaction_detail(Id::new(id)).await?; + Ok(to_value(&transaction)?) +} diff --git a/crates/subgraph/src/orderbook_client.rs b/crates/subgraph/src/orderbook_client.rs index fbcb74ac5..4d83760e5 100644 --- a/crates/subgraph/src/orderbook_client.rs +++ b/crates/subgraph/src/orderbook_client.rs @@ -8,6 +8,7 @@ use crate::types::order::{ OrdersListQuery, }; use crate::types::order_trade::{OrderTradeDetailQuery, OrderTradesListQuery}; +use crate::types::transaction::TransactionDetailQuery; use crate::types::vault::{VaultDetailQuery, VaultsListQuery}; use crate::vault_balance_changes_query::VaultBalanceChangesListPageQueryClient; use cynic::Id; @@ -379,4 +380,17 @@ impl OrderbookSubgraphClient { } Ok(all_pages_merged) } + + pub async fn transaction_detail( + &self, + id: Id, + ) -> Result { + let data = self + .query::(IdQueryVariables { id: &id }) + .await?; + let transaction = data + .transaction + .ok_or(OrderbookSubgraphClientError::Empty)?; + Ok(transaction) + } } diff --git a/crates/subgraph/src/types/mod.rs b/crates/subgraph/src/types/mod.rs index b653da9b9..aa590dc15 100644 --- a/crates/subgraph/src/types/mod.rs +++ b/crates/subgraph/src/types/mod.rs @@ -3,6 +3,7 @@ mod impls; pub mod order; pub mod order_detail_traits; pub mod order_trade; +pub mod transaction; pub mod vault; pub use cynic::Id; diff --git a/crates/subgraph/src/types/transaction.rs b/crates/subgraph/src/types/transaction.rs new file mode 100644 index 000000000..7344b5f23 --- /dev/null +++ b/crates/subgraph/src/types/transaction.rs @@ -0,0 +1,12 @@ +use super::common::*; +use crate::schema; +use typeshare::typeshare; + +#[derive(cynic::QueryFragment, Debug)] +#[cynic(graphql_type = "Query", variables = "IdQueryVariables")] +#[typeshare] +pub struct TransactionDetailQuery { + #[arguments(id: $id)] + #[typeshare(typescript(type = "TransactionSubgraph"))] + pub transaction: Option, +} diff --git a/packages/orderbook/test/js_api/transaction.test.ts b/packages/orderbook/test/js_api/transaction.test.ts new file mode 100644 index 000000000..809db66bb --- /dev/null +++ b/packages/orderbook/test/js_api/transaction.test.ts @@ -0,0 +1,31 @@ +import assert from 'assert'; +import { getLocal } from 'mockttp'; +import { describe, it, beforeEach, afterEach } from 'vitest'; +import { Transaction } from '../../dist/types/js_api.js'; +import { getTransaction } from '../../dist/cjs/js_api.js'; + +const transaction1 = { + id: 'tx1', + from: '0x1', + blockNumber: '1', + timestamp: '1' +} as unknown as Transaction; + +describe('Rain Orderbook JS API Package Bindgen Tests - Order', async function () { + const mockServer = getLocal(); + beforeEach(() => mockServer.start(8090)); + afterEach(() => mockServer.stop()); + + it('should fetch a single transaction', async () => { + await mockServer + .forPost('/sg1') + .thenReply(200, JSON.stringify({ data: { transaction: transaction1 } })); + + try { + const result: Transaction = await getTransaction(mockServer.url + '/sg1', transaction1.id); + assert.equal(result.id, transaction1.id); + } catch (e) { + assert.fail('expected to resolve, but failed' + (e instanceof Error ? e.message : String(e))); + } + }); +}); From 8bd686d51a16c2b18c307e5c060f6109feb0b099 Mon Sep 17 00:00:00 2001 From: Jamie Harding Date: Tue, 11 Feb 2025 11:34:58 +0100 Subject: [PATCH 02/25] getting the tc and polling --- crates/js_api/src/subgraph/transaction.rs | 6 +-- crates/subgraph/src/orderbook_client.rs | 2 + .../detail/DepositOrWithdrawButtons.svelte | 8 +++- .../lib/components/detail/OrderDetail.svelte | 3 ++ .../lib/components/detail/VaultDetail.svelte | 2 + .../src/lib/stores/transactionStore.ts | 47 +++++++++++++++---- .../components/DepositOrWithdrawModal.svelte | 7 ++- packages/webapp/src/lib/services/modal.ts | 1 + 8 files changed, 61 insertions(+), 15 deletions(-) diff --git a/crates/js_api/src/subgraph/transaction.rs b/crates/js_api/src/subgraph/transaction.rs index d629860b4..cb173586d 100644 --- a/crates/js_api/src/subgraph/transaction.rs +++ b/crates/js_api/src/subgraph/transaction.rs @@ -6,11 +6,11 @@ use reqwest::Url; /// Internal function to fetch a single transaction /// Returns the Transaction struct #[wasm_bindgen(js_name = "getTransaction")] -pub async fn get_sg_transaction( +pub async fn get_transaction( url: &str, - id: &str, + tx_hash: &str, ) -> Result { let client = OrderbookSubgraphClient::new(Url::parse(url)?); - let transaction = client.transaction_detail(Id::new(id)).await?; + let transaction = client.transaction_detail(Id::new(tx_hash)).await?; Ok(to_value(&transaction)?) } diff --git a/crates/subgraph/src/orderbook_client.rs b/crates/subgraph/src/orderbook_client.rs index 4d83760e5..aa902c629 100644 --- a/crates/subgraph/src/orderbook_client.rs +++ b/crates/subgraph/src/orderbook_client.rs @@ -26,6 +26,8 @@ pub enum OrderbookSubgraphClientError { CynicClientError(#[from] CynicClientError), #[error("Subgraph query returned no data")] Empty, + #[error("Request timed out")] + RequestTimedOut, #[error(transparent)] PaginationClientError(#[from] PaginationClientError), #[error(transparent)] diff --git a/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte b/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte index 0b70c7e1b..7e5472c60 100644 --- a/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte +++ b/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte @@ -10,12 +10,14 @@ action: 'deposit' | 'withdraw'; chainId: number; rpcUrl: string; + subgraphUrl: string; }) => void; export let vault: Vault; export let chainId: number; export let rpcUrl: string; export let query: CreateQueryResult; + export let subgraphUrl: string; diff --git a/packages/ui-components/src/lib/components/detail/OrderDetail.svelte b/packages/ui-components/src/lib/components/detail/OrderDetail.svelte index 21f550cb4..8f9780854 100644 --- a/packages/ui-components/src/lib/components/detail/OrderDetail.svelte +++ b/packages/ui-components/src/lib/components/detail/OrderDetail.svelte @@ -31,6 +31,7 @@ action: 'deposit' | 'withdraw'; chainId: number; rpcUrl: string; + subgraphUrl: string; }) => void) | undefined = undefined; export let handleOrderRemoveModal: @@ -146,6 +147,7 @@ {rpcUrl} query={orderDetailQuery} {handleDepositOrWithdrawModal} + {subgraphUrl} /> {/if} {/each} @@ -169,6 +171,7 @@ {rpcUrl} query={orderDetailQuery} {handleDepositOrWithdrawModal} + {subgraphUrl} /> {/if} {/each} diff --git a/packages/ui-components/src/lib/components/detail/VaultDetail.svelte b/packages/ui-components/src/lib/components/detail/VaultDetail.svelte index 4ba56f815..70ea6fac3 100644 --- a/packages/ui-components/src/lib/components/detail/VaultDetail.svelte +++ b/packages/ui-components/src/lib/components/detail/VaultDetail.svelte @@ -30,6 +30,7 @@ action: 'deposit' | 'withdraw'; chainId: number; rpcUrl: string; + subgraphUrl: string }) => void) | undefined = undefined; export let id: string; @@ -97,6 +98,7 @@ {rpcUrl} query={vaultDetailQuery} {handleDepositOrWithdrawModal} + {subgraphUrl} /> {:else if handleDepositModal && handleWithdrawModal && $walletAddressMatchesOrBlank?.(data.owner)}