import { createContext, useContext, useState, useEffect } from "react"; import useSWR, { mutate } from "swr"; const BRIDGE_IN = "Bridge-In"; const BRIDGE_OUT = "Bridge-Out"; const DEX_ACTION = "DEX"; const STAKE_ACTION = "Stake"; const BOND_ACTION = "Bond"; const DEX_ACTION_SWAP = "Swap"; const DEX_ACTION_ADD = "Add Liquidity"; const STAKE_ACTION_STAKE = "Stake"; const UNSTAKE_ACTION_STAKE = "Unstake"; const WRAP_ACTION_STAKE = "Wrap"; const UNWRAP_ACTION_STAKE = "Unwrap"; // TODO: add bond later const POSSIBLE_HISTORY_TYPES = [BRIDGE_IN, BRIDGE_OUT, DEX_ACTION, STAKE_ACTION]; const DEFAULT_HISTORY_TYPES = [BRIDGE_IN, BRIDGE_OUT]; const HISTORY_PREFIX = "history"; const PENDING_HISTORY_PREIFX = "pending"; const LocalStorageContext = createContext(); export const useLocalStorage = () => useContext(LocalStorageContext); const CONSTANTS = { possibleHistoryTypes: POSSIBLE_HISTORY_TYPES, defaultHistoryTypes: DEFAULT_HISTORY_TYPES, historyPrefix: HISTORY_PREFIX, pendingHistoryPrefix: PENDING_HISTORY_PREIFX, bridgeIn: { key: BRIDGE_IN, name: BRIDGE_IN }, bridgeOut: { key: BRIDGE_OUT, name: BRIDGE_OUT }, dex: { key: DEX_ACTION, swap: DEX_ACTION_SWAP, add: DEX_ACTION_ADD }, stake: { key: STAKE_ACTION, stake: STAKE_ACTION_STAKE, unstake: UNSTAKE_ACTION_STAKE, wrap: WRAP_ACTION_STAKE, unwrap: UNWRAP_ACTION_STAKE, }, }; export const LocalStorageProvider = ({ children }) => { const getStorageKey = (chainId, address, target) => { return `${chainId}:${address}:${target}`; } const useStorageValue = (chainId, address, target, defaultValue) => { return useSWR( chainId && address ? ["local", chainId, address, target] : null, ([_, chainId, address, target]) => { const key = getStorageKey(chainId, address, target); const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : defaultValue; }, { revalidateOnFocus: false, fallbackData: defaultValue } ); }; const setStorageValue = async (chainId, address, target, value) => { const key = getStorageKey(chainId, address, target); localStorage.setItem(key, JSON.stringify(value)); await mutate(["local", chainId, address, target]); } const clearPendingHistory = async (chainId, address, target) => { const key = getStorageKey(chainId, address, PENDING_HISTORY_PREIFX); const stored = localStorage.getItem(key); if (!stored) return const pendingValues = JSON.parse(stored); if (target in pendingValues) { delete pendingValues[target]; localStorage.setItem(key, JSON.stringify(pendingValues)); await mutate(["local", chainId, address, PENDING_HISTORY_PREIFX]); } } const tryStoreInHistory = async (chainId, address, target, txHash, name) => { const historyKey = getStorageKey(chainId, address, HISTORY_PREFIX); const storedHistoryTypes = localStorage.getItem(historyKey); const historyTypes = storedHistoryTypes ? JSON.parse(storedHistoryTypes) : []; if (!historyTypes.includes(target)) return; const key = getStorageKey(chainId, address, target); const stored = localStorage.getItem(key); const values = stored ? JSON.parse(stored) : []; const value = { name, txHash, submitted: Date.now() }; const newValues = [value, ...values]; localStorage.setItem(key, JSON.stringify(newValues)); const pendingKey = getStorageKey(chainId, address, PENDING_HISTORY_PREIFX); const pendingItems = localStorage.getItem(pendingKey); const pendingValues = pendingItems ? JSON.parse(pendingItems) : {}; const currentCount = pendingValues[target] || 0; pendingValues[target] = currentCount + 1; localStorage.setItem(pendingKey, JSON.stringify(pendingValues)); await mutate(["local", chainId, address, PENDING_HISTORY_PREIFX]); } return ( {children} ) }