diff --git a/Cargo.lock b/Cargo.lock index 3738ca8b6..86a887e55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8894,8 +8894,7 @@ dependencies = [ [[package]] name = "wasm-bindgen-utils" version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1275439b9979266e83596c1d8853fde5efc5f3b7316bf7b4d37fee8b05da26d2" +source = "git+https://github.com/rainlanguage/rain.wasm?rev=4379d24a671742a58ec5cdab2c39fecbda59619d#4379d24a671742a58ec5cdab2c39fecbda59619d" dependencies = [ "js-sys", "paste", @@ -8910,8 +8909,7 @@ dependencies = [ [[package]] name = "wasm-bindgen-utils-macros" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8275f5d18c47b912ec50aba1d89b96695fce856106923474520ac9dfc5ff4370" +source = "git+https://github.com/rainlanguage/rain.wasm?rev=4379d24a671742a58ec5cdab2c39fecbda59619d#4379d24a671742a58ec5cdab2c39fecbda59619d" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 84fbbb84a..916d60ea4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ test-context = "0.3.0" portpicker = "0.1.1" rain-erc = { git = "https://github.com/rainlanguage/rain.erc", rev = "0106e645ebd49334addc698c5aad9a85370eb54d" } rain-error-decoding = { git = "https://github.com/rainlanguage/rain.error", rev = "72d9577fdaf7135113847027ba951f9a43b41827" } -wasm-bindgen-utils = "0.0.7" +wasm-bindgen-utils = { git = "https://github.com/rainlanguage/rain.wasm", rev = "4379d24a671742a58ec5cdab2c39fecbda59619d" } [workspace.dependencies.rain_orderbook_bindings] path = "crates/bindings" diff --git a/crates/js_api/src/gui/state_management.rs b/crates/js_api/src/gui/state_management.rs index ce3076654..164a12a28 100644 --- a/crates/js_api/src/gui/state_management.rs +++ b/crates/js_api/src/gui/state_management.rs @@ -1,5 +1,4 @@ use super::*; -use js_sys::{eval, Reflect}; use rain_orderbook_app_settings::{gui::GuiDepositCfg, order::OrderIOCfg, token::TokenCfg}; use sha2::{Digest, Sha256}; use std::sync::{Arc, RwLock}; @@ -289,6 +288,7 @@ mod tests { tests::{initialize_gui, initialize_gui_with_select_tokens, YAML}, }; use alloy::primitives::U256; + use js_sys::{eval, Reflect}; use wasm_bindgen_test::wasm_bindgen_test; const SERIALIZED_STATE: &str = "H4sIAAAAAAAA_21Py4rCQBDMuMsuC3uShT0t7Ac45KkkggcRRfFxEFH0ppNBjZOZmEx8_oSfLGpPRLEPXVXdTXdXTrvFF-Bsyf0ln2NTU_EGaBrG85CFoGBoGVPkA1CKFeX2q22vJx_VN6hEhBRzKrciXv1BbSFlVNZ1JsiULUQiy67hFvU4IjiN2VEdRIohdbo-aP4AzTvD3ekpoTz6hPbg8sO_jd6VbvfsXGYlW2h5Hror0_MKQIMAH-pJVfi4MwqDmtNp-d3NOh6n0-HGbdT6TupY41Jjwgip_CqnlFEi8dU-9mnExD6kXJ4Bw5ytw6gBAAA="; diff --git a/crates/quote/src/js_api/mod.rs b/crates/quote/src/js_api/mod.rs index 998079bab..67ae963e3 100644 --- a/crates/quote/src/js_api/mod.rs +++ b/crates/quote/src/js_api/mod.rs @@ -1,73 +1,115 @@ use crate::{error::Error, BatchQuoteSpec, QuoteSpec}; -use crate::{get_order_quotes, BatchQuoteTarget, QuoteTarget}; +use crate::{ + get_order_quotes, BatchOrderQuotesResponse, BatchQuoteTarget, OrderQuoteValue, QuoteTarget, +}; +use alloy::hex::FromHexError; +use alloy::primitives::ruint::ParseError; use alloy::primitives::{ hex::{encode_prefixed, FromHex}, Address, U256, }; use rain_orderbook_bindings::wasm_traits::TryIntoU256; use rain_orderbook_subgraph_client::{types::common::SgOrder, utils::make_order_id}; +use serde::{Deserialize, Serialize}; use std::str::FromStr; -use wasm_bindgen_utils::prelude::*; +use thiserror::Error; +use wasm_bindgen_utils::{impl_wasm_traits, prelude::*, wasm_export}; + +#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] +#[serde(untagged)] +pub enum QuoteResultEnum { + Success { + value: OrderQuoteValue, + #[tsify(type = "undefined")] + error: Option, + }, + Err { + #[tsify(type = "undefined")] + value: Option, + error: String, + }, +} +impl_wasm_traits!(QuoteResultEnum); + +#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] +#[serde(rename_all = "camelCase")] +pub struct DoQuoteTargetsResult(pub Vec); +impl_wasm_traits!(DoQuoteTargetsResult); + +#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] +#[serde(rename_all = "camelCase")] +pub struct DoQuoteSpecsResult(pub Vec); +impl_wasm_traits!(DoQuoteSpecsResult); + +#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] +#[serde(rename_all = "camelCase")] +pub struct QuoteTargetResult( + #[tsify(type = "(QuoteTarget | undefined)[]")] pub Vec>, +); +impl_wasm_traits!(QuoteTargetResult); + +#[derive(Serialize, Deserialize, Debug, Clone, Tsify)] +#[serde(rename_all = "camelCase")] +pub struct DoOrderQuoteResult(pub Vec); +impl_wasm_traits!(DoOrderQuoteResult); /// Get subgraph represented "order_id" of a QuoteTarget -#[wasm_bindgen(js_name = "getId")] -pub fn get_id(orderbook: &str, order_hash: &str) -> String { - let mut orderbook_error = "orderbook address, ".to_string(); - let mut order_hash_error = "order hash, ".to_string(); - let orderbook = Address::from_hex(orderbook) - .inspect_err(|e| orderbook_error.push_str(&e.to_string())) - .expect_throw(&orderbook_error); - let order_hash = U256::from_str(order_hash) - .inspect_err(|e| order_hash_error.push_str(&e.to_string())) - .expect_throw(&order_hash_error); - encode_prefixed(make_order_id(orderbook, order_hash)) +#[wasm_export(js_name = "getId", unchecked_return_type = "string")] +pub fn get_id(orderbook: &str, order_hash: &str) -> Result { + let orderbook = Address::from_hex(orderbook)?; + let order_hash = U256::from_str(order_hash)?; + Ok(encode_prefixed(make_order_id(orderbook, order_hash))) } /// Quotes the target on the given rpc url /// Resolves with array of OrderQuoteValue object or a string error -#[wasm_bindgen(js_name = "doQuoteTargets")] +#[wasm_export( + js_name = "doQuoteTargets", + unchecked_return_type = "DoQuoteTargetsResult" +)] pub async fn do_quote_targets( quote_targets: &BatchQuoteTarget, rpc_url: &str, block_number: Option, gas: Option, multicall_address: Option, -) -> Result { - let mut multicall_address_error = "multicall address, ".to_string(); - let multicall_address = multicall_address.map(|v| { - Address::from_hex(v) - .inspect_err(|e| multicall_address_error.push_str(&e.to_string())) - .expect_throw(&multicall_address_error) - }); - let mut gas_error = "gas, ".to_string(); - let gas_value = gas.map(|v| { - v.try_into_u256() - .inspect_err(|e| gas_error.push_str(&e.to_string())) - .expect_throw(&gas_error) - }); +) -> Result { + let multicall_address = multicall_address + .map(|v| Address::from_hex(v)) + .transpose()?; + let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; let quote_targets: Vec = quote_targets .0 .iter() .map(|v| QuoteTarget::from(v.clone())) .collect(); let batch_quote_target = BatchQuoteTarget(quote_targets); - match batch_quote_target + + let quotes = batch_quote_target .do_quote(rpc_url, block_number, gas_value, multicall_address) - .await - { - Err(e) => Err(e), - Ok(v) => Ok(js_sys::Array::from_iter( - v.into_iter() - .map(|e| e.map_or_else(JsValue::from, JsValue::from)), - ) - .into()), - } + .await?; + + let res = quotes + .into_iter() + .map(|q| match q { + Ok(v) => QuoteResultEnum::Success { + value: v, + error: None, + }, + Err(e) => QuoteResultEnum::Err { + value: None, + error: e.to_string(), + }, + }) + .collect(); + + Ok(DoQuoteTargetsResult(res)) } /// Given a subgraph url, will fetch the order details from the subgraph and /// then quotes them using the given rpc url. /// Resolves with array of OrderQuoteValue object or a string error -#[wasm_bindgen(js_name = "doQuoteSpecs")] +#[wasm_export(js_name = "doQuoteSpecs", unchecked_return_type = "DoQuoteSpecsResult")] pub async fn do_quote_specs( quote_specs: &BatchQuoteSpec, subgraph_url: &str, @@ -75,26 +117,19 @@ pub async fn do_quote_specs( block_number: Option, gas: Option, multicall_address: Option, -) -> Result { - let mut multicall_address_error = "multicall address, ".to_string(); - let multicall_address = multicall_address.map(|v| { - Address::from_hex(v) - .inspect_err(|e| multicall_address_error.push_str(&e.to_string())) - .expect_throw(&multicall_address_error) - }); - let mut gas_error = "gas, ".to_string(); - let gas_value = gas.map(|v| { - v.try_into_u256() - .inspect_err(|e| gas_error.push_str(&e.to_string())) - .expect_throw(&gas_error) - }); +) -> Result { + let multicall_address = multicall_address + .map(|v| Address::from_hex(v)) + .transpose()?; + let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; let quote_specs: Vec = quote_specs .0 .iter() .map(|v| QuoteSpec::from(v.clone())) .collect(); let batch_quote_spec = BatchQuoteSpec(quote_specs); - match batch_quote_spec + + let quotes = batch_quote_spec .do_quote( subgraph_url, rpc_url, @@ -102,61 +137,102 @@ pub async fn do_quote_specs( gas_value, multicall_address, ) - .await - { - Err(e) => Err(e), - Ok(v) => Ok(js_sys::Array::from_iter( - v.into_iter() - .map(|e| e.map_or_else(JsValue::from, JsValue::from)), - ) - .into()), - } + .await?; + + let res = quotes + .into_iter() + .map(|q| match q { + Ok(v) => QuoteResultEnum::Success { + value: v, + error: None, + }, + Err(e) => QuoteResultEnum::Err { + value: None, + error: e.to_string(), + }, + }) + .collect(); + + Ok(DoQuoteSpecsResult(res)) } /// Given a subgraph url, will fetch orders details and returns their /// respective quote targets. /// Resolves with array of QuoteTarget object or undefined if no result /// found on subgraph for a specific spec -#[wasm_bindgen(js_name = "getQuoteTargetFromSubgraph")] +#[wasm_export( + js_name = "getQuoteTargetFromSubgraph", + unchecked_return_type = "QuoteTargetResult" +)] pub async fn get_batch_quote_target_from_subgraph( quote_specs: &BatchQuoteSpec, subgraph_url: &str, -) -> Result { +) -> Result { let quote_specs: Vec = quote_specs .0 .iter() .map(|v| QuoteSpec::from(v.clone())) .collect(); let batch_quote_spec = BatchQuoteSpec(quote_specs); - match batch_quote_spec + + let quote_targets = batch_quote_spec .get_batch_quote_target_from_subgraph(subgraph_url) - .await - { - Err(e) => Err(e), - Ok(v) => Ok(to_js_value( - &v.into_iter() - .map(|e| e.map(QuoteTarget::from)) - .collect::>(), - )?), - } + .await?; + Ok(QuoteTargetResult(quote_targets)) } /// Get the quote for an order /// Resolves with a BatchOrderQuotesResponse object -#[wasm_bindgen(js_name = "getOrderQuote")] +#[wasm_export( + js_name = "getOrderQuote", + unchecked_return_type = "DoOrderQuoteResult" +)] pub async fn get_order_quote( order: Vec, rpc_url: &str, block_number: Option, gas: Option, -) -> Result { - let mut gas_error = "gas, ".to_string(); - let gas_value = gas.map(|v| { - v.try_into_u256() - .inspect_err(|e| gas_error.push_str(&e.to_string())) - .expect_throw(&gas_error) - }); - Ok(to_js_value( - &get_order_quotes(order, block_number, rpc_url.to_string(), gas_value).await?, - )?) +) -> Result { + let gas_value = gas.map(|v| v.try_into_u256()).transpose()?; + let order_quotes = + get_order_quotes(order, block_number, rpc_url.to_string(), gas_value).await?; + Ok(DoOrderQuoteResult(order_quotes)) +} + +#[derive(Error, Debug)] +pub enum QuoteBindingsError { + #[error(transparent)] + QuoteError(#[from] Error), + #[error(transparent)] + FromHexError(#[from] FromHexError), + #[error(transparent)] + U256ParseError(#[from] ParseError), + #[error(transparent)] + SerdeWasmBindgenError(#[from] serde_wasm_bindgen::Error), +} + +impl QuoteBindingsError { + pub fn to_readable_msg(&self) -> String { + match self { + Self::QuoteError(e) => format!("Quote error: {}", e), + Self::FromHexError(e) => format!("Failed to parse orderbook address: {}", e), + Self::U256ParseError(e) => format!("Failed to parse u256 value: {}", e), + Self::SerdeWasmBindgenError(err) => format!("Data serialization error: {}", err), + } + } +} + +impl From for JsValue { + fn from(value: QuoteBindingsError) -> Self { + JsError::new(&value.to_string()).into() + } +} + +impl From for WasmEncodedError { + fn from(value: QuoteBindingsError) -> Self { + WasmEncodedError { + msg: value.to_string(), + readable_msg: value.to_readable_msg(), + } + } } diff --git a/packages/orderbook/test/quote/test.test.ts b/packages/orderbook/test/quote/test.test.ts index 492fec609..bb995d534 100644 --- a/packages/orderbook/test/quote/test.test.ts +++ b/packages/orderbook/test/quote/test.test.ts @@ -1,6 +1,6 @@ import assert from 'assert'; import { getLocal } from 'mockttp'; -import { describe, it, beforeEach, afterEach } from 'vitest'; +import { describe, it, beforeEach, afterEach, expect } from 'vitest'; import { getId, doQuoteTargets, @@ -23,7 +23,8 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { const orderHash = '0xf4058d50e798f18a048097265fe67fe2e8619f337b9377a7620bb87fc2f52721'; const result = getId(orderbook, orderHash); const expected = '0xca228cb816102ef9f8e0f9a87bb34e06c49c4d4ddf5a2a0ec229ab671475c235'; - assert.equal(result, expected); + if (result.error) expect.fail('Expected value'); + assert.equal(result.value, expected); }); it('should get correct quote targets from subgraph', async () => { @@ -113,6 +114,7 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { }; try { const result = await getQuoteTargetFromSubgraph([quoteSpec], mockServer.url + '/sg-url'); + if (!result.value) expect.fail('Expected value'); const expected: QuoteTarget = { quoteConfig: { order: { @@ -144,9 +146,8 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { }, orderbook: '0x713180d188e1ff758f508d9f2e1d350d650fea5e' }; - assert.deepEqual(result[0], expected); + expect(result.value[0]).toEqual(expected); } catch (error) { - console.log(error); assert.fail('expected to resolve, but failed'); } }); @@ -188,17 +189,13 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { signedContext: [] } }; - try { - const result = await doQuoteTargets([target], mockServer.url + '/rpc-url'); - const expected: OrderQuoteValue = { - maxOutput: '0x1', - ratio: '0x2' - }; - assert.deepEqual(result[0], expected); - } catch (error) { - console.log(error); - assert.fail('expected to resolve, but failed'); - } + const result = await doQuoteTargets([target], mockServer.url + '/rpc-url'); + if (!result.value) expect.fail('Expected value'); + const expected: OrderQuoteValue = { + maxOutput: '0x1', + ratio: '0x2' + }; + assert.deepEqual(result.value[0].value, expected); }); it('should get order quote', async () => { await mockServer.forPost('/rpc-url').once().thenSendJsonRpcResult('0x01'); @@ -276,6 +273,7 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { removeEvents: [] } as unknown as SgOrder; const result = await getOrderQuote([order], mockServer.url + '/rpc-url'); + if (result.error) expect.fail('Expected value'); const expected: BatchOrderQuotesResponse[] = [ { pair: { pairName: 'T2/T1', inputIndex: 0, outputIndex: 0 }, @@ -289,7 +287,7 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { } ]; - assert.deepEqual(result, expected); + assert.deepEqual(result.value, expected); }); it('should quote targets with gas', async () => { @@ -333,29 +331,28 @@ describe('Rain Orderbook Quote Package Bindgen Tests', async function () { }; // should fail without gas specified - try { - await doQuoteTargets([target], mockServer.url + '/rpc-url'); - throw 'expected to fail, but resolved'; - } catch (error) { - if (error === 'expected to fail, but resolved') assert.fail(error); - } + const doQuoteTargetsResult = await doQuoteTargets([target], mockServer.url + '/rpc-url'); + if (!doQuoteTargetsResult.error) expect.fail('Expected error'); + assert.deepEqual( + doQuoteTargetsResult.error.msg, + 'Execution reverted with unknown error. Data: "" ' + ); + assert.deepEqual( + doQuoteTargetsResult.error.readableMsg, + 'Quote error: Execution reverted with unknown error. Data: "" ' + ); - // should pass with gas specified - try { - const result = await doQuoteTargets( - [target], - mockServer.url + '/rpc-url', - undefined, - BigInt(123456) - ); - const expected: OrderQuoteValue = { - maxOutput: '0x1', - ratio: '0x2' - }; - assert.deepEqual(result[0], expected); - } catch (error) { - console.log(error); - assert.fail('expected to resolve, but failed'); - } + const result = await doQuoteTargets( + [target], + mockServer.url + '/rpc-url', + undefined, + BigInt(123456) + ); + if (result.error) expect.fail('Expected value'); + const expected: OrderQuoteValue = { + maxOutput: '0x1', + ratio: '0x2' + }; + assert.deepEqual(result.value[0].value, expected); }); }); diff --git a/packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts b/packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts index 3d00b14a5..a4cdaff1c 100644 --- a/packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts +++ b/packages/ui-components/src/__tests__/TanstackOrderQuote.test.ts @@ -12,15 +12,17 @@ vi.mock('@rainlanguage/orderbook', () => ({ })); test('displays order quote data when query is successful', async () => { - (getOrderQuote as Mock).mockResolvedValueOnce([ - { - success: true, - block_number: '0x123', - pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x158323e942e36d8c', ratio: '0x5b16799fcb6114f7' }, - error: undefined - } - ]); + (getOrderQuote as Mock).mockResolvedValueOnce({ + value: [ + { + success: true, + block_number: '0x123', + pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x158323e942e36d8c', ratio: '0x5b16799fcb6114f7' }, + error: undefined + } + ] + }); const queryClient = new QueryClient(); @@ -45,22 +47,24 @@ test('displays order quote data when query is successful', async () => { }); test('refreshes the quote when the refresh icon is clicked', async () => { - (getOrderQuote as Mock).mockResolvedValueOnce([ - { - success: true, - block_number: '0x123', - pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x158323e942e36d8c', ratio: '0x5b16799fcb6114f7' }, - error: undefined - }, - { - success: true, - block_number: '0x123', - pair: { pairName: 'BTC/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x54fa82f5c7001dad', ratio: '0x53e0089714d06709' }, - error: undefined - } - ]); + (getOrderQuote as Mock).mockResolvedValueOnce({ + value: [ + { + success: true, + block_number: '0x123', + pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x158323e942e36d8c', ratio: '0x5b16799fcb6114f7' }, + error: undefined + }, + { + success: true, + block_number: '0x123', + pair: { pairName: 'BTC/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x54fa82f5c7001dad', ratio: '0x53e0089714d06709' }, + error: undefined + } + ] + }); const queryClient = new QueryClient(); @@ -85,22 +89,24 @@ test('refreshes the quote when the refresh icon is clicked', async () => { expect(orderQuoteRows[1]).toHaveTextContent('6.123350635480882605'); }); - (getOrderQuote as Mock).mockResolvedValueOnce([ - { - success: true, - block_number: '0x123', - pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x5282713eceeccb5e', ratio: '0x577fe09a8775137c' }, - error: undefined - }, - { - success: true, - block_number: '0x123', - pair: { pairName: 'BTC/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x5430775053da5e53', ratio: '0x5a01719c871bb83f' }, - error: undefined - } - ]); + (getOrderQuote as Mock).mockResolvedValueOnce({ + value: [ + { + success: true, + block_number: '0x123', + pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x5282713eceeccb5e', ratio: '0x577fe09a8775137c' }, + error: undefined + }, + { + success: true, + block_number: '0x123', + pair: { pairName: 'BTC/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x5430775053da5e53', ratio: '0x5a01719c871bb83f' }, + error: undefined + } + ] + }); const refreshButton = screen.getByTestId('refresh-button'); fireEvent.click(refreshButton); @@ -121,15 +127,17 @@ test('refreshes the quote when the refresh icon is clicked', async () => { }); test('displays error message when query fails', async () => { - (getOrderQuote as Mock).mockResolvedValueOnce([ - { - success: false, - block_number: '0x123', - pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, - data: undefined, - error: 'Network error' - } - ]); + (getOrderQuote as Mock).mockResolvedValueOnce({ + value: [ + { + success: false, + block_number: '0x123', + pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, + data: undefined, + error: 'Network error' + } + ] + }); const queryClient = new QueryClient(); @@ -151,15 +159,17 @@ test('displays error message when query fails', async () => { }); test('displays zero for price when io ratio is zero', async () => { - (getOrderQuote as Mock).mockResolvedValueOnce([ - { - success: true, - block_number: '0x123', - pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, - data: { maxOutput: '0x158323e942e36d8c', ratio: '0x0' }, - error: undefined - } - ]); + (getOrderQuote as Mock).mockResolvedValueOnce({ + value: [ + { + success: true, + block_number: '0x123', + pair: { pairName: 'ETH/USDT', inputIndex: 0, outputIndex: 1 }, + data: { maxOutput: '0x158323e942e36d8c', ratio: '0x0' }, + error: undefined + } + ] + }); const queryClient = new QueryClient(); diff --git a/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte b/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte index f01a0d531..d4575b0e3 100644 --- a/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte +++ b/packages/ui-components/src/lib/components/detail/TanstackOrderQuote.svelte @@ -44,7 +44,11 @@ $: orderQuoteQuery = createQuery({ queryKey: [id, QKEY_ORDER_QUOTE + id], - queryFn: () => getOrderQuote([order], rpcUrl), + queryFn: async () => { + const result = await getOrderQuote([order], rpcUrl); + if (result.error) throw new Error(result.error.msg); + return result.value; + }, enabled: !!id && enabled }); diff --git a/tauri-app/src-tauri/Cargo.lock b/tauri-app/src-tauri/Cargo.lock index 21b4a92c5..baebb8100 100644 --- a/tauri-app/src-tauri/Cargo.lock +++ b/tauri-app/src-tauri/Cargo.lock @@ -11776,8 +11776,7 @@ dependencies = [ [[package]] name = "wasm-bindgen-utils" version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1275439b9979266e83596c1d8853fde5efc5f3b7316bf7b4d37fee8b05da26d2" +source = "git+https://github.com/rainlanguage/rain.wasm?rev=4379d24a671742a58ec5cdab2c39fecbda59619d#4379d24a671742a58ec5cdab2c39fecbda59619d" dependencies = [ "js-sys", "paste", @@ -11792,8 +11791,7 @@ dependencies = [ [[package]] name = "wasm-bindgen-utils-macros" version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8275f5d18c47b912ec50aba1d89b96695fce856106923474520ac9dfc5ff4370" +source = "git+https://github.com/rainlanguage/rain.wasm?rev=4379d24a671742a58ec5cdab2c39fecbda59619d#4379d24a671742a58ec5cdab2c39fecbda59619d" dependencies = [ "proc-macro2", "quote",