From bf3fdea49daa6238eac166846f95beaff9d5fbde Mon Sep 17 00:00:00 2001 From: HoseinBaseri Date: Tue, 7 Jan 2025 10:12:46 +0330 Subject: [PATCH 1/3] refactor: update address handling in CardDialog and remove baseUrl from MyTonSwapClient --- lib/components/SwapCard/CardDialog.tsx | 44 +++++++++++++++----------- lib/store/events.store.ts | 14 ++++---- lib/store/swap.store.ts | 1 - lib/store/wallet.store.ts | 1 - lib/utils/swap.ts | 1 - 5 files changed, 32 insertions(+), 29 deletions(-) diff --git a/lib/components/SwapCard/CardDialog.tsx b/lib/components/SwapCard/CardDialog.tsx index f9beb9b..358e217 100644 --- a/lib/components/SwapCard/CardDialog.tsx +++ b/lib/components/SwapCard/CardDialog.tsx @@ -177,26 +177,32 @@ const CardDialog: FC = ({ onNextPage(1); }; - const filteredAssets = assetList - ? assetList - .sort(sortAssets) - .filter((item) => { - if ( - searchInput.toLowerCase() === 'usdt' && - item.symbol === 'USD₮' - ) { - return true; - } - const searchValue = searchInput.toLowerCase(); + const filteredAssets = + assetList + ?.sort(sortAssets) + .filter((item) => { + const searchValue = searchInput.toLowerCase(); - return ( - item.name.toLowerCase().includes(searchValue) || - item.symbol.toLowerCase().includes(searchValue) || - item.address.includes(searchInput) - ); - }) - .filter((item) => (communityTokens ? true : !item.warning)) - : []; + if (searchValue === 'usdt' && item.symbol === 'USD₮') { + return true; + } + + let addressSearch = ''; + try { + addressSearch = address(searchInput).toString({ + bounceable: true, + }); + } catch { + // Ignore invalid address + } + + return ( + item.name.toLowerCase().includes(searchValue) || + item.symbol.toLowerCase().includes(searchValue) || + item.address.includes(addressSearch) + ); + }) + .filter((item) => (communityTokens ? true : !item.warning)) || []; const handleOnClose = () => { setIsSelectVisible(false); diff --git a/lib/store/events.store.ts b/lib/store/events.store.ts index 3809b34..d74dbb2 100644 --- a/lib/store/events.store.ts +++ b/lib/store/events.store.ts @@ -1,8 +1,8 @@ -import { Asset } from "@mytonswap/sdk"; -import { create } from "zustand"; +import { Asset } from '@mytonswap/sdk'; +import { create } from 'zustand'; export type onSwap = { - type: "start" | "success" | "error"; + type: 'start' | 'success' | 'error'; data: { pay: Asset; receive: Asset; @@ -10,13 +10,13 @@ export type onSwap = { receive_amount: string; pay_rate: number; receive_rate: number; - dex: "stonfi" | "dedust"; + dex: 'stonfi' | 'dedust' | 'tonco'; hash: string; }; }; export type onTokenSelect = { - type: "pay" | "receive"; + type: 'pay' | 'receive'; asset: Asset; }; @@ -29,11 +29,11 @@ type EventsActions = { export const useEventsStore = create((set) => ({ onTokenSelect: (data) => { - console.log("default onTokenSelect called"); + console.log('default onTokenSelect called'); console.log(data); }, onSwap: (data) => { - console.log("default onSwap called"); + console.log('default onSwap called'); console.log(data); }, setOnTokenSelect: (onTokenSelect) => { diff --git a/lib/store/swap.store.ts b/lib/store/swap.store.ts index d982717..d43019f 100644 --- a/lib/store/swap.store.ts +++ b/lib/store/swap.store.ts @@ -71,7 +71,6 @@ type SwapActions = { export const useSwapStore = create((set, get) => ({ client: new MyTonSwapClient({ - baseUrl: 'https://devtest.mytonswap.com/api/', headers: { 'widget-version': WIDGET_VERSION }, }), refetchInterval: null, diff --git a/lib/store/wallet.store.ts b/lib/store/wallet.store.ts index b64532d..346f564 100644 --- a/lib/store/wallet.store.ts +++ b/lib/store/wallet.store.ts @@ -22,7 +22,6 @@ export const useWalletStore = create( (set, get) => ({ client: new MyTonSwapClient({ headers: { 'widget-version': WIDGET_VERSION }, - baseUrl: 'https://devtest.mytonswap.com/api/', }), wallet: null, walletConnected: false, diff --git a/lib/utils/swap.ts b/lib/utils/swap.ts index ade2bdb..0c60de0 100644 --- a/lib/utils/swap.ts +++ b/lib/utils/swap.ts @@ -19,7 +19,6 @@ export default async function swap( ) { const client = new MyTonSwapClient({ headers: { 'widget-version': WIDGET_VERSION }, - baseUrl: 'https://devtest.mytonswap.com/api/', }); const app_id = useOptionsStore.getState().options.app_id; const rawMessageResult = await catchError(() => From 1772db9c5c5976a9c2a9a62723450e3b3aa4faca Mon Sep 17 00:00:00 2001 From: HoseinBaseri Date: Tue, 7 Jan 2025 11:09:54 +0330 Subject: [PATCH 2/3] feat: add liquidity provider option and enhance Swap component styling --- lib/components/Swap/Swap.scss | 1 + lib/components/Swap/Swap.stories.tsx | 15 ++++++++++ lib/components/SwapCard/CardDialog.tsx | 3 +- lib/store/options.store.ts | 38 ++++++++++++++++++++++---- lib/store/swap.store.ts | 4 ++- lib/store/wallet.store.ts | 4 ++- lib/utils/swap.ts | 4 ++- 7 files changed, 60 insertions(+), 9 deletions(-) diff --git a/lib/components/Swap/Swap.scss b/lib/components/Swap/Swap.scss index ec99bcb..75aa7b2 100644 --- a/lib/components/Swap/Swap.scss +++ b/lib/components/Swap/Swap.scss @@ -25,6 +25,7 @@ button { cursor: pointer; border: none; + background: transparent; font-family: Inter, sans-serif; } input { diff --git a/lib/components/Swap/Swap.stories.tsx b/lib/components/Swap/Swap.stories.tsx index be12ccc..695c47e 100644 --- a/lib/components/Swap/Swap.stories.tsx +++ b/lib/components/Swap/Swap.stories.tsx @@ -150,6 +150,21 @@ export const WithAppId: Story = { ], }; +export const WithLiquidityProvider: Story = { + args: { + options: { + liquidity_provider: 'dedust', + }, + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +}; + export const HideSwapDetail: Story = { args: { options: { diff --git a/lib/components/SwapCard/CardDialog.tsx b/lib/components/SwapCard/CardDialog.tsx index 358e217..4a08bda 100644 --- a/lib/components/SwapCard/CardDialog.tsx +++ b/lib/components/SwapCard/CardDialog.tsx @@ -199,7 +199,8 @@ const CardDialog: FC = ({ return ( item.name.toLowerCase().includes(searchValue) || item.symbol.toLowerCase().includes(searchValue) || - item.address.includes(addressSearch) + (addressSearch.length > 0 && + item.address.includes(addressSearch)) ); }) .filter((item) => (communityTokens ? true : !item.warning)) || []; diff --git a/lib/store/options.store.ts b/lib/store/options.store.ts index a37656c..0b46ef9 100644 --- a/lib/store/options.store.ts +++ b/lib/store/options.store.ts @@ -1,7 +1,10 @@ -import { create } from "zustand"; -import { defaultsDeep } from "lodash"; -import { TonConnectUI } from "@tonconnect/ui-react"; -import { useSwapStore } from "./swap.store"; +import { create } from 'zustand'; +import { defaultsDeep } from 'lodash'; +import { TonConnectUI } from '@tonconnect/ui-react'; +import { useSwapStore } from './swap.store'; +import { MyTonSwapClient } from '@mytonswap/sdk'; +import { WIDGET_VERSION } from '../constants'; +import { useWalletStore } from './wallet.store'; export type SwapOptions = { default_pay_token?: string; @@ -13,7 +16,13 @@ export type SwapOptions = { default_pay_amount?: string; pin_tokens?: string[]; app_id?: string; - layout_direction?: "ltr" | "rtl"; + liquidity_provider?: + | 'mytonswap' + | 'stonfi' + | 'dedust' + | 'tonco' + | 'omniston'; + layout_direction?: 'ltr' | 'rtl'; ui_preferences?: { disable_provided_text?: boolean; show_swap_details?: boolean; @@ -41,6 +50,7 @@ export const useOptionsStore = create( (set, get) => ({ tonConnectInstance: null, options: { + liquidity_provider: 'mytonswap', ui_preferences: { disable_provided_text: false, disable_token_select_pay: false, @@ -67,6 +77,24 @@ export const useOptionsStore = create( if (option.default_slippage) { useSwapStore.getState().setSlippage(option.default_slippage); } + if (option.liquidity_provider) { + useSwapStore.setState({ + client: new MyTonSwapClient({ + headers: { + 'widget-version': WIDGET_VERSION, + 'liquidity-provider': option.liquidity_provider, + }, + }), + }); + useWalletStore.setState({ + client: new MyTonSwapClient({ + headers: { + 'widget-version': WIDGET_VERSION, + 'liquidity-provider': option.liquidity_provider, + }, + }), + }); + } }, setTonConnectInstance: (instance) => { if (get().tonConnectInstance) return; diff --git a/lib/store/swap.store.ts b/lib/store/swap.store.ts index d43019f..93fa9f6 100644 --- a/lib/store/swap.store.ts +++ b/lib/store/swap.store.ts @@ -71,7 +71,9 @@ type SwapActions = { export const useSwapStore = create((set, get) => ({ client: new MyTonSwapClient({ - headers: { 'widget-version': WIDGET_VERSION }, + headers: { + 'widget-version': WIDGET_VERSION, + }, }), refetchInterval: null, pay_token: null, diff --git a/lib/store/wallet.store.ts b/lib/store/wallet.store.ts index 346f564..61f9f65 100644 --- a/lib/store/wallet.store.ts +++ b/lib/store/wallet.store.ts @@ -21,7 +21,9 @@ type WalletActions = { export const useWalletStore = create( (set, get) => ({ client: new MyTonSwapClient({ - headers: { 'widget-version': WIDGET_VERSION }, + headers: { + 'widget-version': WIDGET_VERSION, + }, }), wallet: null, walletConnected: false, diff --git a/lib/utils/swap.ts b/lib/utils/swap.ts index 0c60de0..9d25a83 100644 --- a/lib/utils/swap.ts +++ b/lib/utils/swap.ts @@ -18,7 +18,9 @@ export default async function swap( bestRoute: BestRoute ) { const client = new MyTonSwapClient({ - headers: { 'widget-version': WIDGET_VERSION }, + headers: { + 'widget-version': WIDGET_VERSION, + }, }); const app_id = useOptionsStore.getState().options.app_id; const rawMessageResult = await catchError(() => From 1db7183358cd4b9c2b630ff62081d117115a74f4 Mon Sep 17 00:00:00 2001 From: HoseinBaseri Date: Tue, 7 Jan 2025 11:17:52 +0330 Subject: [PATCH 3/3] test: standardize string quotes in swap tests --- cypress/e2e/base.cy.ts | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cypress/e2e/base.cy.ts b/cypress/e2e/base.cy.ts index 8787ce2..ac68e63 100644 --- a/cypress/e2e/base.cy.ts +++ b/cypress/e2e/base.cy.ts @@ -1,48 +1,48 @@ -describe("swap tests", () => { +describe('swap tests', () => { beforeEach(() => { cy.visit( - "http://localhost:6006/iframe.html?args=&globals=&id=components-swap--default&viewMode=story" + 'http://localhost:6006/iframe.html?args=&globals=&id=components-swap--default&viewMode=story' ); }); - it("should be able to swap ston with right dex", () => { + it('should be able to swap ston with right dex', () => { cy.get("[data-testid='card-button-receive']").click(); - cy.get("[data-testid='dialog-search-input']").type("STON"); + cy.get("[data-testid='dialog-search-input']").type('STON'); cy.get( "[data-testid='EQA2kCVNwVsil2EM2mB0SkXytxCqQjS4mttjDpnXmwG9T6bO']" ).click(); - cy.get("[data-testid='swapcard-input-pay']").type("100"); + cy.get("[data-testid='swapcard-input-pay']").type('100'); cy.get("[data-testid='swap-details']").click(); cy.get("[data-testid='dex-container']").should( - "contain.text", - "Ston.fi" + 'contain.text', + 'StonFi' ); }); - it("should be able to swap scale with right dex", () => { + it('should be able to swap scale with right dex', () => { cy.get("[data-testid='card-button-receive']").click(); - cy.get("[data-testid='dialog-search-input']").type("SCALE"); + cy.get("[data-testid='dialog-search-input']").type('SCALE'); cy.get( "[data-testid='EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE']" ).click(); - cy.get("[data-testid='swapcard-input-pay']").type("100"); + cy.get("[data-testid='swapcard-input-pay']").type('100'); cy.get("[data-testid='swap-details']").click(); cy.get("[data-testid='dex-container']").should( - "contain.text", - "Dedust" + 'contain.text', + 'Dedust' ); }); - it("output should get price impact when input amount is too high", () => { + it('output should get price impact when input amount is too high', () => { cy.get("[data-testid='card-button-receive']").click(); - cy.get("[data-testid='dialog-search-input']").type("SCALE"); + cy.get("[data-testid='dialog-search-input']").type('SCALE'); cy.get( "[data-testid='EQBlqsm144Dq6SjbPI4jjZvA1hqTIP3CvHovbIfW_t-SCALE']" ).click(); - cy.get("[data-testid='swapcard-input-pay']").type("10000"); + cy.get("[data-testid='swapcard-input-pay']").type('10000'); cy.get("[data-testid='swap-details']").click(); cy.wait(1000); cy.get("[data-testid='price-impact']") - .invoke("text") + .invoke('text') .then((text) => { - const impact = parseFloat(text.replace("%", "")); + const impact = parseFloat(text.replace('%', '')); expect(impact).to.be.greaterThan(90); }); });