diff --git a/crates/js_api/src/gui/select_tokens.rs b/crates/js_api/src/gui/select_tokens.rs index 67a920764..beafda022 100644 --- a/crates/js_api/src/gui/select_tokens.rs +++ b/crates/js_api/src/gui/select_tokens.rs @@ -47,6 +47,17 @@ impl DotrainOrderGui { Ok(()) } + #[wasm_bindgen(js_name = "getNetworkKey")] + pub fn get_network_key(&self) -> Result { + let order_key = Deployment::parse_order_key( + self.dotrain_order.dotrain_yaml().documents, + &self.selected_deployment, + )?; + let network_key = + Order::parse_network_key(self.dotrain_order.dotrain_yaml().documents, &order_key)?; + Ok(network_key) + } + #[wasm_bindgen(js_name = "saveSelectToken")] pub async fn save_select_token( &mut self, 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..cb173586d --- /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_transaction( + url: &str, + tx_hash: &str, +) -> Result { + let client = OrderbookSubgraphClient::new(Url::parse(url)?); + 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 fbcb74ac5..aa902c629 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; @@ -25,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)] @@ -379,4 +382,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/gui.test.ts b/packages/orderbook/test/js_api/gui.test.ts index 701af6781..ce140b675 100644 --- a/packages/orderbook/test/js_api/gui.test.ts +++ b/packages/orderbook/test/js_api/gui.test.ts @@ -1386,5 +1386,10 @@ ${dotrainWithoutVaultIds}`; "Missing required field 'tokens' in root" ); }); + + it('should get network key', async () => { + const networkKey = gui.getNetworkKey(); + assert.equal(networkKey, 'some-network'); + }); }); }); 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))); + } + }); +}); diff --git a/packages/ui-components/src/__tests__/DeploymentSteps.test.ts b/packages/ui-components/src/__tests__/DeploymentSteps.test.ts index 70b2c63bf..46566e7f3 100644 --- a/packages/ui-components/src/__tests__/DeploymentSteps.test.ts +++ b/packages/ui-components/src/__tests__/DeploymentSteps.test.ts @@ -6,6 +6,7 @@ import { DotrainOrderGui, type Scenario } from '@rainlanguage/orderbook/js_api'; import type { ComponentProps } from 'svelte'; import { writable } from 'svelte/store'; import type { AppKit } from '@reown/appkit'; +import type { ConfigSource } from '../lib/typeshare/config'; const { mockWagmiConfigStore, mockConnectedStore } = await vi.hoisted( () => import('../lib/__mocks__/stores') ); @@ -622,7 +623,8 @@ describe('DeploymentSteps', () => { it('shows deployment details when provided', async () => { (DotrainOrderGui.chooseDeployment as Mock).mockResolvedValue({ getSelectTokens: () => [], - getTokenInfo: vi.fn() + getTokenInfo: vi.fn(), + getNetworkKey: vi.fn() }); render(DeploymentSteps, { @@ -633,6 +635,7 @@ describe('DeploymentSteps', () => { wagmiConnected: mockConnectedStore, appKitModal: writable({} as AppKit), handleDeployModal: vi.fn(), + settings: writable({} as ConfigSource), handleUpdateGuiState: vi.fn() } }); @@ -646,7 +649,8 @@ describe('DeploymentSteps', () => { const mockSelectTokens = ['token1', 'token2']; (DotrainOrderGui.chooseDeployment as Mock).mockResolvedValue({ getSelectTokens: () => mockSelectTokens, - getTokenInfo: vi.fn() + getTokenInfo: vi.fn(), + getNetworkKey: vi.fn() }); render(DeploymentSteps, { @@ -657,6 +661,7 @@ describe('DeploymentSteps', () => { wagmiConnected: mockConnectedStore, appKitModal: writable({} as AppKit), handleDeployModal: vi.fn(), + settings: writable({} as ConfigSource), handleUpdateGuiState: vi.fn() } }); @@ -682,6 +687,7 @@ describe('DeploymentSteps', () => { wagmiConnected: mockConnectedStore, appKitModal: writable({} as AppKit), handleDeployModal: vi.fn(), + settings: writable({} as ConfigSource), handleUpdateGuiState: vi.fn() } }); @@ -706,7 +712,8 @@ describe('DeploymentSteps', () => { deposits: [] }), getAllFieldDefinitions: () => [], - getTokenInfo: vi.fn() + getTokenInfo: vi.fn(), + getNetworkKey: vi.fn() }); render(DeploymentSteps, { @@ -717,6 +724,7 @@ describe('DeploymentSteps', () => { wagmiConnected: mockConnectedStore, appKitModal: writable({} as AppKit), handleDeployModal: vi.fn(), + settings: writable({} as ConfigSource), handleUpdateGuiState: vi.fn() } }); @@ -739,7 +747,8 @@ describe('DeploymentSteps', () => { deposits: [] }), getAllFieldDefinitions: () => [], - getTokenInfo: vi.fn() + getTokenInfo: vi.fn(), + getNetworkKey: vi.fn() }); render(DeploymentSteps, { @@ -750,6 +759,7 @@ describe('DeploymentSteps', () => { wagmiConnected: mockConnectedStore, appKitModal: writable({} as AppKit), handleDeployModal: vi.fn(), + settings: writable({} as ConfigSource), handleUpdateGuiState: vi.fn() } }); diff --git a/packages/ui-components/src/__tests__/LightweightChart.test.ts b/packages/ui-components/src/__tests__/LightweightChart.test.ts index 2911a5df4..e400b2058 100644 --- a/packages/ui-components/src/__tests__/LightweightChart.test.ts +++ b/packages/ui-components/src/__tests__/LightweightChart.test.ts @@ -8,12 +8,14 @@ const setDataMock = vi.fn(); const applyOptionsMock = vi.fn(); const setVisibleRangeMock = vi.fn(); const removeMock = vi.fn(); +const updateMock = vi.fn(); vi.mock('lightweight-charts', async (importOriginal) => ({ ...((await importOriginal()) as object), createChart: vi.fn(() => ({ addLineSeries: vi.fn(() => ({ - setData: setDataMock + setData: setDataMock, + update: updateMock })), remove: removeMock, applyOptions: applyOptionsMock, @@ -96,23 +98,18 @@ test('renders with data correctly', async () => { }); }); -test('updates data correctly when props change', async () => { +test('updates data correctly when new data points are added', async () => { const title = 'test title'; const emptyMessage = 'empty message'; const loading = false; const priceSymbol = '$'; const createSeries = (chart: IChartApi) => chart.addLineSeries(); - const initialData: { value: number; time: UTCTimestamp; color?: string }[] = [ + const initialData = [ { value: 10, time: 1529899200 as UTCTimestamp }, { value: 20, time: 1529899300 as UTCTimestamp } ]; - const newData: { value: number; time: UTCTimestamp; color?: string }[] = [ - { value: 15, time: 1529900000 as UTCTimestamp }, - { value: 25, time: 1529900300 as UTCTimestamp } - ]; - const { component } = render(LightweightChart, { title, emptyMessage, @@ -123,15 +120,32 @@ test('updates data correctly when props change', async () => { lightweightChartsTheme: readable({ test: 'test' }) }); + // First render should call setData with initial data await waitFor(() => { expect(setDataMock).toHaveBeenCalledWith(initialData); }); - // Update data prop - await act(() => component.$set({ data: newData })); + // Add new data points + const newDataPoints = [ + ...initialData, + { value: 30, time: 1529899400 as UTCTimestamp }, + { value: 40, time: 1529899500 as UTCTimestamp } + ]; + + // Update with new data that includes additional points + await act(() => component.$set({ data: newDataPoints })); + // Should call update for each new point await waitFor(() => { - expect(setDataMock).toHaveBeenCalledWith(newData); + expect(updateMock).toHaveBeenCalledTimes(2); + expect(updateMock).toHaveBeenCalledWith({ + value: 30, + time: 1529899400 as UTCTimestamp + }); + expect(updateMock).toHaveBeenCalledWith({ + value: 40, + time: 1529899500 as UTCTimestamp + }); }); }); diff --git a/packages/ui-components/src/__tests__/OrderDetail.test.svelte b/packages/ui-components/src/__tests__/OrderDetail.test.svelte index 284198db7..a1b46623b 100644 --- a/packages/ui-components/src/__tests__/OrderDetail.test.svelte +++ b/packages/ui-components/src/__tests__/OrderDetail.test.svelte @@ -58,6 +58,7 @@ rpcUrl="https://example.com" query={orderDetailQuery} handleDepositOrWithdrawModal={() => {}} + {subgraphUrl} /> diff --git a/packages/ui-components/src/__tests__/VaultBalanceChart.test.ts b/packages/ui-components/src/__tests__/VaultBalanceChart.test.ts index 4304faa75..49337235f 100644 --- a/packages/ui-components/src/__tests__/VaultBalanceChart.test.ts +++ b/packages/ui-components/src/__tests__/VaultBalanceChart.test.ts @@ -5,6 +5,9 @@ import VaultBalanceChart from '../lib/components/charts/VaultBalanceChart.svelte import type { Vault } from '@rainlanguage/orderbook/js_api'; import { getVaultBalanceChanges } from '@rainlanguage/orderbook/js_api'; import { writable } from 'svelte/store'; +import type { ComponentProps } from 'svelte'; + +type VaultBalanceChartProps = ComponentProps; vi.mock('@rainlanguage/orderbook/js_api', () => ({ getVaultBalanceChanges: vi.fn() @@ -42,8 +45,9 @@ test('calls getVaultBalanceChanges with correct arguments', async () => { props: { vault: mockVault, subgraphUrl: 'https://example.com', - lightweightChartsTheme: writable({}) - }, + lightweightChartsTheme: writable({}), + id: 'vault1' + } as VaultBalanceChartProps, context: new Map([['$$_queryClient', queryClient]]) }); diff --git a/packages/ui-components/src/__tests__/transactionStore.test.ts b/packages/ui-components/src/__tests__/transactionStore.test.ts index 95ab04e64..10630ccb6 100644 --- a/packages/ui-components/src/__tests__/transactionStore.test.ts +++ b/packages/ui-components/src/__tests__/transactionStore.test.ts @@ -5,6 +5,8 @@ import transactionStore, { TransactionErrorMessage } from '../lib/stores/transactionStore'; import { waitForTransactionReceipt, sendTransaction, switchChain, type Config } from '@wagmi/core'; +import { getTransaction } from '@rainlanguage/orderbook/js_api'; +import { waitFor } from '@testing-library/svelte'; vi.mock('@wagmi/core', () => ({ waitForTransactionReceipt: vi.fn(), @@ -12,6 +14,10 @@ vi.mock('@wagmi/core', () => ({ switchChain: vi.fn() })); +vi.mock('@rainlanguage/orderbook/js_api', () => ({ + getTransaction: vi.fn() +})); + describe('transactionStore', () => { const mockConfig = {} as Config; const mockOrderbookAddress = '0xabcdef1234567890'; @@ -23,7 +29,8 @@ describe('transactionStore', () => { awaitWalletConfirmation, awaitApprovalTx, transactionSuccess, - transactionError + transactionError, + awaitTransactionIndexing } = transactionStore; beforeEach(() => { @@ -89,6 +96,7 @@ describe('transactionStore', () => { (sendTransaction as Mock).mockResolvedValueOnce('approvalHash1'); (sendTransaction as Mock).mockResolvedValueOnce('approvalHash2'); (sendTransaction as Mock).mockResolvedValueOnce('deployHash'); + (getTransaction as Mock).mockReturnValue({ id: 'mockHash' }); (waitForTransactionReceipt as Mock).mockResolvedValue({}); (switchChain as Mock).mockResolvedValue({}); @@ -97,10 +105,11 @@ describe('transactionStore', () => { approvals: mockApprovals, deploymentCalldata: mockDeploymentCalldata, orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); - expect(get(transactionStore).status).toBe(TransactionStatus.SUCCESS); + expect(get(transactionStore).status).toBe(TransactionStatus.PENDING_SUBGRAPH); expect(get(transactionStore).hash).toBe('deployHash'); }); @@ -112,7 +121,8 @@ describe('transactionStore', () => { approvals: [], deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(get(transactionStore).status).toBe(TransactionStatus.ERROR); @@ -130,7 +140,8 @@ describe('transactionStore', () => { approvals: mockApprovals, deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(get(transactionStore).status).toBe(TransactionStatus.ERROR); @@ -149,7 +160,8 @@ describe('transactionStore', () => { approvals: mockApprovals, deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(get(transactionStore).status).toBe(TransactionStatus.ERROR); @@ -165,7 +177,8 @@ describe('transactionStore', () => { approvals: [], deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(get(transactionStore).status).toBe(TransactionStatus.ERROR); @@ -182,7 +195,8 @@ describe('transactionStore', () => { approvals: [], deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(get(transactionStore).status).toBe(TransactionStatus.ERROR); @@ -207,11 +221,58 @@ describe('transactionStore', () => { approvals: mockApprovals, deploymentCalldata: '0x', orderbookAddress: mockOrderbookAddress as `0x${string}`, - chainId: 1 + chainId: 1, + subgraphUrl: 'test.com' }); expect(sendTransaction).toHaveBeenCalledTimes(3); // 2 approvals + 1 deployment - expect(get(transactionStore).status).toBe(TransactionStatus.SUCCESS); - expect(get(transactionStore).message).toBe('Strategy deployed successfully.'); + expect(get(transactionStore).status).toBe(TransactionStatus.PENDING_SUBGRAPH); + }); + + it('should handle waiting for subgraph indexing', async () => { + const mockSubgraphUrl = 'test.com'; + const mockTxHash = 'mockHash'; + const mockSuccessMessage = 'Success! Transaction confirmed'; + + (getTransaction as Mock).mockResolvedValue({ id: mockTxHash }); + + vi.useFakeTimers({ shouldAdvanceTime: true }); + + await awaitTransactionIndexing(mockSubgraphUrl, mockTxHash, mockSuccessMessage); + + vi.runOnlyPendingTimers(); + + await waitFor(() => { + expect(get(transactionStore).status).toBe(TransactionStatus.SUCCESS); + expect(get(transactionStore).message).toBe(mockSuccessMessage); + expect(get(transactionStore).hash).toBe(mockTxHash); + }); + }); + + it('should handle subgraph indexing timeout', async () => { + vi.useFakeTimers(); + const mockSubgraphUrl = 'test.com'; + const mockTxHash = 'mockHash'; + const mockSuccessMessage = 'Success message'; + + (getTransaction as Mock).mockResolvedValue(null); + + const indexingPromise = awaitTransactionIndexing( + mockSubgraphUrl, + mockTxHash, + mockSuccessMessage + ); + + expect(get(transactionStore).status).toBe(TransactionStatus.PENDING_SUBGRAPH); + expect(get(transactionStore).message).toBe('Checking for transaction indexing...'); + + await vi.advanceTimersByTime(10000); + await indexingPromise; + + expect(get(transactionStore).message).toBe( + 'The subgraph took too long to respond. Please check again later.' + ); + + vi.useRealTimers(); }); }); diff --git a/packages/ui-components/src/lib/components/charts/LightweightChart.svelte b/packages/ui-components/src/lib/components/charts/LightweightChart.svelte index 599d63698..8713fd332 100644 --- a/packages/ui-components/src/lib/components/charts/LightweightChart.svelte +++ b/packages/ui-components/src/lib/components/charts/LightweightChart.svelte @@ -45,6 +45,7 @@ let timeDelta: number; let timeFrom: UTCTimestamp; let timeTo: UTCTimestamp; + let previousDataLength = 0; function setTimeScale() { if (chart === undefined) return; @@ -70,9 +71,22 @@ }); } - function setData() { + function updateNewDataPoints() { if (series === undefined || data.length === 0) return; - series.setData(data); + + // If this is the first data set, set all the data + if (previousDataLength === 0) { + series.setData(data); + } + // If we have new data points, only update the new ones + else if (data.length > previousDataLength) { + const newPoints = data.slice(previousDataLength); + newPoints.forEach((point) => { + series?.update(point); + }); + } + + previousDataLength = data.length; setTimeScale(); } @@ -91,7 +105,7 @@ setOptions(); } - $: if (data || series) setData(); + $: if (data || series) updateNewDataPoints(); $: if (timeDelta) setTimeScale(); $: if ($lightweightChartsTheme) setOptions(); diff --git a/packages/ui-components/src/lib/components/charts/VaultBalanceChart.svelte b/packages/ui-components/src/lib/components/charts/VaultBalanceChart.svelte index 93a7ab5f5..6c71fa818 100644 --- a/packages/ui-components/src/lib/components/charts/VaultBalanceChart.svelte +++ b/packages/ui-components/src/lib/components/charts/VaultBalanceChart.svelte @@ -14,11 +14,12 @@ import { QKEY_VAULT_CHANGES } from '../../queries/keys'; export let vault: Vault; + export let id: string; export let subgraphUrl: string; export let lightweightChartsTheme; $: query = createQuery({ - queryKey: [QKEY_VAULT_CHANGES, vault], + queryKey: [id, QKEY_VAULT_CHANGES + id, QKEY_VAULT_CHANGES], queryFn: () => { return getVaultBalanceChanges(subgraphUrl || '', vault.id, { page: 1, diff --git a/packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte b/packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte index 923d22520..84e5124e5 100644 --- a/packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte +++ b/packages/ui-components/src/lib/components/deployment/DeploymentSteps.svelte @@ -4,6 +4,8 @@ import SelectTokensSection from './SelectTokensSection.svelte'; import ComposedRainlangModal from './ComposedRainlangModal.svelte'; import FieldDefinitionsSection from './FieldDefinitionsSection.svelte'; + import { type ConfigSource } from '../../typeshare/config'; + import WalletConnect from '../wallet/WalletConnect.svelte'; import { DotrainOrderGui, @@ -39,7 +41,7 @@ SERIALIZE_ERROR = 'Error serializing state', ADD_ORDER_FAILED = 'Failed to add order' } - + export let settings: Writable; export let dotrain: string; export let deployment: GuiDeployment; export let handleDeployModal: (args: { @@ -47,6 +49,7 @@ deploymentCalldata: DepositAndAddOrderCalldataResult; orderbookAddress: Hex; chainId: number; + subgraphUrl: string; }) => void; export let handleUpdateGuiState: (gui: DotrainOrderGui) => void; @@ -59,6 +62,8 @@ let gui: DotrainOrderGui | null = null; let error: DeploymentStepErrors | null = null; let errorDetails: string | null = null; + let networkKey: string | null = null; + let subgraphUrl: string = ''; export let wagmiConfig: Writable; export let wagmiConnected: Writable; @@ -78,6 +83,8 @@ gui = await DotrainOrderGui.chooseDeployment(dotrain, deployment); if (gui) { + networkKey = await gui.getNetworkKey(); + subgraphUrl = $settings?.subgraphs?.[networkKey] ?? ''; try { selectTokens = gui.getSelectTokens(); return selectTokens; @@ -181,7 +188,8 @@ approvals, deploymentCalldata, orderbookAddress, - chainId + chainId, + subgraphUrl }); } catch (e) { error = DeploymentStepErrors.ADD_ORDER_FAILED; diff --git a/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte b/packages/ui-components/src/lib/components/detail/DepositOrWithdrawButtons.svelte index 6ec384d48..d72fe8732 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 2adf3ee81..c1d3ce749 100644 --- a/packages/ui-components/src/lib/components/detail/OrderDetail.svelte +++ b/packages/ui-components/src/lib/components/detail/OrderDetail.svelte @@ -34,6 +34,7 @@ action: 'deposit' | 'withdraw'; chainId: number; rpcUrl: string; + subgraphUrl: string; }) => void) | undefined = undefined; export let handleOrderRemoveModal: @@ -73,7 +74,9 @@ $: orderDetailQuery = createQuery({ queryKey: [id, QKEY_ORDER + id], - queryFn: () => getOrder(subgraphUrl, id), + queryFn: () => { + return getOrder(subgraphUrl, id); + }, enabled: !!subgraphUrl }); @@ -162,6 +165,7 @@ {rpcUrl} query={orderDetailQuery} {handleDepositOrWithdrawModal} + {subgraphUrl} /> {/if} diff --git a/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte b/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte index 265bd9067..2d63397bd 100644 --- a/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte +++ b/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte @@ -40,7 +40,7 @@ }; $: orderQuoteQuery = createQuery({ - queryKey: [QKEY_ORDER_QUOTE + id], + queryKey: [QKEY_ORDER_QUOTE + id, id], queryFn: () => getOrderQuote([order], rpcUrl), enabled: !!id && enabled, refetchInterval: 10000 diff --git a/packages/ui-components/src/lib/components/detail/VaultDetail.svelte b/packages/ui-components/src/lib/components/detail/VaultDetail.svelte index 4ba56f815..63bdca277 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)}