diff --git a/apps/minifront/src/components/swap/swap-loader.ts b/apps/minifront/src/components/swap/swap-loader.ts index a6b0ab01c5..a8ea9fe70e 100644 --- a/apps/minifront/src/components/swap/swap-loader.ts +++ b/apps/minifront/src/components/swap/swap-loader.ts @@ -5,7 +5,6 @@ import { SwapRecord } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/vie 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; @@ -17,13 +16,11 @@ 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; @@ -34,8 +31,6 @@ export const SwapLoader: LoaderFunction = async (): Promise => { 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/index.ts b/apps/minifront/src/state/index.ts index d1c840afe6..06fa10a655 100644 --- a/apps/minifront/src/state/index.ts +++ b/apps/minifront/src/state/index.ts @@ -39,19 +39,41 @@ export type SliceCreator = StateCreator< SliceInterface >; -export const initializeStore = () => { - return immer((setState, getState: () => AllSlices, store) => ({ - balances: createBalancesSlice()(setState, getState, store), - ibcIn: createIbcInSlice()(setState, getState, store), - ibcOut: createIbcOutSlice()(setState, getState, store), - send: createSendSlice()(setState, getState, store), - shared: createSharedSlice()(setState, getState, store), - staking: createStakingSlice()(setState, getState, store), - status: createStatusSlice()(setState, getState, store), - swap: createSwapSlice()(setState, getState, store), - transactions: createTransactionsSlice()(setState, getState, store), - unclaimedSwaps: createUnclaimedSwapsSlice()(setState, getState, store), - })); -}; +type Middleware = StateCreator; + +const SLICE_MIDDLEWARES: Middleware[] = [ + // (set, get, store) => , +]; + +const sliceMiddleware = + (f: Middleware): Middleware => + (set, get, store) => { + // return SLICE_MIDDLEWARES.reduce((prev, curr) => f(set, get, store); + const setState = store.setState; + store.setState = (...args) => { + const before = store.getState(); + setState(...args); + const after = store.getState(); + + // if (!before.swap.assetIn && !before.shared.stakingTokenMetadata.data && after.shared) + }; + return f(set, get, store); + }; + +export const initializeStore = () => + sliceMiddleware( + immer((setState, getState: () => AllSlices, store) => ({ + balances: createBalancesSlice()(setState, getState, store), + ibcIn: createIbcInSlice()(setState, getState, store), + ibcOut: createIbcOutSlice()(setState, getState, store), + send: createSendSlice()(setState, getState, store), + shared: createSharedSlice()(setState, getState, store), + staking: createStakingSlice()(setState, getState, store), + status: createStatusSlice()(setState, getState, store), + swap: createSwapSlice()(setState, getState, store), + transactions: createTransactionsSlice()(setState, getState, store), + unclaimedSwaps: createUnclaimedSwapsSlice()(setState, getState, store), + })), + ); export const useStore = create()(initializeStore()); diff --git a/apps/minifront/src/state/shared.ts b/apps/minifront/src/state/shared.ts index 71626eb393..e6aed281c2 100644 --- a/apps/minifront/src/state/shared.ts +++ b/apps/minifront/src/state/shared.ts @@ -2,6 +2,20 @@ import { ZQueryState, createZQuery } from '@penumbra-zone/zquery'; import { SliceCreator, useStore } from '.'; import { getStakingTokenMetadata } from '../fetchers/registry'; import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; +import { getAllAssets } from '../fetchers/assets'; + +export const { assets, useAssets } = createZQuery({ + name: 'assets', + fetch: getAllAssets, + getUseStore: () => useStore, + get: state => state.shared.assets, + set: setter => { + const newState = setter(useStore.getState().shared.assets); + useStore.setState(state => { + state.shared.assets = newState; + }); + }, +}); export const { stakingTokenMetadata, useStakingTokenMetadata } = createZQuery({ name: 'stakingTokenMetadata', @@ -17,9 +31,11 @@ export const { stakingTokenMetadata, useStakingTokenMetadata } = createZQuery({ }); export interface SharedSlice { + assets: ZQueryState; stakingTokenMetadata: ZQueryState; } export const createSharedSlice = (): SliceCreator => () => ({ + assets, stakingTokenMetadata, }); diff --git a/apps/minifront/src/state/swap/index.ts b/apps/minifront/src/state/swap/index.ts index 225a9c5fb4..f5f4eb9f09 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,35 @@ 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: getSwappableBalancesResponses, + 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: () => getAllAssets().then(assets => assets.filter(isSwappable)), + getUseStore: () => useStore, + get: state => state.swap.swappableAssets, + set: setter => { + const newState = setter(useStore.getState().swap.balancesResponses); + useStore.setState(state => { + state.swap.balancesResponses = newState; + }); + }, +}); export interface SimulateSwapResult { metadataByAssetId: Record; @@ -28,9 +57,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 +65,8 @@ interface Actions { } interface State { - balancesResponses: BalancesResponse[]; - stakingAssetMetadata: Metadata; - swappableAssets: Metadata[]; + balancesResponses: ZQueryState; + swappableAssets: ZQueryState; assetIn?: BalancesResponse; amount: string; assetOut?: Metadata; @@ -57,11 +82,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 +114,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 +121,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 +134,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, ); }