/ src / store / protocolDataSlice.ts
protocolDataSlice.ts
 1  import { providers, utils } from 'ethers';
 2  import { permitByChainAndToken } from 'src/ui-config/permitConfig';
 3  import {
 4    availableMarkets,
 5    getNetworkConfig,
 6    getProvider,
 7    marketsData,
 8  } from 'src/utils/marketsAndNetworksConfig';
 9  import { StateCreator } from 'zustand';
10  
11  import { CustomMarket, MarketDataType } from '../ui-config/marketsConfig';
12  import { NetworkConfig } from '../ui-config/networksConfig';
13  import { RootStore } from './root';
14  import { setQueryParameter } from './utils/queryParams';
15  
16  type TypePermitParams = {
17    reserveAddress: string;
18    isWrappedBaseAsset: boolean;
19  };
20  
21  export interface ProtocolDataSlice {
22    currentMarket: CustomMarket;
23    currentMarketData: MarketDataType;
24    currentChainId: number;
25    currentNetworkConfig: NetworkConfig;
26    jsonRpcProvider: (chainId?: number) => providers.Provider;
27    setCurrentMarket: (market: CustomMarket, omitQueryParameterUpdate?: boolean) => void;
28    tryPermit: ({ reserveAddress, isWrappedBaseAsset }: TypePermitParams) => boolean;
29  }
30  
31  export const createProtocolDataSlice: StateCreator<
32    RootStore,
33    [['zustand/subscribeWithSelector', never], ['zustand/devtools', never]],
34    [],
35    ProtocolDataSlice
36  > = (set, get) => {
37    const initialMarket = availableMarkets[0];
38    const initialMarketData = marketsData[initialMarket];
39    return {
40      currentMarket: initialMarket,
41      currentMarketData: marketsData[initialMarket],
42      currentChainId: initialMarketData.chainId,
43      currentNetworkConfig: getNetworkConfig(initialMarketData.chainId),
44      jsonRpcProvider: (chainId) => getProvider(chainId ?? get().currentChainId),
45      setCurrentMarket: (market, omitQueryParameterUpdate) => {
46        if (!availableMarkets.includes(market as CustomMarket)) return;
47        const nextMarketData = marketsData[market];
48        localStorage.setItem('selectedMarket', market);
49        if (!omitQueryParameterUpdate) {
50          setQueryParameter('marketName', market);
51        }
52        set({
53          currentMarket: market,
54          currentMarketData: nextMarketData,
55          currentChainId: nextMarketData.chainId,
56          currentNetworkConfig: getNetworkConfig(nextMarketData.chainId),
57        });
58      },
59      tryPermit: ({ reserveAddress, isWrappedBaseAsset }: TypePermitParams) => {
60        const currentNetworkConfig = get().currentNetworkConfig;
61        const currentMarketData = get().currentMarketData;
62        // current chain id, or underlying chain id for fork networks
63        const underlyingChainId = currentNetworkConfig.isFork
64          ? currentNetworkConfig.underlyingChainId
65          : currentMarketData.chainId;
66        // enable permit for all v3 test network assets (except WrappedBaseAssets) or v3 production assets included in permitConfig)
67        const testnetPermitEnabled = Boolean(
68          currentMarketData.v3 &&
69            currentNetworkConfig.isTestnet &&
70            !currentMarketData.permitDisabled &&
71            !isWrappedBaseAsset
72        );
73        const productionPermitEnabled = Boolean(
74          currentMarketData.v3 &&
75            underlyingChainId &&
76            permitByChainAndToken[underlyingChainId]?.[utils.getAddress(reserveAddress).toLowerCase()]
77        );
78        return testnetPermitEnabled || productionPermitEnabled;
79      },
80    };
81  };