From d5c9f94b1b769ee0664921c2f1b8dceb07839959 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Mon, 17 Jun 2024 19:33:05 -0700 Subject: [PATCH 1/9] Fix typo --- apps/minifront/src/components/send/send-form/index.tsx | 4 ++-- .../src/components/swap/swap-form/token-swap-input.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/minifront/src/components/send/send-form/index.tsx b/apps/minifront/src/components/send/send-form/index.tsx index 8f4901b40f..79c705143a 100644 --- a/apps/minifront/src/components/send/send-form/index.tsx +++ b/apps/minifront/src/components/send/send-form/index.tsx @@ -34,7 +34,7 @@ export const SendForm = () => { txInProgress, } = useStore(sendSelector); // State to manage privacy warning display - const [showNonNativeFeeWarning, setshowNonNativeFeeWarning] = useState(false); + const [showNonNativeFeeWarning, setShowNonNativeFeeWarning] = useState(false); // Check if the user has native staking tokens const stakingToken = hasStakingToken( @@ -81,7 +81,7 @@ export const SendForm = () => { if (Number(amount) < 0) return; setAmount(amount); // Conditionally prompt a privacy warning about non-native fee tokens - setshowNonNativeFeeWarning(Number(amount) > 0 && !stakingToken); + setShowNonNativeFeeWarning(Number(amount) > 0 && !stakingToken); }} validations={[ { diff --git a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx index f0606759d4..b6744056dc 100644 --- a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx +++ b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx @@ -90,7 +90,7 @@ export const TokenSwapInput = () => { hasStakingTokenMeta, } = useStoreShallow(tokenSwapInputSelector); // State to manage privacy warning display - const [showNonNativeFeeWarning, setshowNonNativeFeeWarning] = useState(false); + const [showNonNativeFeeWarning, setShowNonNativeFeeWarning] = useState(false); // Check if the user has native staking tokens const stakingToken = hasStakingToken(balancesResponses, hasStakingTokenMeta); @@ -131,7 +131,7 @@ export const TokenSwapInput = () => { onChange={e => { if (!isValidAmount(e.target.value, assetIn)) return; setAmount(e.target.value); - setshowNonNativeFeeWarning(Number(e.target.value) > 0 && !stakingToken); + setShowNonNativeFeeWarning(Number(e.target.value) > 0 && !stakingToken); }} />
From 8e7eda36bd0879ee54d2e0d165c97aa9f8d9dd18 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Tue, 18 Jun 2024 14:30:00 -0700 Subject: [PATCH 2/9] Use ZQuery for the Swap slice --- apps/minifront/src/components/root-router.tsx | 3 +- .../swap/swap-form/token-swap-input.tsx | 53 ++++++------ .../src/components/swap/swap-loader.ts | 42 ---------- apps/minifront/src/state/swap/index.ts | 80 ++++++++++++------- 4 files changed, 84 insertions(+), 94 deletions(-) delete mode 100644 apps/minifront/src/components/swap/swap-loader.ts diff --git a/apps/minifront/src/components/root-router.tsx b/apps/minifront/src/components/root-router.tsx index ca609cb773..6aa2a78c37 100644 --- a/apps/minifront/src/components/root-router.tsx +++ b/apps/minifront/src/components/root-router.tsx @@ -10,7 +10,6 @@ import { SendForm } from './send/send-form'; import { Receive } from './send/receive'; import { ErrorBoundary } from './shared/error-boundary'; import { SwapLayout } from './swap/layout'; -import { SwapLoader } from './swap/swap-loader'; import { StakingLayout } from './staking/layout'; import { IbcLoader } from './ibc/ibc-loader'; import { IbcLayout } from './ibc/layout'; @@ -56,7 +55,7 @@ export const rootRouter: Router = createHashRouter([ }, { path: PagePath.SWAP, - loader: SwapLoader, + loader: abortLoader, element: , }, { diff --git a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx index b6744056dc..8a9f72eaf0 100644 --- a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx +++ b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx @@ -26,6 +26,8 @@ import BalanceSelector from '../../shared/balance-selector'; import { Amount } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/num/v1/num_pb'; import { useStatus } from '../../../state/status'; import { hasStakingToken } from '../../../fetchers/staking-token'; +import { useStakingTokenMetadata } from '../../../state/shared'; +import { useBalancesResponses, useSwappableAssets } from '../../../state/swap'; const isValidAmount = (amount: string, assetIn?: BalancesResponse) => Number(amount) >= 0 && (!assetIn || !amountMoreThanBalance(assetIn, amount)); @@ -39,7 +41,11 @@ const getKnownZeroValueView = (metadata?: Metadata) => { }); }; -const assetOutBalanceSelector = ({ swap: { balancesResponses, assetIn, assetOut } }: AllSlices) => { +const getAssetOutBalance = ( + balancesResponses: BalancesResponse[] = [], + assetIn?: BalancesResponse, + assetOut?: Metadata, +) => { if (!assetIn || !assetOut) return getKnownZeroValueView(); const match = balancesResponses.find(balance => { @@ -54,17 +60,13 @@ const assetOutBalanceSelector = ({ swap: { balancesResponses, assetIn, assetOut }; const tokenSwapInputSelector = (state: AllSlices) => ({ - swappableAssets: state.swap.swappableAssets, assetIn: state.swap.assetIn, setAssetIn: state.swap.setAssetIn, assetOut: state.swap.assetOut, setAssetOut: state.swap.setAssetOut, amount: state.swap.amount, setAmount: state.swap.setAmount, - balancesResponses: state.swap.balancesResponses, priceHistory: state.swap.priceHistory, - assetOutBalance: assetOutBalanceSelector(state), - hasStakingTokenMeta: state.swap.stakingAssetMetadata, }); /** @@ -76,24 +78,16 @@ const tokenSwapInputSelector = (state: AllSlices) => ({ export const TokenSwapInput = () => { const status = useStatus(); const latestKnownBlockHeight = status.data?.latestKnownBlockHeight ?? 0n; - const { - swappableAssets, - amount, - setAmount, - assetIn, - setAssetIn, - assetOut, - setAssetOut, - balancesResponses, - priceHistory, - assetOutBalance, - hasStakingTokenMeta, - } = useStoreShallow(tokenSwapInputSelector); + const stakingTokenMetadata = useStakingTokenMetadata(); + const balancesResponses = useBalancesResponses(); + const swappableAssets = useSwappableAssets(); + const { amount, setAmount, assetIn, setAssetIn, assetOut, setAssetOut, priceHistory } = + useStoreShallow(tokenSwapInputSelector); // State to manage privacy warning display const [showNonNativeFeeWarning, setShowNonNativeFeeWarning] = useState(false); + const assetOutBalance = getAssetOutBalance(balancesResponses.data, assetIn, assetOut); - // Check if the user has native staking tokens - const stakingToken = hasStakingToken(balancesResponses, hasStakingTokenMeta); + const userHasStakingToken = hasStakingToken(balancesResponses.data, stakingTokenMetadata.data); useEffect(() => { if (!assetIn || !assetOut) return; @@ -131,7 +125,7 @@ export const TokenSwapInput = () => { onChange={e => { if (!isValidAmount(e.target.value, assetIn)) return; setAmount(e.target.value); - setShowNonNativeFeeWarning(Number(e.target.value) > 0 && !stakingToken); + setShowNonNativeFeeWarning(Number(e.target.value) > 0 && !userHasStakingToken); }} />
@@ -144,7 +138,13 @@ export const TokenSwapInput = () => { )}
- + {balancesResponses.data && ( + + )} {assetIn?.balanceView && ( )} @@ -155,7 +155,14 @@ export const TokenSwapInput = () => {
- + {swappableAssets.data && ( + + )} + {assetOut && }
diff --git a/apps/minifront/src/components/swap/swap-loader.ts b/apps/minifront/src/components/swap/swap-loader.ts deleted file mode 100644 index a6b0ab01c5..0000000000 --- a/apps/minifront/src/components/swap/swap-loader.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { LoaderFunction } from 'react-router-dom'; -import { useStore } from '../../state'; -import { abortLoader } from '../../abort-loader'; -import { SwapRecord } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb'; -import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; -import { getSwappableBalancesResponses, isSwappable } from './helpers'; -import { getAllAssets } from '../../fetchers/assets'; -import { getStakingTokenMetadata } from '../../fetchers/registry'; - -export interface UnclaimedSwapsWithMetadata { - swap: SwapRecord; - asset1: Metadata; - asset2: Metadata; -} - -export type SwapLoaderResponse = UnclaimedSwapsWithMetadata[]; - -const getAndSetDefaultAssetBalances = async (swappableAssets: Metadata[]) => { - const balancesResponses = await getSwappableBalancesResponses(); - const stakingTokenAssetMetadata = await getStakingTokenMetadata(); - - // set initial denom in if there is an available balance - if (balancesResponses[0]) { - useStore.getState().swap.setAssetIn(balancesResponses[0]); - useStore.getState().swap.setAssetOut(swappableAssets[0]!); - useStore.getState().swap.setStakingAssetMetadata(stakingTokenAssetMetadata); - } - - return balancesResponses; -}; - -export const SwapLoader: LoaderFunction = async (): Promise => { - await abortLoader(); - const assets = await getAllAssets(); - const swappableAssets = assets.filter(isSwappable); - - const balancesResponses = await getAndSetDefaultAssetBalances(swappableAssets); - useStore.getState().swap.setBalancesResponses(balancesResponses); - useStore.getState().swap.setSwappableAssets(swappableAssets); - - return null; -}; diff --git a/apps/minifront/src/state/swap/index.ts b/apps/minifront/src/state/swap/index.ts index 225a9c5fb4..a09f862f93 100644 --- a/apps/minifront/src/state/swap/index.ts +++ b/apps/minifront/src/state/swap/index.ts @@ -4,7 +4,7 @@ import { } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; import { SwapExecution_Trace } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/dex/v1/dex_pb'; import { BalancesResponse } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/view/v1/view_pb'; -import { AllSlices, SliceCreator } from '..'; +import { AllSlices, SliceCreator, useStore } from '..'; import { DurationOption } from './constants'; import { DutchAuctionSlice, @@ -18,6 +18,52 @@ import { } from './instant-swap'; import { PriceHistorySlice, createPriceHistorySlice } from './price-history'; import { getMetadata } from '@penumbra-zone/getters/value-view'; +import { ZQueryState, createZQuery } from '@penumbra-zone/zquery'; +import { getSwappableBalancesResponses, isSwappable } from '../../components/swap/helpers'; +import { getAllAssets } from '../../fetchers/assets'; + +export const { balancesResponses, useBalancesResponses } = createZQuery({ + name: 'balancesResponses', + fetch: async () => { + const balancesResponses = await getSwappableBalancesResponses(); + + if (balancesResponses[0] && !useStore.getState().swap.assetIn) { + useStore.getState().swap.setAssetIn(balancesResponses[0]); + } + + return balancesResponses; + }, + getUseStore: () => useStore, + get: state => state.swap.balancesResponses, + set: setter => { + const newState = setter(useStore.getState().swap.balancesResponses); + useStore.setState(state => { + state.swap.balancesResponses = newState; + }); + }, +}); + +export const { swappableAssets, useSwappableAssets } = createZQuery({ + name: 'swappableAssets', + fetch: async () => { + const allAssets = await getAllAssets(); + const swappableAssets = allAssets.filter(isSwappable); + + if (swappableAssets[0] && !useStore.getState().swap.assetOut) { + useStore.getState().swap.setAssetOut(swappableAssets[0]); + } + + return swappableAssets; + }, + getUseStore: () => useStore, + get: state => state.swap.swappableAssets, + set: setter => { + const newState = setter(useStore.getState().swap.swappableAssets); + useStore.setState(state => { + state.swap.swappableAssets = newState; + }); + }, +}); export interface SimulateSwapResult { metadataByAssetId: Record; @@ -28,9 +74,6 @@ export interface SimulateSwapResult { } interface Actions { - setBalancesResponses: (balancesResponses: BalancesResponse[]) => void; - setStakingAssetMetadata: (metadata: Metadata) => void; - setSwappableAssets: (assets: Metadata[]) => void; setAssetIn: (asset: BalancesResponse) => void; setAmount: (amount: string) => void; setAssetOut: (metadata: Metadata) => void; @@ -39,9 +82,8 @@ interface Actions { } interface State { - balancesResponses: BalancesResponse[]; - stakingAssetMetadata: Metadata; - swappableAssets: Metadata[]; + balancesResponses: ZQueryState; + swappableAssets: ZQueryState; assetIn?: BalancesResponse; amount: string; assetOut?: Metadata; @@ -57,11 +99,10 @@ interface Subslices { const INITIAL_STATE: State = { amount: '', - swappableAssets: [], - balancesResponses: [], + swappableAssets, + balancesResponses, duration: 'instant', txInProgress: false, - stakingAssetMetadata: new Metadata(), }; export type SwapSlice = Actions & State & Subslices; @@ -90,21 +131,6 @@ export const createSwapSlice = (): SliceCreator => (set, get, store) dutchAuction: createDutchAuctionSlice()(set, get, store), instantSwap: createInstantSwapSlice()(set, get, store), priceHistory: createPriceHistorySlice()(set, get, store), - setBalancesResponses: balancesResponses => { - set(state => { - state.swap.balancesResponses = balancesResponses; - }); - }, - setStakingAssetMetadata: stakingAssetMetadata => { - set(state => { - state.swap.stakingAssetMetadata = stakingAssetMetadata; - }); - }, - setSwappableAssets: swappableAssets => { - set(state => { - state.swap.swappableAssets = swappableAssets; - }); - }, setAssetIn: asset => { get().swap.resetSubslices(); set(({ swap }) => { @@ -112,7 +138,7 @@ export const createSwapSlice = (): SliceCreator => (set, get, store) if (balancesResponseAndMetadataAreSameAsset(asset, get().swap.assetOut)) { swap.assetOut = getFirstMetadataNotMatchingBalancesResponse( - get().swap.swappableAssets, + get().swap.swappableAssets.data ?? [], asset, ); } @@ -125,7 +151,7 @@ export const createSwapSlice = (): SliceCreator => (set, get, store) if (balancesResponseAndMetadataAreSameAsset(get().swap.assetIn, metadata)) { swap.assetIn = getFirstBalancesResponseNotMatchingMetadata( - get().swap.balancesResponses, + get().swap.balancesResponses.data ?? [], metadata, ); } From 447cbb86bcd33892808fca21e7c18d9008010102 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Tue, 18 Jun 2024 16:12:13 -0700 Subject: [PATCH 3/9] Add a fade transition --- .../swap/swap-form/token-swap-input.tsx | 66 +++++++++++-------- packages/ui/components/ui/fade-in.tsx | 15 +++++ 2 files changed, 52 insertions(+), 29 deletions(-) create mode 100644 packages/ui/components/ui/fade-in.tsx diff --git a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx index 8a9f72eaf0..bf33fd013b 100644 --- a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx +++ b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx @@ -28,6 +28,7 @@ import { useStatus } from '../../../state/status'; import { hasStakingToken } from '../../../fetchers/staking-token'; import { useStakingTokenMetadata } from '../../../state/shared'; import { useBalancesResponses, useSwappableAssets } from '../../../state/swap'; +import { FadeIn } from '@repo/ui/components/ui/fade-in'; const isValidAmount = (amount: string, assetIn?: BalancesResponse) => Number(amount) >= 0 && (!assetIn || !amountMoreThanBalance(assetIn, amount)); @@ -128,7 +129,7 @@ export const TokenSwapInput = () => { setShowNonNativeFeeWarning(Number(e.target.value) > 0 && !userHasStakingToken); }} /> -
+
{assetIn && (
@@ -137,34 +138,41 @@ export const TokenSwapInput = () => {
)} -
- {balancesResponses.data && ( - - )} - {assetIn?.balanceView && ( - - )} -
- -
- -
- -
- {swappableAssets.data && ( - - )} - - {assetOut && } -
+ +
+
+ {balancesResponses.data && ( + + )} + {assetIn?.balanceView && ( + + )} +
+ +
+ +
+ +
+ {swappableAssets.data && ( + + )} + + {assetOut && } +
+
+
{priceHistory.startMetadata && priceHistory.endMetadata && priceHistory.candles.length ? ( = { + layout: true, + initial: { opacity: 0 }, + animate: { opacity: 1 }, + exit: { opacity: 0 }, +}; + +export const FadeIn = ({ condition, children }: PropsWithChildren<{ condition: boolean }>) => ( + + {condition && {children}} + +); From e371b9d2b0c9d678f6b7033948d82813a7d9c704 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Wed, 19 Jun 2024 13:03:21 -0700 Subject: [PATCH 4/9] Add docs for FadeIn --- packages/ui/components/ui/fade-in.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/ui/components/ui/fade-in.tsx b/packages/ui/components/ui/fade-in.tsx index 5c1db4af59..06a997c5f2 100644 --- a/packages/ui/components/ui/fade-in.tsx +++ b/packages/ui/components/ui/fade-in.tsx @@ -1,6 +1,9 @@ import { AnimatePresence, motion } from 'framer-motion'; import { ComponentProps, PropsWithChildren } from 'react'; +/** + * Use a constant for props, since they'll never change. + */ const MOTION_DIV_PROPS: ComponentProps = { layout: true, initial: { opacity: 0 }, @@ -8,6 +11,24 @@ const MOTION_DIV_PROPS: ComponentProps = { exit: { opacity: 0 }, }; +/** + * A simple wrapper around other elements that fades them in when they are + * rendered. + * + * Note that this wraps those elements in a `
`, so any (e.g., flex box) + * styling should be applied to elements _inside_ of ``. + * + * @example + * ```tsx + * + *
+ * + * + * + *
+ *
+ * ``` + */ export const FadeIn = ({ condition, children }: PropsWithChildren<{ condition: boolean }>) => ( {condition && {children}} From 4a3bec9f962b841decb5a59fb6d8c4a79d4c26db Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Wed, 19 Jun 2024 13:35:28 -0700 Subject: [PATCH 5/9] Fix tests --- apps/minifront/src/state/swap/index.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/minifront/src/state/swap/index.test.ts b/apps/minifront/src/state/swap/index.test.ts index e9e059ad90..0f4aff4c3f 100644 --- a/apps/minifront/src/state/swap/index.test.ts +++ b/apps/minifront/src/state/swap/index.test.ts @@ -102,8 +102,8 @@ describe('Swap Slice', () => { }); useStore.setState(state => { - state.swap.swappableAssets = [metadata1, metadata2]; - state.swap.balancesResponses = [ + state.swap.swappableAssets.data = [metadata1, metadata2]; + state.swap.balancesResponses.data = [ balancesResponseWithMetadata1, balancesResponseWithMetadata2, ]; @@ -149,8 +149,8 @@ describe('Swap Slice', () => { }); useStore.setState(state => { - state.swap.swappableAssets = [metadata1, metadata2]; - state.swap.balancesResponses = [ + state.swap.swappableAssets.data = [metadata1, metadata2]; + state.swap.balancesResponses.data = [ balancesResponseWithMetadata1, balancesResponseWithMetadata2, ]; From facf73a746e4e138c1946b0840303f3adab382e4 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Wed, 19 Jun 2024 13:41:50 -0700 Subject: [PATCH 6/9] Remove unnecessary class change --- .../src/components/swap/swap-form/token-swap-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx index bf33fd013b..b6acf64f93 100644 --- a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx +++ b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx @@ -129,7 +129,7 @@ export const TokenSwapInput = () => { setShowNonNativeFeeWarning(Number(e.target.value) > 0 && !userHasStakingToken); }} /> -
+
{assetIn && (
From e18dcae454cf4afd96742864f479889fc9a04838 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Wed, 19 Jun 2024 15:21:44 -0700 Subject: [PATCH 7/9] Fix tests --- .../staking-actions/index.test.tsx | 14 ++++++-------- apps/minifront/src/state/swap/index.test.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/apps/minifront/src/components/staking/account/delegation-value-view/staking-actions/index.test.tsx b/apps/minifront/src/components/staking/account/delegation-value-view/staking-actions/index.test.tsx index 754fe58b8d..06f3be14f7 100644 --- a/apps/minifront/src/components/staking/account/delegation-value-view/staking-actions/index.test.tsx +++ b/apps/minifront/src/components/staking/account/delegation-value-view/staking-actions/index.test.tsx @@ -25,12 +25,10 @@ const zeroBalance = new ValueView({ const validatorInfo = new ValidatorInfo({ validator: {} }); -let MOCK_STAKING_TOKENS_AND_FILTER: - | { - unstakedTokensByAccount: Map; - accountSwitcherFilter: number[]; - } - | undefined; +let MOCK_STAKING_TOKENS_AND_FILTER: { + unstakedTokensByAccount: Map; + accountSwitcherFilter: number[]; +} | null = vi.hoisted(() => null); vi.mock('../../../../../state/staking', async () => ({ ...(await vi.importActual('../../../../../state/staking')), @@ -53,7 +51,7 @@ vi.mock('../../../../../utils/use-store-shallow', async () => ({ describe('', () => { beforeEach(() => { - MOCK_STAKING_TOKENS_AND_FILTER = undefined; + MOCK_STAKING_TOKENS_AND_FILTER = null; }); it('renders an enabled Delegate button there is a non-zero balance of unstaked tokens', () => { @@ -91,7 +89,7 @@ describe('', () => { }); it('renders a disabled Delegate button when unstaked tokens are undefined', () => { - MOCK_STAKING_TOKENS_AND_FILTER = undefined; + MOCK_STAKING_TOKENS_AND_FILTER = null; const { getByText } = render( , diff --git a/apps/minifront/src/state/swap/index.test.ts b/apps/minifront/src/state/swap/index.test.ts index 0f4aff4c3f..9ac1d94ea9 100644 --- a/apps/minifront/src/state/swap/index.test.ts +++ b/apps/minifront/src/state/swap/index.test.ts @@ -48,8 +48,12 @@ describe('Swap Slice', () => { expect(useStore.getState().swap.amount).toBe(''); expect(useStore.getState().swap.assetIn).toBeUndefined(); expect(useStore.getState().swap.assetOut).toBeUndefined(); - expect(useStore.getState().swap.swappableAssets).toEqual([]); - expect(useStore.getState().swap.balancesResponses).toEqual([]); + expect(useStore.getState().swap.swappableAssets).toEqual( + expect.objectContaining({ data: undefined, error: undefined, loading: false }), + ); + expect(useStore.getState().swap.balancesResponses).toEqual( + expect.objectContaining({ data: undefined, error: undefined, loading: false }), + ); expect(useStore.getState().swap.duration).toBe('instant'); expect(useStore.getState().swap.txInProgress).toBe(false); }); From 8c45d6686f1a5421290487ad0393c7192f0add86 Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Thu, 20 Jun 2024 13:22:38 -0700 Subject: [PATCH 8/9] Render errors, if any --- .../src/components/swap/swap-form/token-swap-input.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx index b6acf64f93..18116e4ff1 100644 --- a/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx +++ b/apps/minifront/src/components/swap/swap-form/token-swap-input.tsx @@ -138,6 +138,13 @@ export const TokenSwapInput = () => {
)} + +
+ {balancesResponses.error instanceof Error && balancesResponses.error.toString()} + {swappableAssets.error instanceof Error && swappableAssets.error.toString()} +
+
+
From 8bc397d27e9077f041b41b4949a2475f5792dcbf Mon Sep 17 00:00:00 2001 From: Jesse Pinho Date: Wed, 19 Jun 2024 16:10:58 -0700 Subject: [PATCH 9/9] Make getAssetId optional --- apps/minifront/src/state/ibc-out.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/minifront/src/state/ibc-out.ts b/apps/minifront/src/state/ibc-out.ts index ff76528616..13c801d4d6 100644 --- a/apps/minifront/src/state/ibc-out.ts +++ b/apps/minifront/src/state/ibc-out.ts @@ -232,7 +232,7 @@ export const filterBalancesPerChain = ( registryAssets: Metadata[], stakingTokenMetadata?: Metadata, ): BalancesResponse[] => { - const penumbraAssetId = getAssetId(stakingTokenMetadata); + const penumbraAssetId = getAssetId.optional()(stakingTokenMetadata); const assetsWithMatchingChannel = registryAssets .filter(a => { const match = assetPatterns.ibc.capture(a.base); @@ -244,6 +244,6 @@ export const filterBalancesPerChain = ( const assetIdsToCheck = [penumbraAssetId, ...assetsWithMatchingChannel]; return allBalances.filter(({ balanceView }) => { - return assetIdsToCheck.some(assetId => assetId.equals(getAssetIdFromValueView(balanceView))); + return assetIdsToCheck.some(assetId => assetId?.equals(getAssetIdFromValueView(balanceView))); }); };