From 094773c5e6cb4a8d10ba6a1ec607ad65f27b5ac5 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Tue, 9 Jul 2024 13:12:10 -0500 Subject: [PATCH 01/21] matomo race conditions (#613) --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index f1b85a2e..bd43f768 100644 --- a/public/index.html +++ b/public/index.html @@ -58,8 +58,8 @@ OD | App - - + + From 4629318d50029d71c34e748d291e95d65d423f81 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:08:08 -0500 Subject: [PATCH 02/21] typo fix (#618) --- src/containers/Analytics/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/containers/Analytics/index.tsx b/src/containers/Analytics/index.tsx index 5a46034b..1cec3dbb 100644 --- a/src/containers/Analytics/index.tsx +++ b/src/containers/Analytics/index.tsx @@ -167,7 +167,7 @@ const Analytics = () => { title: 'Surplus in Treasury', value: surplusInTreasury, description: - "Total HAI accrued by the system's stability fees. It's stored in the Stability Fee Treasury accountance", + "Total OD accrued by the system's stability fees. It's stored in the Stability Fee Treasury accountance", } const liquidityUniswap = { From 75431ce007185c6bc0d1cc11486be5d01edc96d6 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Tue, 9 Jul 2024 22:40:28 -0500 Subject: [PATCH 03/21] Issue #606: Vaults explorer page (#611) * explore page * explore page more changes * fix explore page * more explore page fixes * revert yarn lock * explore table reorder, external link * add risk status, fix bugs --- src/App.tsx | 3 + src/containers/Explore/ExploreTable.tsx | 352 ++++++++++++++++++++++++ src/containers/Explore/index.css | 38 +++ src/containers/Explore/index.tsx | 162 +++++++++++ src/hooks/useVaultSubgraph.ts | 15 +- src/utils/helper.ts | 31 ++- 6 files changed, 598 insertions(+), 3 deletions(-) create mode 100644 src/containers/Explore/ExploreTable.tsx create mode 100644 src/containers/Explore/index.css create mode 100644 src/containers/Explore/index.tsx diff --git a/src/App.tsx b/src/App.tsx index b79584cc..6a585141 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -30,6 +30,8 @@ import { Fuul } from '@fuul/sdk' import EarnDetails from './containers/Earn/EarnDetails' import Marketplace from './containers/Marketplace' import ScreenLoader from '~/components/Modals/ScreenLoader' +import Explore from '~/containers/Explore' + import 'react-loading-skeleton/dist/skeleton.css' const ToastContainer = lazy(() => import('react-toastify').then((module) => ({ default: module.ToastContainer }))) @@ -101,6 +103,7 @@ const App = () => { + { + return parseFloat(value.replace(/,/g, '').replace(' OD', '')) +} + +const columnHelper = createColumnHelper() +const columns: ColumnDef[] = [ + columnHelper.accessor('id', { + header: () => 'ID', + cell: (info) => info.getValue(), + sortingFn: 'alphanumeric', + enableSorting: true, + }), + columnHelper.accessor('image', { + header: () => '', + cell: (info) => { + const image = info.row.original.image + const vaultID = info.row.original.id + return image ? ( + + + + ) : null + }, + enableSorting: false, + }), + columnHelper.accessor('collateralAmount', { + header: () => 'Collateral Amount', + cell: (info) => info.getValue().toLocaleString(), + sortingFn: (rowA, rowB) => { + const a = rowA.getValue('collateralAmount') + const b = rowB.getValue('collateralAmount') + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = row.getValue(columnId) + return value.toString().includes(filterValue) + }, + }), + columnHelper.accessor('collateral', { + header: () => 'Collateral', + cell: (info) => info.getValue(), + sortingFn: 'alphanumeric', + enableSorting: true, + }), + columnHelper.accessor('debtAmount', { + header: () => 'Debt Amount', + cell: (info) => info.getValue(), + sortingFn: (rowA, rowB) => { + const a = parseDebtAmount(rowA.getValue('debtAmount')) + const b = parseDebtAmount(rowB.getValue('debtAmount')) + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = parseDebtAmount(row.getValue(columnId)) + return value.toString().includes(filterValue) + }, + }), + columnHelper.accessor('riskStatus', { + header: () => 'Risk Status', + cell: (info) => info.getValue().toLocaleString(), + sortingFn: (rowA, rowB) => { + const a = riskStatusMapping[rowA.getValue('riskStatus')] || 1 + const b = riskStatusMapping[rowB.getValue('riskStatus')] || 1 + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = row.getValue(columnId) + return value.includes(filterValue) + }, + }), + columnHelper.accessor('actions', { + header: '', + cell: (info) => { + return ( + + + + ) + }, + enableSorting: false, + }), +] + +const ExploreTable = ({ data }: { data: Vault[] }) => { + const [sorting, setSorting] = useState([]) + const [globalFilter, setGlobalFilter] = useState('') + + const table = useReactTable({ + data: data, + columns, + state: { + sorting, + globalFilter, + }, + onSortingChange: setSorting, + onGlobalFilterChange: setGlobalFilter, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + }) + + return ( + + setGlobalFilter(String(e.target.value))} + placeholder="Search all columns..." + style={{ marginBottom: '10px', padding: '8px', width: '100%', fontFamily: 'Barlow' }} + /> + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => ( + + ))} + + ))} + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => { + const header = cell.column.columnDef.header + let headerText = '' + + if (typeof header === 'function') { + // @ts-ignore + const renderedHeader = header(cell.getContext()) + if (typeof renderedHeader === 'string') { + headerText = renderedHeader + } else if ( + typeof renderedHeader === 'object' && + renderedHeader.props && + renderedHeader.props.children + ) { + headerText = renderedHeader.props.children + } + } else { + headerText = header ? header.toString() : '' + } + + return ( + + ) + })} + + ))} + +
+ {header.isPlaceholder ? null : ( + + {flexRender(header.column.columnDef.header, header.getContext())} + {header.column.getCanSort() ? ( + header.column.getIsSorted() ? ( + header.column.getIsSorted() === 'asc' ? ( + + ) : ( + + ) + ) : ( +  ⇅ + ) + ) : null} + + )} +
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+
+ ) +} + +export default ExploreTable + +const ArrowUpAndDownIcon = styled.span` + font-size: 15px; + padding-bottom: 4px; +` + +const StyledArrow = styled.div` + padding-left: 4px; +` + +const SortableHeader = styled.div` + display: flex; + align-items: center; + justify-content: start; + cursor: pointer; + font-family: 'Open Sans', sans-serif; + font-size: ${(props) => props.theme.font.xSmall}; +` + +const TableContainer = styled.div` + overflow-x: auto; + table { + width: 100%; + border-collapse: collapse; + min-width: 600px; + padding: 20px; + background-color: rgba(255, 255, 255, 0); + backdrop-filter: blur(10px); + } + th, + td { + padding: 8px 0px; + text-align: left; + } + + th { + background-color: #fff; + border-top: 2px solid #000; + border-bottom: 2px solid #000; + } + + tr { + margin-bottom: 20px; + } + + tr:not(:last-child) td { + border-bottom: 1px solid #ddd; + } + + @media (max-width: 768px) { + table { + min-width: 100%; + display: block; + overflow-x: auto; + } + + thead { + display: none; + } + + tbody, + td { + display: block; + width: 100%; + box-sizing: border-box; + } + + tr { + display: flex; + flex-direction: column; + margin-bottom: 20px; + border-bottom: 4px solid #ddd; + } + + td { + display: flex; + justify-content: space-between; + padding: 10px; + } + + td::before { + display: flex; + content: attr(data-label); + left: 10px; + white-space: nowrap; + font-weight: bold; + text-align: left; + } + } +` + +const SVGContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 139px; + height: 139px; + position: relative; + margin: 20px 10px 20px 10px; + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.3), 0 12px 40px 0 rgba(0, 0, 0, 0.25); + + @media (max-width: 768px) { + width: 294px; + height: 294px; + justify-content: center; + margin-left: auto; + margin-right: auto; + } +` + +const SvgWrapper = styled.div` + transform: scale(0.33); + border-radius: 10px; + + @media (max-width: 768px) { + transform: scale(0.7); + } +` + +const ButtonFloat = styled.div` + position: relative; + top: 0; + right: 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + gap: 10px; + border-radius: 5px; + z-index: 2; + button { + margin: 5px; + padding: 5px; + } +` diff --git a/src/containers/Explore/index.css b/src/containers/Explore/index.css new file mode 100644 index 00000000..3978e6d9 --- /dev/null +++ b/src/containers/Explore/index.css @@ -0,0 +1,38 @@ +html { + font-family: 'Open Sans', sans-serif; + font-size: 18px; +} + +table { + width: 100%; + background-color: #fff; + border-radius: 4px; + +} + +th { + padding: 20px; + text-align: left; + font-family: 'Barlow', sans-serif; + text-transform: uppercase; + border-bottom: 1px solid #b6c7d3cc; + white-space: nowrap; + + &:first-child { + /* width: 150px; */ + } + + &:not(:first-child) { + /* text-align: right; */ + } +} + +td { + padding: 20px; + text-transform: capitalize; + text-decoration: none; + + &:not(:first-child) { + /* text-align: right; */ + } +} diff --git a/src/containers/Explore/index.tsx b/src/containers/Explore/index.tsx new file mode 100644 index 00000000..f8d64744 --- /dev/null +++ b/src/containers/Explore/index.tsx @@ -0,0 +1,162 @@ +import styled from 'styled-components' +import { useState, useEffect } from 'react' +// @ts-ignore +import { generateSvg } from '@opendollar/svg-generator' +import ExploreTable from './ExploreTable' +import { ethers } from 'ethers' +import { + parseRay, + formatDataNumber, + multiplyRates, + transformToAnnualRate, + calculateRiskStatusText, + ratioChecker, + parseFormattedNumber, +} from '~/utils' +import { AllVaults, useVaultSubgraph } from '~/hooks/useVaultSubgraph' +import useAnalyticsData from '~/hooks/useAnalyticsData' +import useGeb from '~/hooks/useGeb' + +const Explore: React.FC = () => { + const [isLoading, setIsLoading] = useState(true) + const [tableData, setTableData] = useState([]) + const allVaults: AllVaults = useVaultSubgraph() + const geb = useGeb() + const analyticsData = useAnalyticsData() + + const parseNumber = (value: string): number => { + return parseFloat(value.replace(/,/g, '')) + } + + const getSafeData = async () => { + setIsLoading(true) + const tableRows = [] + + if (!allVaults?.vaults || !analyticsData?.tokenAnalyticsData) return + + for (const vault of allVaults.vaults) { + try { + const estimatedValue = `${( + +ethers.utils.formatUnits(vault.collateral) * + +ethers.utils.formatUnits(analyticsData.tokenAnalyticsData[vault.collateralType].currentPrice) + ).toFixed(2)}` + + const stabilityFee = transformToAnnualRate( + multiplyRates( + analyticsData.tokenAnalyticsData[vault.collateralType].stabilityFee.toString(), + analyticsData.redemptionRate?.toString() + ) || '0', + 27 + ) + + const formattedDebt = parseFormattedNumber(formatDataNumber(vault.debt)) + let cratio = 0 + if (formattedDebt !== 0) { + cratio = (+estimatedValue / formattedDebt) * 100 + } + + let correctCollateralizationRatio + if (Number(cratio) > 0) { + correctCollateralizationRatio = Number(cratio) + } else if (Number(cratio) === 0 && parseFormattedNumber(formatDataNumber(vault.collateral)) > 0) { + correctCollateralizationRatio = '∞' + } else if (Number(cratio) === 0 && parseFormattedNumber(formatDataNumber(vault.collateral)) === 0) { + correctCollateralizationRatio = 0 + } + + const svgData = { + vaultID: vault.id, + stabilityFee, + debtAmount: formatDataNumber(vault.debt), + collateralAmount: formatDataNumber(vault.collateral) + ' ' + vault.collateralType, + collateralizationRatio: correctCollateralizationRatio, + liqRatio: Number( + parseRay(analyticsData.tokenAnalyticsData[vault.collateralType].liquidationCRatio) + ), + safetyRatio: Number(parseRay(analyticsData.tokenAnalyticsData[vault.collateralType].safetyCRatio)), + } + + const riskStatus = calculateRiskStatusText( + ratioChecker( + Number(cratio), + Number(parseRay(analyticsData.tokenAnalyticsData[vault.collateralType].liquidationCRatio)), + Number(parseRay(analyticsData.tokenAnalyticsData[vault.collateralType].safetyCRatio)) + ) + ) + + let svg = null + try { + svg = await generateSvg(svgData) + } catch (e) { + console.error(e) + } + + tableRows.push({ + id: vault.id, + collateral: vault.collateralType, + image: svg ? svg : null, + collateralAmount: parseNumber(formatDataNumber(vault.collateral)), + debtAmount: formatDataNumber(vault.debt) + ' OD', + riskStatus: riskStatus, + }) + } catch (e) { + console.error(e) + } + } + // @ts-ignore + setTableData(tableRows) + setIsLoading(false) + } + + useEffect(() => { + getSafeData() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [allVaults, analyticsData, geb]) + + return ( + +
+ Explore Vaults +
+ {tableData.length !== 0 && } + {tableData.length === 0 && isLoading &&

Loading...

} + {tableData.length === 0 && !isLoading &&

No vaults available

} +
+ ) +} + +export default Explore + +const Container = styled.div` + max-width: 1362px; + margin: 80px auto; + padding: 0 15px; + @media (max-width: 767px) { + margin: 50px auto; + display: flex; + flex-direction: column; + } + color: ${(props) => props.theme.colors.accent}; +` + +const Title = styled.h2` + font-size: 34px; + font-weight: 700; + font-family: ${(props) => props.theme.family.headers}; + + color: ${(props) => props.theme.colors.accent}; + @media (max-width: 767px) { + font-size: 32px; + } +` + +const Header = styled.div` + display: flex; + justify-content: space-between; + @media (max-width: 767px) { + flex-direction: column; + justify-content: left; + } + + margin-bottom: 40px; +` diff --git a/src/hooks/useVaultSubgraph.ts b/src/hooks/useVaultSubgraph.ts index 6c2420c3..3c1c63ca 100644 --- a/src/hooks/useVaultSubgraph.ts +++ b/src/hooks/useVaultSubgraph.ts @@ -28,6 +28,13 @@ export type VaultDetails = { collateralType: string } +export type AllVaults = { + vaults: VaultDetails[] + owners: string[] + vaultsByOwner: { [key: string]: string[] } + vaultsByCollateral: { [key: string]: string[] } +} + export const fetchAllVaults = async () => { const data = await postQuery( ` @@ -65,8 +72,12 @@ export const fetchAllVaults = async () => { } export const useVaultSubgraph = () => { - const [vaults, setVaults] = useState({ vaults: [] }) - + const [vaults, setVaults] = useState({ + vaults: [], + owners: [], + vaultsByOwner: {}, + vaultsByCollateral: {}, + }) const getVaults = async () => { const allVaults = await fetchAllVaults() setVaults(allVaults) diff --git a/src/utils/helper.ts b/src/utils/helper.ts index 950692f7..ef509e36 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -127,7 +127,7 @@ export const toFixedString = (value: string, type: keyof typeof floatsTypes = 'W } } -const getBytes32String = (collateralType: string, tokensData: { [key: string]: TokenData }): string | null => { +export const getBytes32String = (collateralType: string, tokensData: { [key: string]: TokenData }): string | null => { const token = Object.values(tokensData).find( (token) => token.symbol === collateralType || token.bytes32String === collateralType ) @@ -255,6 +255,35 @@ export const safeIsSafe = (totalCollateral: string, totalDebt: string, safetyPri return totalDebtBN.lte(totalCollateralBN.mul(safetyPriceBN).div(gebUtils.RAY)) } +/** + * Removes commas from a formatted number + * @param value + */ +export const parseFormattedNumber = (value: string): number => { + return parseFloat(value.replace(/,/g, '')) +} + +/** + * Calculate the risk status text given a numeric risk status + * @param riskStatusNumeric + */ +export const calculateRiskStatusText = (riskStatusNumeric: Number) => { + switch (riskStatusNumeric) { + case 0: + return 'NO' + case 1: + return 'LOW' + case 2: + return 'ELEVATED' + case 3: + return 'HIGH' + case 4: + return 'LIQUIDATION' + default: + return 'LOW' + } +} + /** * Check the risk state of the current liquidation ratio given a fixed minLiquidationRatio * @param currentLiquidationRatio From 0ff37361f3696f68749fcec1dba2b4617ee1c18d Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 01:09:05 -0700 Subject: [PATCH 04/21] remove fuul (#620) --- package.json | 1 - src/App.tsx | 15 --- src/components/Steps.tsx | 10 -- src/containers/Bolts/Affiliate.tsx | 206 ----------------------------- src/hooks/useFuulSDK.ts | 92 ------------- yarn.lock | 22 +-- 6 files changed, 1 insertion(+), 345 deletions(-) delete mode 100644 src/containers/Bolts/Affiliate.tsx delete mode 100644 src/hooks/useFuulSDK.ts diff --git a/package.json b/package.json index 3fd6fde7..905e7ed0 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "@ethersproject/address": "^5.0.10", "@ethersproject/experimental": "5.4.0", "@ethersproject/providers": "5.4.5", - "@fuul/sdk": "^4.7.1", "@opendollar/sdk": "1.7.3-rc.1", "@opendollar/svg-generator": "1.0.5", "@react-spring/web": "^9.7.3", diff --git a/src/App.tsx b/src/App.tsx index 6a585141..03a634a8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,7 +26,6 @@ import GeoBlockContainer from './containers/GeoBlockContainer' import * as Sentry from '@sentry/react' import Earn from './containers/Earn' import Bolts from './containers/Bolts' -import { Fuul } from '@fuul/sdk' import EarnDetails from './containers/Earn/EarnDetails' import Marketplace from './containers/Marketplace' import ScreenLoader from '~/components/Modals/ScreenLoader' @@ -49,20 +48,6 @@ Sentry.init({ environment: process.env.NODE_ENV, }) -const network = process.env.REACT_APP_NETWORK_ID -const fuulApiKey = process.env.REACT_APP_FUUL_API_KEY -// Only initialize Fuul on Arbitrum One -if (network === '42161' && fuulApiKey) { - try { - Fuul.init({ - apiKey: fuulApiKey, - }) - Fuul.sendPageview() - } catch (e) { - console.log(e) - } -} - const App = () => { const location = useLocation() diff --git a/src/components/Steps.tsx b/src/components/Steps.tsx index 446424bc..0a9d32f6 100644 --- a/src/components/Steps.tsx +++ b/src/components/Steps.tsx @@ -14,7 +14,6 @@ import { COIN_TICKER } from '~/utils' import useGeb from '~/hooks/useGeb' import { Tooltip as ReactTooltip } from 'react-tooltip' import { checkUserGasBalance } from '~/utils' -import useFuulSDK from '~/hooks/useFuulSDK' import LowGasModal from './Modals/LowGasModal' const Steps = () => { @@ -28,7 +27,6 @@ const Steps = () => { const { popupsModel: popupsActions, connectWalletModel: connectWalletActions } = useStoreActions((state) => state) const addTransaction = useTransactionAdder() - const { sendConnectWalletEvent } = useFuulSDK() const { step, isWrongNetwork, isStepLoading, blockNumber, ctHash } = connectWalletState @@ -42,14 +40,6 @@ const Steps = () => { return } try { - const referralProgram = localStorage.getItem('referralProgram') === 'true' - if (referralProgram) { - try { - await sendConnectWalletEvent(account) - } catch (e) { - console.debug('User declined Fuul program ', e) - } - } const txData = await geb.contracts.proxyRegistry.populateTransaction['build()']() const signer = provider.getSigner(account) connectWalletActions.setIsStepLoading(true) diff --git a/src/containers/Bolts/Affiliate.tsx b/src/containers/Bolts/Affiliate.tsx deleted file mode 100644 index e3cda72e..00000000 --- a/src/containers/Bolts/Affiliate.tsx +++ /dev/null @@ -1,206 +0,0 @@ -import { useState, useEffect } from 'react' -import styled from 'styled-components' -import { useActiveWeb3React } from '~/hooks/useActiveWeb3React' -import { useStoreActions } from '~/store' - -import useFuulSDK from '~/hooks/useFuulSDK' -import Button from '~/components/Button' -import CopyToClipboard from 'react-copy-to-clipboard' -import CopyIcon from '~/components/Icons/CopyIcon' - -const Affiliate = () => { - const { account } = useActiveWeb3React() - const { createAffiliateCode, getAffiliateCode } = useFuulSDK() - const [affiliateCode, setAffiliateCode] = useState('') - const [newAffiliateCode, setNewAffiliateCode] = useState('') - const [error, setError] = useState(null) - const [copied, setCopied] = useState(false) - const [hasFetched, setHasFetched] = useState(false) - - const { popupsModel: popupsActions } = useStoreActions((state) => state) - const handleConnectWallet = () => popupsActions.setIsConnectorsWalletOpen(true) - - useEffect(() => { - if (account && !hasFetched) { - setHasFetched(true) - ;(async () => { - try { - const code = await getAffiliateCode(account) - if (code) { - setAffiliateCode(code) - } - } catch (err) { - console.error('Error fetching referral code:', err) - } - })() - } - }, [account, getAffiliateCode, hasFetched]) - - const handleCreateAffiliateCode = async () => { - if (account && newAffiliateCode) { - try { - await createAffiliateCode(account, newAffiliateCode) - setAffiliateCode(newAffiliateCode) - setNewAffiliateCode('') - setError(null) - } catch (err) { - console.error('Error creating referral code:', err) - setError((err as Error)?.message || 'Failed to create referral code. Please try again.') - } - } - } - - return ( - - - {affiliateCode ? ( - <> - - - Your Referral Link:{' '} - {`https://app.opendollar.com?af=${affiliateCode}`} - - - { - setCopied(true) - setTimeout(() => setCopied(false), 1500) - }} - > - - - - - - ) : ( - <> - - https://app.opendollar.com?af= - setNewAffiliateCode(e.target.value)} - /> - - - {account ? ( - - ) : ( - - )} - - - {error && {error}} - - )} - - - ) -} - -export default Affiliate - -const CopyIconContainer = styled.div` - margin-left: 4px; -` - -const AffiliateText = styled.div` - display: flex; - justify-content: space-between; - font-style: italic; - font-size: ${(props) => props.theme.font.small}; -` - -const Container = styled.div` - background-color: rgba(0, 0, 0, 0.02); - backdrop-filter: blur(10px); - - border: 1px solid rgba(255, 255, 255, 0); - border-radius: 3px; - box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1); - - display: flex; - justify-content: flex-start; - margin-top: 20px; - padding: 20px; - border-radius: 5px; - width: 100%; - - @media (max-width: 767px) { - justify-content: center; - } -` - -const Content = styled.div` - display: flex; - align-items: center; - column-gap: 10px; - - input { - padding: 10px; - border: 1px solid #ccc; - border-radius: 4px; - width: 100%; - } - @media (max-width: 767px) { - flex-direction: column; - row-gap: 20px; - } -` - -const FlexContainer = styled.div` - display: flex; - align-items: center; - justify-content: center; - min-height: 59px; - - input { - flex-grow: 1; - } - - @media (max-width: 767px) { - flex-direction: column; /* Stack elements vertically */ - align-items: flex-start; - } -` - -const UrlText = styled.div` - text-wrap: nowrap; - font-style: italic; - font-size: ${(props) => props.theme.font.small}; -` -const BoldText = styled.span` - margin-left: 10px; - margin-right: 10px; - font-weight: bold; - font-size: ${(props) => props.theme.font.small}; -` - -const ErrorMessage = styled.div` - color: red; - margin-top: 10px; -` - -const BtnWrapper = styled.div` - width: max-content; - margin-right: auto; - button { - height: 49px; - text-transform: uppercase; - font-weight: 700; - font-size: 18px; - display: flex; - width: 280px; - } -` diff --git a/src/hooks/useFuulSDK.ts b/src/hooks/useFuulSDK.ts deleted file mode 100644 index 343265b2..00000000 --- a/src/hooks/useFuulSDK.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Fuul } from '@fuul/sdk' -import { SiweMessage } from 'siwe' -import { useActiveWeb3React } from '~/hooks/useActiveWeb3React' - -function useFuulSDK() { - const { chainId, provider } = useActiveWeb3React() - - const fuulSendPageViewEvent = async (pageName: string) => { - const response = await Fuul.sendPageview(pageName) - return response - } - - async function createSiweMessage(address: string, statement: string) { - const scheme = window.location.protocol.slice(0, -1) - const domain = window.location.host - const origin = window.location.origin - - const message = new SiweMessage({ - scheme, - domain, - address, - statement, - uri: origin, - version: '1', - chainId: chainId, - }) - return message.prepareMessage() - } - - const sendConnectWalletEvent = async (walletAddress: string): Promise => { - const message = await createSiweMessage( - walletAddress, - `Sign in with Ethereum to Open Dollar and agree to the Terms of Service at opendollar.com/terms and fuul.xyz/terms/users` - ) - const signature = await provider?.getSigner().signMessage(message) - return await Fuul.sendConnectWallet({ - address: walletAddress, - signature, - message, - }) - } - - const createAffiliateCode = async (walletAddress: string, affiliateCode: string): Promise => { - // DO NOT CHANGE THIS MESSAGE - THIS MESSAGE MUST MATCH EXACTLY OR THE SIGNATURE WILL FAIL - const message = `I confirm that I am creating the ${affiliateCode} code on Fuul` - const signature = await provider?.getSigner().signMessage(message) - if (!signature) { - throw new Error('Failed to sign message') - } - return await Fuul.createAffiliateCode(walletAddress, affiliateCode, signature) - } - - const getAffiliateCode = async (walletAddress: string): Promise => { - try { - return await Fuul.getAffiliateCode(walletAddress) - } catch (error) { - console.debug('No affiliate code found:', error) - return null - } - } - - const getUserData = async (user_address: string): Promise => { - try { - const data = await Fuul.getPointsLeaderboard({ user_address }) - const results = data?.results[0] - if (!results) { - return { - points: '0 🔩', - rank: 0, - } - } - return { - points: `${parseInt(results.total_amount).toLocaleString()} 🔩`, - rank: `#${results.rank}`, - } - } catch (error) { - console.debug('No user data found:', error) - return null - } - } - - return { - Fuul, - fuulSendPageViewEvent, - sendConnectWalletEvent, - createAffiliateCode, - getAffiliateCode, - getUserData, - } -} - -export default useFuulSDK diff --git a/yarn.lock b/yarn.lock index a0afed32..b4c9a9aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2938,16 +2938,6 @@ __metadata: languageName: node linkType: hard -"@fuul/sdk@npm:^4.7.1": - version: 4.7.4 - resolution: "@fuul/sdk@npm:4.7.4" - dependencies: - axios: ^1.2.2 - nanoid: ^4.0.0 - checksum: 0351e5f52733dcc12f1f8f28c75289a36387721b64f7425e2e33c7e6c438e04af56c207e3bded8799c12500a4584be7070e26d559351dbdb8b28072678b16a0f - languageName: node - linkType: hard - "@graphql-typed-document-node/core@npm:^3.1.1": version: 3.2.0 resolution: "@graphql-typed-document-node/core@npm:3.2.0" @@ -7016,7 +7006,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.2.2, axios@npm:^1.6.7": +"axios@npm:^1.6.7": version: 1.7.2 resolution: "axios@npm:1.7.2" dependencies: @@ -14656,15 +14646,6 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^4.0.0": - version: 4.0.2 - resolution: "nanoid@npm:4.0.2" - bin: - nanoid: bin/nanoid.js - checksum: 3fec62f422bc4727918eda0e7aa43e9cbb2e759be72813a0587b9dac99727d3c7ad972efce7f4f1d4cb5c7c554136a1ec3b1043d1d91d28d818d6acbe98200e5 - languageName: node - linkType: hard - "napi-wasm@npm:^1.1.0": version: 1.1.0 resolution: "napi-wasm@npm:1.1.0" @@ -15022,7 +15003,6 @@ __metadata: "@ethersproject/address": ^5.0.10 "@ethersproject/experimental": 5.4.0 "@ethersproject/providers": 5.4.5 - "@fuul/sdk": ^4.7.1 "@opendollar/sdk": 1.7.3-rc.1 "@opendollar/svg-generator": 1.0.5 "@react-spring/web": ^9.7.3 From 8ab866a56861de1fddb7265c2c8a556ac4fead6c Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 01:26:40 -0700 Subject: [PATCH 05/21] bump sdk (#621) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 905e7ed0..2191972c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@ethersproject/address": "^5.0.10", "@ethersproject/experimental": "5.4.0", "@ethersproject/providers": "5.4.5", - "@opendollar/sdk": "1.7.3-rc.1", + "@opendollar/sdk": "1.7.4-rc.1", "@opendollar/svg-generator": "1.0.5", "@react-spring/web": "^9.7.3", "@sentry/cli": "^2.31.0", diff --git a/yarn.lock b/yarn.lock index b4c9a9aa..595a4588 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3678,15 +3678,15 @@ __metadata: languageName: node linkType: hard -"@opendollar/sdk@npm:1.7.3-rc.1": - version: 1.7.3-rc.1 - resolution: "@opendollar/sdk@npm:1.7.3-rc.1" +"@opendollar/sdk@npm:1.7.4-rc.1": + version: 1.7.4-rc.1 + resolution: "@opendollar/sdk@npm:1.7.4-rc.1" dependencies: "@opendollar/abis": 0.0.0-605371bd ethers: 5.4.7 peerDependencies: utf-8-validate: ^5.0.2 - checksum: 43ad0437424c39a0938fc8994f1469ac9e3f83b3246e2fde7c3d293ecd68ffe11dae8eb60eebaaee7d91fb4182132014e165c7799a4713b504057aaa0246b8ff + checksum: 74974d2ca6af9030f04bb3bfeb692cd2028d83cc1fa606708069fba03bf0f3fdb9a4368dfbfb9f4403f3c4df04ac6bd7ad7d1e48d7a9852afb865dcb10fa2aed languageName: node linkType: hard @@ -15003,7 +15003,7 @@ __metadata: "@ethersproject/address": ^5.0.10 "@ethersproject/experimental": 5.4.0 "@ethersproject/providers": 5.4.5 - "@opendollar/sdk": 1.7.3-rc.1 + "@opendollar/sdk": 1.7.4-rc.1 "@opendollar/svg-generator": 1.0.5 "@react-spring/web": ^9.7.3 "@sentry/cli": ^2.31.0 From aafec609590681b44e1d97adff978923cfedc6f6 Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 01:31:25 -0700 Subject: [PATCH 06/21] remove maintenance from bolts --- src/containers/Bolts/index.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/containers/Bolts/index.tsx b/src/containers/Bolts/index.tsx index 2f0f529b..8528ec84 100644 --- a/src/containers/Bolts/index.tsx +++ b/src/containers/Bolts/index.tsx @@ -27,12 +27,8 @@ const Bolts = () => { Bolts Welcome Vault Keepers! -
- Under Maintenance - Check back later -
- {/*
+
{ Suggest a Quest -
*/} +
) } From b516220e34f5a2bcebab7eb76df3cc6f374a7746 Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 01:45:49 -0700 Subject: [PATCH 07/21] add credit guild block (#622) * add credit guild block * update earn block * final copy --- src/containers/Earn/EarnBlock.tsx | 225 ++++++++++++++++++++++++++++++ src/containers/Earn/index.tsx | 15 ++ 2 files changed, 240 insertions(+) create mode 100644 src/containers/Earn/EarnBlock.tsx diff --git a/src/containers/Earn/EarnBlock.tsx b/src/containers/Earn/EarnBlock.tsx new file mode 100644 index 00000000..c110a834 --- /dev/null +++ b/src/containers/Earn/EarnBlock.tsx @@ -0,0 +1,225 @@ +import styled from 'styled-components' +import { formatWithCommas, getTokenLogo } from '~/utils' +import { Tooltip as ReactTooltip } from 'react-tooltip' + +const Link = styled.a`` + +const EarnBlock = ({ + status, + url, + apy, + tvl, + title, + rewardToken1Symbol, + rewardToken2Symbol, +}: { + status: string + url: string + apy: string + tvl: string + title: string | JSX.Element + rewardToken1Symbol: string + rewardToken2Symbol: string +}) => { + return ( + + + + + {title} + + + + + + + + {status} + + + + + {tvl} + + + + {apy} + + + + {`${rewardToken1Symbol}, ${rewardToken2Symbol}`} + + + + + + ) +} + +export default EarnBlock + +const BlockContainer = styled.div` + border-radius: 4px; + margin-bottom: 29px; + background: white; + box-shadow: 0px 4px 6px 0px #0d4b9d33; + position: relative; + display: flex; + flex-direction: column; + &.empty { + background: white; + } +` + +const BlockHeader = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #1c293a33; + padding-left: 34px; + padding-top: 22px; + padding-bottom: 11px; + padding-right: 34px; + + ${({ theme }) => theme.mediaWidth.upToSmall` + display: flex; + flex-direction: column; + align-items: flex-end; + `} +` + +const PoolInfo = styled.div` + display: flex; + align-items: center; + svg { + border-radius: ${(props) => props.theme.global.borderRadius}; + border: 1px solid ${(props) => props.theme.colors.border}; + ${({ theme }) => theme.mediaWidth.upToSmall` + width: 25px; + height: 25px; + `} + } + + ${({ theme }) => theme.mediaWidth.upToSmall` + display: flex; + flex-direction: column; + `} +` + +const PoolData = styled.div` + display: flex; + font-size: ${(props) => props.theme.font.large}; + font-family: ${(props) => props.theme.family.headers}; + color: ${(props) => props.theme.colors.accent}; + font-weight: 700; + + img { + margin-left: 22px; + } + span { + font-weight: 500; + color: ${(props) => props.theme.colors.primary}; + } + ${({ theme }) => theme.mediaWidth.upToSmall` + margin-left: 10px; + `} +` + +const Block = styled.div` + display: flex; + justify-content: space-between; + + padding-left: 34px; + padding-top: 19px; + padding-bottom: 22px; + padding-right: 34px; + + ${({ theme }) => theme.mediaWidth.upToSmall` + display: block; + margin-top: 10px; + &:last-child { + border-bottom: 0; + } + `} +` + +const Item = styled.div` + min-width: 150px; + display: flex; + flex-direction: column; + justify-content: space-between; + + @media (max-width: 767px) { + display: flex; + flex-direction: row; + width: auto; + align-items: center; + margin: 0 0 3px 0; + &:last-child { + margin-bottom: 0; + } + } + + &.low div:last-child { + color: #459d00; + } + + &.elevated div:last-child { + color: #ffaf1d; + } + + &.high div:last-child { + color: #e75966; + } + + &.liquidation div:last-child { + color: #e75966; + } +` + +const Label = styled.div` + font-size: ${(props) => props.theme.font.default}; + color: ${(props) => props.theme.colors.tertiary}; + font-weight: 400; + display: flex; + gap: 10px; + align-items: center; + @media (max-width: 767px) { + font-size: ${(props) => props.theme.font.small}; + } +` + +const Value = styled.div` + font-size: ${(props) => props.theme.font.default}; + color: ${(props) => props.theme.colors.accent}; + font-weight: 700; + @media (max-width: 767px) { + font-size: ${(props) => props.theme.font.small}; + } + + display: flex; + align-items: center; + + &.status { + color: #459d00; + font-weight: 400; + border: 1px solid #459d00; + border-radius: 50px; + width: fit-content; + padding: 4px 15px; + } +` + +const Dot = styled.div` + width: 6px; + height: 6px; + background-color: #459d00; + border-radius: 100%; + margin-right: 5px; +` diff --git a/src/containers/Earn/index.tsx b/src/containers/Earn/index.tsx index 1e752e23..372b3175 100644 --- a/src/containers/Earn/index.tsx +++ b/src/containers/Earn/index.tsx @@ -10,6 +10,8 @@ import PoolBlock from './PoolBlock' import { JSX } from 'react/jsx-runtime' import { PoolData } from '@opendollar/sdk' import Skeleton from 'react-loading-skeleton' +import EarnBlock from './EarnBlock' +import { getTokenLogo } from '~/utils' interface Cache { [key: string]: PoolData @@ -83,6 +85,19 @@ const Earn = () => { Strategies + + Credit Guild {''} + + } + /> {nitroPools.length > 0 ? ( POOLS?.map( ( From c3b781ebc9fcaa6fc9f6c661f9b127ef04cea2f9 Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 02:19:10 -0700 Subject: [PATCH 08/21] api url hotfix --- src/model/boltsModel.ts | 6 +++--- src/services/checkSanctions.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model/boltsModel.ts b/src/model/boltsModel.ts index eff8781a..f0f0c3f3 100644 --- a/src/model/boltsModel.ts +++ b/src/model/boltsModel.ts @@ -76,10 +76,10 @@ const boltsModel: BoltsModel = { fetchData: thunk(async (actions, { account }, { getState }) => { try { - const BOT_DOMAIN = process.env.REACT_APP_OD_API_URL + const BOT_API_URL = process.env.REACT_APP_OD_API_URL ? process.env.REACT_APP_OD_API_URL - : 'https://bot.opendollar.com' - const BOT_API = `${BOT_DOMAIN}/api/bolts` + : 'https://bot.opendollar.com/api' + const BOT_API = `${BOT_API_URL}/bolts` const response = account ? await fetch(`${BOT_API}?address=${account}`) : await fetch(BOT_API) const result = await response.json() if (result.success) { diff --git a/src/services/checkSanctions.ts b/src/services/checkSanctions.ts index fb134d70..c4e9368e 100644 --- a/src/services/checkSanctions.ts +++ b/src/services/checkSanctions.ts @@ -5,7 +5,7 @@ async function checkSanctions(address: string) { try { const BOT_DOMAIN = process.env.REACT_APP_OD_API_URL ? process.env.REACT_APP_OD_API_URL - : 'https://bot.opendollar.com' + : 'https://bot.opendollar.com/api' const BOT_API = `${BOT_DOMAIN}/screen?address=${address}` res = await axios.get(BOT_API, { headers: { From 4a63b7ad035a00214794952b70df261def72c757 Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 10 Jul 2024 10:00:59 -0700 Subject: [PATCH 09/21] Od-weth QA (#623) * round stability fee * OD_API_URL --- src/components/VaultStats.tsx | 20 ++++++++++++-------- src/model/boltsModel.ts | 6 ++---- src/services/checkSanctions.ts | 6 ++---- src/utils/constants.ts | 4 +++- src/utils/gebManager/index.ts | 3 ++- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/components/VaultStats.tsx b/src/components/VaultStats.tsx index c610f77a..913b2f18 100644 --- a/src/components/VaultStats.tsx +++ b/src/components/VaultStats.tsx @@ -213,10 +213,12 @@ const VaultStats = ({ }} > Safety:{' '} - {Number( - safeState.liquidationData!.collateralLiquidationData[collateralName] - .safetyCRatio - ) * 100} + {Math.round( + Number( + safeState.liquidationData!.collateralLiquidationData[collateralName] + .safetyCRatio + ) * 100 + )} % {' '}   @@ -229,10 +231,12 @@ const VaultStats = ({ }} > Minimum:{' '} - {Number( - safeState.liquidationData!.collateralLiquidationData[collateralName] - .liquidationCRatio - ) * 100} + {Math.round( + Number( + safeState.liquidationData!.collateralLiquidationData[collateralName] + .liquidationCRatio + ) * 100 + )} % diff --git a/src/model/boltsModel.ts b/src/model/boltsModel.ts index f0f0c3f3..4367ec67 100644 --- a/src/model/boltsModel.ts +++ b/src/model/boltsModel.ts @@ -1,5 +1,6 @@ import { action, Action, thunk, Thunk } from 'easy-peasy' import { BoltsEarnedData, MultipliersData } from '~/containers/Bolts/quests' +import { OD_API_URL } from '~/utils/constants' type Campaign = { type: number @@ -76,10 +77,7 @@ const boltsModel: BoltsModel = { fetchData: thunk(async (actions, { account }, { getState }) => { try { - const BOT_API_URL = process.env.REACT_APP_OD_API_URL - ? process.env.REACT_APP_OD_API_URL - : 'https://bot.opendollar.com/api' - const BOT_API = `${BOT_API_URL}/bolts` + const BOT_API = `${OD_API_URL}/bolts` const response = account ? await fetch(`${BOT_API}?address=${account}`) : await fetch(BOT_API) const result = await response.json() if (result.success) { diff --git a/src/services/checkSanctions.ts b/src/services/checkSanctions.ts index c4e9368e..14d54bdc 100644 --- a/src/services/checkSanctions.ts +++ b/src/services/checkSanctions.ts @@ -1,12 +1,10 @@ import axios from 'axios' +import { OD_API_URL } from '~/utils/constants' async function checkSanctions(address: string) { let res try { - const BOT_DOMAIN = process.env.REACT_APP_OD_API_URL - ? process.env.REACT_APP_OD_API_URL - : 'https://bot.opendollar.com/api' - const BOT_API = `${BOT_DOMAIN}/screen?address=${address}` + const BOT_API = `${OD_API_URL}/screen?address=${address}` res = await axios.get(BOT_API, { headers: { Accept: 'application/json', diff --git a/src/utils/constants.ts b/src/utils/constants.ts index e60d2bce..8bdb86a4 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -7,7 +7,9 @@ import { ChainId, WalletInfo } from './interfaces' type AddressMap = { [chainId: number]: string } -const { REACT_APP_SYSTEM_STATUS, REACT_APP_NETWORK_URL } = process.env +const { REACT_APP_SYSTEM_STATUS, REACT_APP_NETWORK_URL, REACT_APP_OD_API_URL } = process.env + +export const OD_API_URL = REACT_APP_OD_API_URL ? REACT_APP_OD_API_URL : 'https://bot.opendollar.com/api' export const MULTICALL2_ADDRESSES: AddressMap = { [SupportedChainId.ARBITRUM_SEPOLIA]: '0xcA11bde05977b3631167028862bE2a173976CA11', diff --git a/src/utils/gebManager/index.ts b/src/utils/gebManager/index.ts index 8666b1a0..bb979b21 100644 --- a/src/utils/gebManager/index.ts +++ b/src/utils/gebManager/index.ts @@ -4,6 +4,7 @@ import { fetchLiquidationData, Geb, TokenLiquidationData, utils } from '@opendol import { ILiquidationResponse, IUserSafeList, IOwnerAddressesResponse } from '../interfaces' import { fetchUserSafes } from '@opendollar/sdk/lib/virtual/virtualUserSafes.js' import { TokenData } from '@opendollar/sdk/lib/contracts/addreses' +import { OD_API_URL } from '~/utils/constants' interface UserListConfig { geb: Geb @@ -117,7 +118,7 @@ const getUserSafesRpc = async (config: UserListConfig): Promise = } const getGlobalSafesRpc = async (): Promise => { - const response = await axios.get('https://bot.opendollar.com/api/vaults') + const response = await axios.get(`${OD_API_URL}/vaults`) const ownerAddresses: string[] = Array.from(new Set(response.data.details.map((safe: any) => safe.owner))) return { ownerAddresses } } From ee6c0c5b61fc3d6c07125e009afbf4e3c997b9ee Mon Sep 17 00:00:00 2001 From: Iana <36742189+alekseevaiana@users.noreply.github.com> Date: Wed, 10 Jul 2024 10:31:31 -0700 Subject: [PATCH 10/21] New "initializing" loader (#609) * change waiting modal content * put modal content back * show loader if no title, text, hint, hash * rm loader modal from account checkking * close loader popup when vaults is fetched * prettier * fix loader and blinking * rm creating modal * prettier * lin fix * cleanup --- src/components/Modals/WaitingModal.tsx | 98 +++++++++++++++----------- src/components/Steps.tsx | 4 +- src/containers/Shared.tsx | 11 +-- src/containers/Vaults/index.tsx | 26 +++++-- src/model/safeModel.ts | 1 + 5 files changed, 84 insertions(+), 56 deletions(-) diff --git a/src/components/Modals/WaitingModal.tsx b/src/components/Modals/WaitingModal.tsx index e05e2bb2..9fb2753b 100644 --- a/src/components/Modals/WaitingModal.tsx +++ b/src/components/Modals/WaitingModal.tsx @@ -71,54 +71,72 @@ const WaitingModal = () => { ) } } + return ( - - {returnStatusIcon(status)} - - { - - {title ? title : t('initializing')} - - } - - {text || (status === 'success' && !isCreate) ? ( - - {status === 'success' && chainId && hash ? ( - - {t('view_arbiscan')} - - ) : status === 'success' && isCreate ? ( - - {text} - - ) : ( - text - )} - - ) : null} - {hint && {hint}} - - {status !== 'loading' && !isCreate ? ( - - diff --git a/src/components/SideMenu.tsx b/src/components/SideMenu.tsx index b4c97bf2..4438d9c7 100644 --- a/src/components/SideMenu.tsx +++ b/src/components/SideMenu.tsx @@ -21,6 +21,7 @@ import WalletIcon from '~/assets/wallet-icon.svg' import DollarValueInner from './DollarValueInner' import parachuteIcon from '../assets/parachute-icon.svg' import { useAddress } from '~/hooks/useAddress' +import Skeleton from 'react-loading-skeleton' const SideMenu = () => { const nodeRef = React.useRef(null) @@ -47,7 +48,7 @@ const SideMenu = () => { } = useStoreState((state) => state) const poolData = usePoolData() const analyticsData = useAnalyticsData() - const address = useAddress(account) + let address = useAddress(account) const handleWalletConnect = () => popupsActions.setIsConnectorsWalletOpen(true) @@ -135,7 +136,6 @@ const SideMenu = () => { console.log('Error adding ODG to the wallet:', error) } } - useEffect(() => { if (chainId !== 421614 && chainId !== 42161 && chainId !== 10) return if (poolData && analyticsData) { @@ -180,7 +180,6 @@ const SideMenu = () => { useEffect(() => { setIsOpen(popupsState.showSideMenu) }, [popupsState.showSideMenu]) - return isOpen ? ( { > -
{address}
+
{address || }
{`$ ${renderBalance()}`}
diff --git a/src/components/VaultStats.tsx b/src/components/VaultStats.tsx index 913b2f18..4e58b040 100644 --- a/src/components/VaultStats.tsx +++ b/src/components/VaultStats.tsx @@ -1,4 +1,4 @@ -import { useMemo } from 'react' +import React, { useMemo } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' import { ExternalLink, Info } from 'react-feather' @@ -20,6 +20,7 @@ import { Tooltip as ReactTooltip } from 'react-tooltip' import { generateSvg } from '@opendollar/svg-generator' import { useWeb3React } from '@web3-react/core' import { useAddress } from '~/hooks/useAddress' +import Skeleton from 'react-loading-skeleton' const VaultStats = ({ isModifying, @@ -88,7 +89,7 @@ const VaultStats = ({ ) const svg = useMemo(() => generateSvg(statsForSVG), [statsForSVG]) - const address = useAddress(singleSafe?.ownerAddress || account!) + let address = useAddress(singleSafe?.ownerAddress || account!) const returnRedRate = () => { const currentRedemptionRate = singleSafe ? getRatePercentage(singleSafe.currentRedemptionRate, 10) : '0' @@ -253,10 +254,10 @@ const VaultStats = ({ - {chainId && ( + {address ? ( {address} + ) : ( + )} diff --git a/src/containers/Earn/index.tsx b/src/containers/Earn/index.tsx index 372b3175..bfc25b27 100644 --- a/src/containers/Earn/index.tsx +++ b/src/containers/Earn/index.tsx @@ -106,13 +106,7 @@ const Earn = () => { ) => ) ) : ( - + )}
From 686337e34b3662f8fb7a994eed235c0d68a37f0f Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Wed, 17 Jul 2024 16:34:21 -0700 Subject: [PATCH 13/21] Update react, react-router (#602) * widget at v2.10.2 * add yarn.lock * Update react-router to v6 * Update widget to v3 * add mui packages * fix onboarding props issue * yarn lock * make compatible with react router dom v6 * remove lifi widget * remove widget --------- Co-authored-by: jahabeebs --- package.json | 13 +- src/App.tsx | 64 ++- src/components/Analytics/GoogleTagManager.tsx | 3 +- src/components/Modals/LiquidateSafeModal.tsx | 6 +- src/components/NavLinks.tsx | 7 +- src/components/Steps.tsx | 8 +- src/components/VaultBlock.tsx | 52 ++- src/components/VaultManager.tsx | 6 +- src/containers/Auctions/index.tsx | 62 ++- src/containers/Bolts/quests.tsx | 6 +- src/containers/Bridge/LiFiWidget.tsx | 65 +++ src/containers/Deposit/DepositFunds.tsx | 25 +- src/containers/Earn/EarnDetails.tsx | 8 +- src/containers/Shared.tsx | 8 +- src/containers/Splash.tsx | 6 +- src/containers/Vaults/CreateVault.tsx | 10 +- src/containers/Vaults/ModifyVault.tsx | 6 +- src/containers/Vaults/VaultDetails.tsx | 31 +- src/containers/Vaults/VaultHeader.tsx | 8 +- src/containers/Vaults/index.tsx | 61 +-- src/index.tsx | 12 +- src/utils/formatBridgeUrl.ts | 4 +- yarn.lock | 379 ++++++++---------- 23 files changed, 425 insertions(+), 425 deletions(-) create mode 100644 src/containers/Bridge/LiFiWidget.tsx diff --git a/package.json b/package.json index 2191972c..1cd79a1f 100644 --- a/package.json +++ b/package.json @@ -20,10 +20,6 @@ "engines": { "node": ">=20.0.0" }, - "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, "dependencies": { "@apollo/client": "^3.7.17", "@coinbase/wallet-sdk": "^3.7.1", @@ -58,23 +54,23 @@ "easy-peasy": "^5.1.0", "ethers": "5.4.7", "graphql": "^16.8.1", - "i18next": "^19.7.0", + "i18next": "^23.11.5", "jazzicon": "^1.5.0", "numeral": "^2.0.6", - "react": "^17.0.1", + "react": "^18.3.1", "react-confetti": "^6.0.1", "react-cookie-consent": "^5.2.0", "react-copy-to-clipboard": "^5.0.2", "react-custom-scrollbars": "^4.2.1", "react-device-detect": "^1.13.1", - "react-dom": "^17.0.1", + "react-dom": "^18.3.1", "react-feather": "^2.0.9", "react-helmet-async": "^1.0.7", "react-i18next": "^11.7.2", "react-loading-skeleton": "^3.4.0", "react-number-format": "^5.2.2", "react-paginate": "^6.5.0", - "react-router-dom": "^5.3.0", + "react-router-dom": "^6.24.1", "react-scripts": "5.0.1", "react-toastify": "^6.0.9", "react-tooltip": "^5.21.1", @@ -82,6 +78,7 @@ "siwe": "^2.3.2", "styled-components": "^5.2.0", "terser-webpack-plugin": "^5.3.10", + "tiny-invariant": "^1.3.3", "typescript": "^4.4.3" }, "devDependencies": { diff --git a/src/App.tsx b/src/App.tsx index 03a634a8..a077dd92 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import React, { useEffect, lazy, Suspense } from 'react' import i18next from 'i18next' import { I18nextProvider } from 'react-i18next' -import { Redirect, Route, Switch, useLocation } from 'react-router-dom' +import { Route, Routes, useLocation } from 'react-router-dom' import { ThemeProvider } from 'styled-components' import ErrorBoundary from './ErrorBoundary' import GlobalStyle from './GlobalStyle' @@ -15,7 +15,6 @@ import { lightTheme } from './utils/themes/light' import { StatsProvider } from './hooks/useStats' import { ApolloProvider } from '@apollo/client' import { client } from './utils/graph' -import GoogleTagManager from './components/Analytics/GoogleTagManager' import CreateVault from './containers/Vaults/CreateVault' import Auctions from './containers/Auctions' import Analytics from './containers/Analytics' @@ -73,46 +72,43 @@ const App = () => { - + - - - - - - - - - - - - - + + } path="/404" /> + } path={'/'} /> + } path={'/maintenance'} /> + } path={'/earn'} /> + } path={'/bolts'} /> + } path={'/stats'} /> + } path={'/explore'} /> } + path={'/geoblock'} /> + } path={'/auctions'} /> + } path={'/marketplace'} /> } + path={'/vaults/create'} /> - - - - + } path={'/bridge'} /> } + path={'/vaults/:id/deposit'} /> - - + } path={'/vaults/:id/withdraw'} /> + } path={'/vaults/:id'} /> + } path={'/earn/:id'} /> + } path={'/vaults'} /> + } path={'/:address'} /> + } path={'/deposit/:token/deposit'} /> + } /> + diff --git a/src/components/Analytics/GoogleTagManager.tsx b/src/components/Analytics/GoogleTagManager.tsx index cd748f93..1bc47162 100644 --- a/src/components/Analytics/GoogleTagManager.tsx +++ b/src/components/Analytics/GoogleTagManager.tsx @@ -1,8 +1,7 @@ import React from 'react' import { Helmet } from 'react-helmet-async' -import { RouteComponentProps } from 'react-router-dom' -const GoogleTagManager = ({ location: { pathname } }: RouteComponentProps) => { +const GoogleTagManager = ({ location: { pathname } }: { location: { pathname: string } }) => { return ( {process.env.REACT_APP_GOOGLE_ANALYTICS_ID ? ( diff --git a/src/components/Modals/LiquidateSafeModal.tsx b/src/components/Modals/LiquidateSafeModal.tsx index ad2cc6eb..2312c630 100644 --- a/src/components/Modals/LiquidateSafeModal.tsx +++ b/src/components/Modals/LiquidateSafeModal.tsx @@ -1,6 +1,6 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import styled from 'styled-components' import { handleTransactionError } from '~/hooks' @@ -18,7 +18,7 @@ const LiquidateSafeModal = () => { const { t } = useTranslation() const [accepted, setAccepted] = useState(false) const geb = useGeb() - const history = useHistory() + const navigate = useNavigate() const closeModal = () => { setAccepted(false) @@ -55,7 +55,7 @@ const LiquidateSafeModal = () => { txResponse.wait().then(() => { closeModal() popupsModel.setIsWaitingModalOpen(false) - history.go(0) + navigate(-1) }) } }) diff --git a/src/components/NavLinks.tsx b/src/components/NavLinks.tsx index 3bc0a1fa..ec0e2e95 100644 --- a/src/components/NavLinks.tsx +++ b/src/components/NavLinks.tsx @@ -1,14 +1,12 @@ import React from 'react' import styled, { css } from 'styled-components' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' -import { NavLink } from 'react-router-dom' +import { NavLink, useLocation } from 'react-router-dom' import { useStoreActions } from '../store' const NavLinks = () => { - const history = useHistory() - const { location } = history + const location = useLocation() const { t } = useTranslation() const { popupsModel: popupsActions } = useStoreActions((state) => state) @@ -29,7 +27,6 @@ const NavLinks = () => { { name: 'auctions', to: '/auctions' }, { name: 'bolts', to: '/bolts' }, { name: 'stats', to: '/stats' }, - // { name: 'bridge', to: '/bridge' }, ] return ( diff --git a/src/components/Steps.tsx b/src/components/Steps.tsx index d7959c18..69a8e346 100644 --- a/src/components/Steps.tsx +++ b/src/components/Steps.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import { useActiveWeb3React, handleTransactionError, @@ -21,7 +21,7 @@ const Steps = () => { const { account, provider, chainId } = useActiveWeb3React() const geb = useGeb() const blocksSinceCheck = use10BlocksConfirmations() - const history = useHistory() + const navigate = useNavigate() const { connectWalletModel: connectWalletState } = useStoreState((state) => state) const { popupsModel: popupsActions, connectWalletModel: connectWalletActions } = useStoreActions((state) => state) @@ -65,7 +65,7 @@ const Steps = () => { const hasGasToken = await checkUserGasBalance(account, provider) if (!hasGasToken) { // bridgeModelActions.setReason('No funds for gas fee, please bridge some funds.') - popupsActions.setIsLowGasModalOpen(true) + // popupsActions.setIsLowGasModalOpen(true) } connectWalletActions.setIsStepLoading(false) handleTransactionError(e) @@ -74,7 +74,7 @@ const Steps = () => { } const handleCreateSafe = () => { - history.push('/vaults/create') + navigate('/vaults/create') } const returnSteps = (stepNumber: number) => { diff --git a/src/components/VaultBlock.tsx b/src/components/VaultBlock.tsx index 43ad3632..939719d7 100644 --- a/src/components/VaultBlock.tsx +++ b/src/components/VaultBlock.tsx @@ -3,46 +3,64 @@ import styled from 'styled-components' import { returnState, COIN_TICKER, getTokenLogo, formatWithCommas } from '~/utils' -const VaultBlock = ({ ...props }) => { +interface VaultBlockProps { + id: string + riskState: number + collateralName: string + collateral: string + totalDebt: string + collateralRatio: string + liquidationPrice: string + className?: string +} + +const VaultBlock = ({ + id, + riskState, + collateralName, + collateral, + totalDebt, + collateralRatio, + liquidationPrice, + className, +}: VaultBlockProps) => { + const stateClass = returnState(riskState) ? returnState(riskState).toLowerCase() : 'dimmed' + return ( - - - + + + - {props.collateralName} + {collateralName} - Vault #{props.id} + Vault #{id} - - {formatWithCommas(props.collateral)} + + {formatWithCommas(collateral)} - {formatWithCommas(props.totalDebt)} + {formatWithCommas(totalDebt)} - {`${formatWithCommas(props.collateralRatio)}%`} + {`${formatWithCommas(collateralRatio)}%`} - ${formatWithCommas(props.liquidationPrice)} + ${formatWithCommas(liquidationPrice)} - + -
{returnState(props.riskState) ? returnState(props.riskState) : 'Closed'}
+
{returnState(riskState) ? returnState(riskState) : 'Closed'}
diff --git a/src/components/VaultManager.tsx b/src/components/VaultManager.tsx index ca8884d5..2c2fd551 100644 --- a/src/components/VaultManager.tsx +++ b/src/components/VaultManager.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { isAddress } from '@ethersproject/address' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import styled from 'styled-components' import { useStoreActions, useStoreState } from '~/store' @@ -18,7 +18,7 @@ const VaultManager = () => { const [error, setError] = useState('') const [value, setValue] = useState('') - const history = useHistory() + const navigate = useNavigate() const { popupsModel: popupsActions } = useStoreActions((state) => state) const { tokensData } = useStoreState((state) => state.connectWalletModel) @@ -49,7 +49,7 @@ const VaultManager = () => { if (window?.location) { window.location.assign(`/${value}`) } else { - history.push(`/${value}`) + navigate(`/${value}`) } handleCancel() await timeout(3000) diff --git a/src/containers/Auctions/index.tsx b/src/containers/Auctions/index.tsx index 4e2a45fe..e288070f 100644 --- a/src/containers/Auctions/index.tsx +++ b/src/containers/Auctions/index.tsx @@ -1,8 +1,8 @@ import { useEffect, useState } from 'react' -import { RouteComponentProps, useHistory } from 'react-router-dom' +import { useNavigate, useParams, useLocation } from 'react-router-dom' import styled from 'styled-components' -import { useActiveWeb3React, handleTransactionError, useStartAuction, useQuery, useGetAuctions } from '~/hooks' +import { useActiveWeb3React, handleTransactionError, useStartAuction, useGetAuctions } from '~/hooks' import AlertLabel from '~/components/AlertLabel' import { AuctionEventType } from '~/types' import { useStoreActions, useStoreState } from '~/store' @@ -12,33 +12,26 @@ import { formatNumber } from '~/utils' import useGeb from '~/hooks/useGeb' import CollateralAuctionsList from './CollateralAuctions/CollateralAuctionsList' -const Auctions = ({ - match: { - params: { auctionType }, - }, -}: RouteComponentProps<{ auctionType?: string }>) => { - const { account } = useActiveWeb3React() - const { auctionModel: auctionsActions, popupsModel: popupsActions } = useStoreActions((state) => state) - const { auctionModel: auctionsState, connectWalletModel: connectWalletState } = useStoreState((state) => state) - const query = useQuery() +interface AuctionsProps { + className?: string +} + +const Auctions = ({ className }: AuctionsProps) => { + const { id } = useParams<{ id: string }>() + const auctionType = id ?? '' + const location = useLocation() + const query = new URLSearchParams(location.search) const queryType = query.get('type') as AuctionEventType | null const [type, setType] = useState(queryType || 'COLLATERAL') const [error, setError] = useState('') const [isLoading, setIsLoading] = useState(false) const [selectedItem, setSelectedItem] = useState('WSTETH') + const navigate = useNavigate() + const { account } = useActiveWeb3React() const geb = useGeb() - const history = useHistory() - - const getText = () => { - switch (type) { - case 'COLLATERAL': - return 'Collateral auctions are meant to sell collateral that was seized from a vault in exchange for OD. The OD that is received by an auction is burned.' - case 'SURPLUS': - return 'Surplus auctions sell OD that has accrued inside the protocol in exchange for ODG. The ODG that is received by an auction is burned.' - case 'DEBT': - return 'Debt auctions mint and auction new ODG in exchange for OD. The OD that is received by an auction will be used to eliminate bad (uncovered) debt from the system.' - } - } + const { auctionModel: auctionsActions, popupsModel: popupsActions } = useStoreActions((state) => state) + const { auctionModel: auctionsState, connectWalletModel: connectWalletState } = useStoreState((state) => state) + const { proxyAddress } = connectWalletState const { startSurplusAcution, @@ -55,7 +48,16 @@ const Auctions = ({ surplusCooldownDone, } = useStartAuction() - const { proxyAddress } = connectWalletState + const getText = () => { + switch (type) { + case 'COLLATERAL': + return 'Collateral auctions are meant to sell collateral that was seized from a vault in exchange for OD. The OD that is received by an auction is burned.' + case 'SURPLUS': + return 'Surplus auctions sell OD that has accrued inside the protocol in exchange for ODG. The ODG that is received by an auction is burned.' + case 'DEBT': + return 'Debt auctions mint and auction new ODG in exchange for OD. The OD that is received by an auction will be used to eliminate bad (uncovered) debt from the system.' + } + } const handleStartSurplusAuction = async () => { setIsLoading(true) @@ -93,12 +95,10 @@ const Auctions = ({ const onTabClick = (type: AuctionEventType) => { const params = new URLSearchParams() - if (query) { + if (type) { params.append('type', type) - } else { - params.delete('type') } - history.push({ search: params.toString() }) + navigate({ search: params.toString() }) setType(type) } @@ -144,7 +144,7 @@ const Auctions = ({ }, [auctionsActions, geb, proxyAddress, auctionsState.auctionsData]) return ( - + {error ? : null} Auctions @@ -262,7 +262,6 @@ const Title = styled.div` font-size: 34px; font-weight: 700; font-family: ${(props) => props.theme.family.headers}; - color: ${(props) => props.theme.colors.accent}; min-width: 180px; ` @@ -273,15 +272,12 @@ const Content = styled.div` button { display: flex; align-items: center; - min-width: 100px; padding: 4px 12px; - font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 2px; - color: ${(props) => props.theme.colors.accent}; } ` diff --git a/src/containers/Bolts/quests.tsx b/src/containers/Bolts/quests.tsx index 3c8cd215..8247336c 100644 --- a/src/containers/Bolts/quests.tsx +++ b/src/containers/Bolts/quests.tsx @@ -5,8 +5,8 @@ import zealyLogo from '~/assets/zealy.svg' import galxeLogo from '~/assets/galxe.svg' import camelotLogo from '~/assets/camelot.svg' import odLogo from '~/assets/od-full-logo-light.svg' +import { useNavigate } from 'react-router-dom' import turtleClubLogo from '~/assets/turtle-club.png' -import { useHistory } from 'react-router-dom' import TokenIcon from '~/components/TokenIcon' const StyledAnchor = styled.a` @@ -96,8 +96,8 @@ const TokensGroup = styled.span` ` const InternalLinkButton = ({ url }: { url: string }) => { - const history = useHistory() - const onClick = () => history.push(url) + const navigate = useNavigate() + const onClick = () => navigate(url) return ( diff --git a/src/containers/Vaults/CreateVault.tsx b/src/containers/Vaults/CreateVault.tsx index 01ee47aa..7f61100f 100644 --- a/src/containers/Vaults/CreateVault.tsx +++ b/src/containers/Vaults/CreateVault.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react' import { TokenData } from '@opendollar/sdk/lib/contracts/addreses' import { ChevronLeft, Info, Loader } from 'react-feather' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router' +import { useNavigate } from 'react-router' import useGeb from '~/hooks/useGeb' import { Tooltip as ReactTooltip } from 'react-tooltip' import styled from 'styled-components' @@ -50,7 +50,7 @@ const CreateVault = ({ safeModel: safeState, connectWalletModel: { proxyAddress, tokensData, tokensFetchedData }, } = useStoreState((state) => state) - const history = useHistory() + const navigate = useNavigate() const { safeModel: safeActions, connectWalletModel: connectWalletActions, @@ -180,7 +180,7 @@ const CreateVault = ({ depositAmountUSD, borrowAmountUSD, }) - history.push('/vaults') + navigate('/vaults') safeActions.setIsSuccessfulTx(true) popupsActions.setIsWaitingModalOpen(false) } catch (e) { @@ -243,7 +243,7 @@ const CreateVault = ({ bridgeModelActions.setReason(reason) bridgeModelActions.setFromTokenSymbol(selectedCollateral?.symbol) bridgeModelActions.setToTokenAddress(selectedCollateral?.address) - history.push('/bridge') + navigate('/bridge') } return ( @@ -271,7 +271,7 @@ const CreateVault = ({
- history.goBack()}> + navigate(-1)}> Back diff --git a/src/containers/Vaults/ModifyVault.tsx b/src/containers/Vaults/ModifyVault.tsx index e74c9b97..37c32401 100644 --- a/src/containers/Vaults/ModifyVault.tsx +++ b/src/containers/Vaults/ModifyVault.tsx @@ -26,7 +26,7 @@ import { useTokenApproval, ApprovalState, } from '~/hooks' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOwner: boolean; vaultId: string }) => { const [needsBridge, setNeedsBridge] = useState(false) @@ -35,7 +35,7 @@ const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOw const geb = useGeb() const [showPreview, setShowPreview] = useState(false) const { singleSafe } = safeState - const history = useHistory() + const navigate = useNavigate() const type = isDeposit ? 'deposit_borrow' : 'repay_withdraw' const { safeModel: safeActions, @@ -254,7 +254,7 @@ const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOw if (!singleSafe) return bridgeModelActions.setReason(reason) bridgeModelActions.setFromTokenSymbol(singleSafe?.collateralName) - history.push('/bridge') + navigate('/bridge') } return ( diff --git a/src/containers/Vaults/VaultDetails.tsx b/src/containers/Vaults/VaultDetails.tsx index ec7736f4..eb76aa11 100644 --- a/src/containers/Vaults/VaultDetails.tsx +++ b/src/containers/Vaults/VaultDetails.tsx @@ -1,4 +1,5 @@ import { useEffect, useMemo } from 'react' +import { useParams, useLocation, useNavigate } from 'react-router-dom' import { useTranslation } from 'react-i18next' import styled from 'styled-components' @@ -14,40 +15,29 @@ import gebManager from '~/utils/gebManager' import { ethers } from 'ethers' import Loader from '~/components/Loader' -const VaultDetails = ({ ...props }) => { +const VaultDetails = () => { const geb = useGeb() const { t } = useTranslation() const { account, provider } = useActiveWeb3React() const { safeModel: safeActions } = useStoreActions((state) => state) - const { safeModel: { liquidationData, singleSafe }, } = useStoreState((state) => state) - const safeId = props.match.params.id as string - - const isDeposit = useMemo(() => { - if (props.location) { - return props.location.pathname.includes('deposit') - } - return false - }, [props.location]) + const { id } = useParams() + const safeId = id ?? '' + const location = useLocation() + const navigate = useNavigate() - const isWithdraw = useMemo(() => { - if (props.location) { - return props.location.pathname.includes('withdraw') - } - return false - }, [props.location]) + const isDeposit = useMemo(() => location.pathname.includes('deposit'), [location.pathname]) + const isWithdraw = useMemo(() => location.pathname.includes('withdraw'), [location.pathname]) const isOwner = useIsOwner(safeId) const { safeModel: safeState } = useStoreState((state) => state) - const safes = safeState.list const safe = safes.find((safe) => safe.id === safeId) - // Fetches vault data of a vault not owned by the user const fetchSingleVaultData = async () => { if (safe && safeId && geb && liquidationData) { safeActions.setSingleSafe(safe) @@ -110,9 +100,9 @@ const VaultDetails = ({ ...props }) => { useEffect(() => { if (!account || !provider) return if (!isNumeric(safeId)) { - props.history.push('/vaults') + navigate('/vaults') } - }, [account, provider, props.history, safeId]) + }, [account, provider, navigate, safeId]) const isLoading = !(liquidationData && singleSafe?.collateralName) @@ -135,6 +125,7 @@ const VaultDetails = ({ ...props }) => { {/* Users can only repay debt from a vault they don't own */} {!isLoading && !isOwner ? : null} + {!isOwner ? ( diff --git a/src/containers/Vaults/VaultHeader.tsx b/src/containers/Vaults/VaultHeader.tsx index 89771059..89f2f8e8 100644 --- a/src/containers/Vaults/VaultHeader.tsx +++ b/src/containers/Vaults/VaultHeader.tsx @@ -1,19 +1,19 @@ import { useCallback } from 'react' import { ChevronLeft } from 'react-feather' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import styled from 'styled-components' import Button from '~/components/Button' import { useStoreActions, useStoreState } from '~/store' const VaultHeader = ({ safeId }: { safeId: string }) => { - const history = useHistory() + const navigate = useNavigate() const { openLiquidateSafeModal } = useStoreActions((state) => state.popupsModel) const { singleSafe } = useStoreState((state) => state.safeModel) const handleBack = useCallback(() => { - history.push(`/vaults`) - }, [history]) + navigate(`/vaults`) + }, [navigate]) const canLiquidate = singleSafe && Number(singleSafe.riskState) === 4 diff --git a/src/containers/Vaults/index.tsx b/src/containers/Vaults/index.tsx index d611fbbe..505a4157 100644 --- a/src/containers/Vaults/index.tsx +++ b/src/containers/Vaults/index.tsx @@ -1,10 +1,9 @@ import { useEffect, useState } from 'react' import { isAddress } from '@ethersproject/address' import styled from 'styled-components' - import { useStoreState, useStoreActions } from '~/store' import { useActiveWeb3React } from '~/hooks' -import { useHistory } from 'react-router-dom' +import { useNavigate, useParams } from 'react-router-dom' import useGeb from '~/hooks/useGeb' import CreateVaultStep from '~/components/CreateVaultStep' import VaultList from './VaultList' @@ -13,29 +12,28 @@ import { useTranslation } from 'react-i18next' import Accounts from './Accounts' import Loader from '~/components/Loader' -const OnBoarding = ({ ...props }) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const history = useHistory() - const [loading, setLoading] = useState(false) +interface OnBoardingProps { + className?: string +} + +const OnBoarding = ({ className }: OnBoardingProps) => { + const navigate = useNavigate() const { account, provider, chainId } = useActiveWeb3React() const geb = useGeb() const { t } = useTranslation() + + const [loading, setLoading] = useState(false) + const { address } = useParams<{ address: string }>() const { connectWalletModel: connectWalletState, safeModel: safeState } = useStoreState((state) => state) const { safeModel: safeActions } = useStoreActions((state) => state) const { isWrongNetwork, isStepLoading } = connectWalletState - const address: string = props.match.params.address ?? '' useEffect(() => { if (chainId !== 421614 && chainId !== 42161 && chainId !== 10) return - if ( - (!account && !address) || - (address && !isAddress(address.toLowerCase())) || - !provider || - connectWalletState.isWrongNetwork - ) + if ((!account && !address) || (address && !isAddress(address.toLowerCase())) || !provider || isWrongNetwork) return - async function fetchSafes() { + const fetchSafes = async () => { setLoading(true) try { await safeActions.fetchUserSafes({ @@ -50,39 +48,18 @@ const OnBoarding = ({ ...props }) => { } } - if (geb && connectWalletState.tokensData) { - fetchSafes() - } - - const ms = 3000 - const interval = setInterval(() => { - if ( - (!account && !address) || - (address && !isAddress(address.toLowerCase())) || - !provider || - connectWalletState.isWrongNetwork - ) - fetchSafes() - }, ms) + if (geb && connectWalletState.tokensData) fetchSafes() + const interval = setInterval(fetchSafes, 3000) return () => clearInterval(interval) - }, [ - account, - address, - connectWalletState.isWrongNetwork, - connectWalletState.tokensData, - geb, - provider, - safeActions, - chainId, - ]) + }, [account, address, isWrongNetwork, connectWalletState.tokensData, geb, provider, safeActions, chainId]) const handleCreateSafe = () => { - history.push('/vaults/create') + navigate('/vaults/create') } return ( - + {safeState.safeCreated ? ( <> @@ -91,9 +68,7 @@ const OnBoarding = ({ ...props }) => { stepNumber={2} id="step2" title={'create_safe'} - text={t('create_safe_text', { - coin_ticker: COIN_TICKER, - })} + text={t('create_safe_text', { coin_ticker: COIN_TICKER })} btnText={'create_safe'} handleClick={handleCreateSafe} isDisabled={isWrongNetwork} diff --git a/src/index.tsx b/src/index.tsx index a17f8598..5cebee51 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,6 @@ import React from 'react' -import ReactDOM from 'react-dom' +import { createRoot } from 'react-dom/client' + import { BrowserRouter } from 'react-router-dom' import { StoreProvider } from 'easy-peasy' import './index.css' @@ -26,7 +27,11 @@ const connectors: [MetaMask | WalletConnectV2 | CoinbaseWallet | Network | Gnosi [gnosisSafe, hooks], ] -ReactDOM.render( +const container = document.getElementById('root') + +const root = createRoot(container!) // createRoot(container!) if you use TypeScript + +root.render( @@ -37,6 +42,5 @@ ReactDOM.render( - , - document.getElementById('root') + ) diff --git a/src/utils/formatBridgeUrl.ts b/src/utils/formatBridgeUrl.ts index 64f2eff5..7ead7ffc 100644 --- a/src/utils/formatBridgeUrl.ts +++ b/src/utils/formatBridgeUrl.ts @@ -13,7 +13,7 @@ export const formatBridgeUrl = ({ return `https://bridge.arbitrum.io/?token=${fromTokenAddress}&&destinationChain=arbitrum-one&sourceChain=ethereum` } if (originChain !== 1) { - const toToken = toTokenAddress === 'WETH' ? '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1' : toTokenAddress - return `https://jumper.exchange/?fromChain=${originChain}&fromToken=${fromTokenAddress}&toChain=${toChain}&toToken=${toToken}` + // Formerly Lifi + return `https://bridge.arbitrum.io/?token=${fromTokenAddress}&&destinationChain=arbitrum-one&sourceChain=${originChain}` } } diff --git a/yarn.lock b/yarn.lock index 595a4588..30345f33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1658,7 +1658,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.24.7 resolution: "@babel/runtime@npm:7.24.7" dependencies: @@ -2912,29 +2912,29 @@ __metadata: languageName: node linkType: hard -"@floating-ui/core@npm:^1.0.0": - version: 1.6.3 - resolution: "@floating-ui/core@npm:1.6.3" +"@floating-ui/core@npm:^1.6.0": + version: 1.6.4 + resolution: "@floating-ui/core@npm:1.6.4" dependencies: - "@floating-ui/utils": ^0.2.3 - checksum: ae9335ad78563f579d307b72563e1fcd70fe98db04cdf1b63cf8fb5354cf3d49157d51d614c5ae7cd1d825864a7ed0c96be8f801be8b7e3a70fa8b9ae1b7805b + "@floating-ui/utils": ^0.2.4 + checksum: 545684b6f76cda7579b6049bafb9903542d3f9c177300192fe83db19d99b1df285bc33aba3b8ec2978d021151c4168356876e8181002dd2ff4fb93d9e4b7bf71 languageName: node linkType: hard "@floating-ui/dom@npm:^1.6.1": - version: 1.6.6 - resolution: "@floating-ui/dom@npm:1.6.6" + version: 1.6.7 + resolution: "@floating-ui/dom@npm:1.6.7" dependencies: - "@floating-ui/core": ^1.0.0 - "@floating-ui/utils": ^0.2.3 - checksum: ea7c24510fc1ad5a6a5f511864a8e4b2e51f184589fa1b71c09bf43f3d78433760f3c21bf48008674fc902f4c4aaf7095e3a5360a62f9cbde88c70809ca118d0 + "@floating-ui/core": ^1.6.0 + "@floating-ui/utils": ^0.2.4 + checksum: 5255f522534e0022b554c366b969fa26951677a1cf39ddd58614071a909a340c5e1ffe645501037b221808f01bfac4e7edba14728978ee7e2438e8432c1a163f languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.3": - version: 0.2.3 - resolution: "@floating-ui/utils@npm:0.2.3" - checksum: 7a2dac793cd99f05fde2d597cb434f1caa8b59563618453e1b8ac0ebb811e3627aaded16f3efd6d6e535f7448d590d38f9993be37adea258f3b9f826a6c96b2b +"@floating-ui/utils@npm:^0.2.4": + version: 0.2.4 + resolution: "@floating-ui/utils@npm:0.2.4" + checksum: 154924b01157cb45cf305f4835d7f603e931dda8b00bbe52666729bccc5e7b99630e8b951333725e526d4e53d9b342976434ad5750b8b1da58728e3698bdcc2b languageName: node linkType: hard @@ -3324,9 +3324,9 @@ __metadata: linkType: hard "@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": - version: 1.4.15 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" - checksum: 0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 2eb864f276eb1096c3c11da3e9bb518f6d9fc0023c78344cdc037abadc725172c70314bdb360f2d4b7bffec7f5d657ce006816bc5d4ecb35e61b66132db00c18 languageName: node linkType: hard @@ -3403,12 +3403,12 @@ __metadata: linkType: hard "@metamask/rpc-errors@npm:^6.2.1": - version: 6.3.0 - resolution: "@metamask/rpc-errors@npm:6.3.0" + version: 6.3.1 + resolution: "@metamask/rpc-errors@npm:6.3.1" dependencies: - "@metamask/utils": ^8.3.0 + "@metamask/utils": ^9.0.0 fast-safe-stringify: ^2.0.6 - checksum: ba11083b1bce84bd3f420a83e28337ce58c7773237558280057eeb19415b83fd7bac5148351f3e56bd8fa0621da3ddad0231a85fc11a5a281820fc0e99cf977a + checksum: 0ca1f8b138ef9352310befeae194d248fec75ccdd0442369369fb1003316679088dc142e2766b95e2c181ff6dc8786fd7371123d8860e022ec5e420ce05e7496 languageName: node linkType: hard @@ -3426,7 +3426,7 @@ __metadata: languageName: node linkType: hard -"@metamask/superstruct@npm:^3.0.0": +"@metamask/superstruct@npm:^3.0.0, @metamask/superstruct@npm:^3.1.0": version: 3.1.0 resolution: "@metamask/superstruct@npm:3.1.0" checksum: 8820e76582b3d735a2142c878ac4830d962f7a9c0776cb31bafdff646ff701657b9be192601d7f96834c3a8edd87677650f5bfa1a29d945e8dbc77a8d788b3fc @@ -3463,6 +3463,23 @@ __metadata: languageName: node linkType: hard +"@metamask/utils@npm:^9.0.0": + version: 9.0.0 + resolution: "@metamask/utils@npm:9.0.0" + dependencies: + "@ethereumjs/tx": ^4.2.0 + "@metamask/superstruct": ^3.1.0 + "@noble/hashes": ^1.3.1 + "@scure/base": ^1.1.3 + "@types/debug": ^4.1.7 + debug: ^4.3.4 + pony-cause: ^2.1.10 + semver: ^7.5.4 + uuid: ^9.0.1 + checksum: 916070ed8536b75fb6c5fad3caf8604bd75781db77d899d9d25bbfbd12f4e1fb8471ff87feaf82bcf9e872978ce908e7ec50b755fc68e9ce5e504f3477d305f0 + languageName: node + linkType: hard + "@motionone/animation@npm:^10.15.1, @motionone/animation@npm:^10.18.0": version: 10.18.0 resolution: "@motionone/animation@npm:10.18.0" @@ -3566,12 +3583,12 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.4.0, @noble/curves@npm:~1.4.0": - version: 1.4.0 - resolution: "@noble/curves@npm:1.4.0" +"@noble/curves@npm:1.4.2, @noble/curves@npm:~1.4.0": + version: 1.4.2 + resolution: "@noble/curves@npm:1.4.2" dependencies: "@noble/hashes": 1.4.0 - checksum: 31fbc370df91bcc5a920ca3f2ce69c8cf26dc94775a36124ed8a5a3faf0453badafd2ee4337061ffea1b43c623a90ee8b286a5a81604aaf9563bdad7ff795d18 + checksum: 65620c895b15d46e8087939db6657b46a1a15cd4e0e4de5cd84b97a0dfe0af85f33a431bb21ac88267e3dc508618245d4cb564213959d66a84d690fe18a63419 languageName: node linkType: hard @@ -3965,6 +3982,13 @@ __metadata: languageName: node linkType: hard +"@remix-run/router@npm:1.17.1": + version: 1.17.1 + resolution: "@remix-run/router@npm:1.17.1" + checksum: bee1631feb03975b64e1c7b574da432a05095dda2ff0f164c737e4952841a58d7b9861de87bd13a977fd970c74dcf8c558fc2d26c6ec01a9ae9041b1b4430869 + languageName: node + linkType: hard + "@rollup/plugin-babel@npm:^5.2.0": version: 5.3.1 resolution: "@rollup/plugin-babel@npm:5.3.1" @@ -4711,21 +4735,21 @@ __metadata: linkType: hard "@tanstack/react-table@npm:^8.17.3": - version: 8.17.3 - resolution: "@tanstack/react-table@npm:8.17.3" + version: 8.19.2 + resolution: "@tanstack/react-table@npm:8.19.2" dependencies: - "@tanstack/table-core": 8.17.3 + "@tanstack/table-core": 8.19.2 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: d1ab321f189f1c7e20336c0516f8155a3d46aea74cc7ec849239b7323cf3e4fe919585489de3512eab36fceb7c4eae245e58235e6fcb5f112379411d801605fd + checksum: 6941e12cdb907709d6a2b919efb2daae01348eb3cc964fb437a7725461fc306375604ac83e09ea4dc793e34075b8b69a89b7bfd182b4762b711db2a721c21139 languageName: node linkType: hard -"@tanstack/table-core@npm:8.17.3": - version: 8.17.3 - resolution: "@tanstack/table-core@npm:8.17.3" - checksum: e45f0f74b645689c762dd8c1042726d804726a488130fb2d36e24384bd813a601ed4d20abff3b4ba1bb1a648d14029f65d7fa8728099e0fd9f2702b51dc586c2 +"@tanstack/table-core@npm:8.19.2": + version: 8.19.2 + resolution: "@tanstack/table-core@npm:8.19.2" + checksum: f09f1b4860899466f106fd5b89faf465f0d5210416505d0d6a6641025da05dec7f8eb193ca98d204288f05eb2b617497e0cd9e274ead3f504391749696cfcd3f languageName: node linkType: hard @@ -5190,11 +5214,11 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 20.14.9 - resolution: "@types/node@npm:20.14.9" + version: 20.14.10 + resolution: "@types/node@npm:20.14.10" dependencies: undici-types: ~5.26.4 - checksum: 911ffa444dc032897f4a23ed580c67903bd38ea1c5ec99b1d00fa10b83537a3adddef8e1f29710cbdd8e556a61407ed008e06537d834e48caf449ce59f87d387 + checksum: 0b06cff14365c2d0085dc16cc8cbea5c40ec09cfc1fea966be9eeecf35562760bfde8f88e86de6edfaf394501236e229d9c1084fad04fb4dec472ae245d8ae69 languageName: node linkType: hard @@ -6412,11 +6436,11 @@ __metadata: linkType: hard "acorn@npm:^8.11.0, acorn@npm:^8.11.3, acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": - version: 8.12.0 - resolution: "acorn@npm:8.12.0" + version: 8.12.1 + resolution: "acorn@npm:8.12.1" bin: acorn: bin/acorn - checksum: a19f9dead009d3b430fa3c253710b47778cdaace15b316de6de93a68c355507bc1072a9956372b6c990cbeeb167d4a929249d0faeb8ae4bb6911d68d53299549 + checksum: 51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386 languageName: node linkType: hard @@ -7228,11 +7252,11 @@ __metadata: linkType: hard "base-x@npm:^3.0.2": - version: 3.0.9 - resolution: "base-x@npm:3.0.9" + version: 3.0.10 + resolution: "base-x@npm:3.0.10" dependencies: safe-buffer: ^5.0.1 - checksum: e6bbeae30b24f748b546005affb710c5fbc8b11a83f6cd0ca999bd1ab7ad3a22e42888addc40cd145adc4edfe62fcfab4ebc91da22e4259aae441f95a77aee1a + checksum: a13a34b71439ee5381667efa630b3bf640cf17f632c5ba01990483367592e72f247d7fb4f8c6d0e3ff8c0fb7224b3ac682ff5be09b87063a45b3968f0457e563 languageName: node linkType: hard @@ -7445,16 +7469,16 @@ __metadata: linkType: hard "browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.2, browserslist@npm:^4.23.0": - version: 4.23.1 - resolution: "browserslist@npm:4.23.1" + version: 4.23.2 + resolution: "browserslist@npm:4.23.2" dependencies: - caniuse-lite: ^1.0.30001629 - electron-to-chromium: ^1.4.796 + caniuse-lite: ^1.0.30001640 + electron-to-chromium: ^1.4.820 node-releases: ^2.0.14 - update-browserslist-db: ^1.0.16 + update-browserslist-db: ^1.1.0 bin: browserslist: cli.js - checksum: eb47c7ab9d60db25ce2faca70efeb278faa7282a2f62b7f2fa2f92e5f5251cf65144244566c86559419ff4f6d78f59ea50e39911321ad91f3b27788901f1f5e9 + checksum: 0217d23c69ed61cdd2530c7019bf7c822cd74c51f8baab18dd62457fed3129f52499f8d3a6f809ae1fb7bb3050aa70caa9a529cc36c7478427966dbf429723a5 languageName: node linkType: hard @@ -7662,10 +7686,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001629": - version: 1.0.30001638 - resolution: "caniuse-lite@npm:1.0.30001638" - checksum: 33019e0c53ed73f1e728b6f313efed2d7a25710dfa2ad3924d2be9939df10d0991556ac87523d3177d472c246654c9216f03e5532717ed97df58014728c3e798 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001640": + version: 1.0.30001641 + resolution: "caniuse-lite@npm:1.0.30001641" + checksum: a065b641cfcc84b36955ee909bfd7313ad103d6a299f0fd261e0e4160e8f1cec79d685c5a9f11097a77687cf47154eddb8133163f2a34bcb8d73c45033a014d2 languageName: node linkType: hard @@ -8744,8 +8768,8 @@ __metadata: linkType: hard "cypress@npm:*, cypress@npm:^13.6.4": - version: 13.12.0 - resolution: "cypress@npm:13.12.0" + version: 13.13.0 + resolution: "cypress@npm:13.13.0" dependencies: "@cypress/request": ^3.0.0 "@cypress/xvfb": ^1.2.4 @@ -8786,12 +8810,12 @@ __metadata: request-progress: ^3.0.0 semver: ^7.5.3 supports-color: ^8.1.1 - tmp: ~0.2.1 + tmp: ~0.2.3 untildify: ^4.0.0 yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: a9f74ce07b8d9d8058e4909ac3824d3d8a09af6f92eb4b69bce0892765ceeeac77094976e41a2a31e5138b6e43c2e5f1fb6fb54fbf9fa1bab957b465f5517540 + checksum: 732533a3d783ca98763643307ec519d8006528c38af98be4e3880583a15bd4bb1ccaf5eed5d68f61ecf4d5f887211fec82b25bb3c0fee959707c87bc7a2684a2 languageName: node linkType: hard @@ -9415,10 +9439,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.796": - version: 1.4.814 - resolution: "electron-to-chromium@npm:1.4.814" - checksum: 1e757252840a39ebf77b56e2b0adede1fb3f130b8318bdfcc81361b6da9137daeb4c6886a3a63ebfbfdd37fce60ec35795a2adaa250568895784475fba76a446 +"electron-to-chromium@npm:^1.4.820": + version: 1.4.823 + resolution: "electron-to-chromium@npm:1.4.823" + checksum: 772ad25e1305ab4a1a18beb9edae5d62ba55c5660c9d20a86c90e195d22da64dcf209ba8c9fb8172c76d1cbff12ea56a83eb75863bd2b22fb7ddabcd1d73c1e7 languageName: node linkType: hard @@ -10122,11 +10146,11 @@ __metadata: linkType: hard "esquery@npm:^1.4.2": - version: 1.5.0 - resolution: "esquery@npm:1.5.0" + version: 1.6.0 + resolution: "esquery@npm:1.6.0" dependencies: estraverse: ^5.1.0 - checksum: a084bd049d954cc88ac69df30534043fb2aee5555b56246493f42f27d1e168f00d9e5d4192e46f10290d312dc30dc7d58994d61a609c579c1219d636996f9213 + checksum: cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2 languageName: node linkType: hard @@ -10318,14 +10342,14 @@ __metadata: linkType: hard "ethereum-cryptography@npm:^2.0.0": - version: 2.2.0 - resolution: "ethereum-cryptography@npm:2.2.0" + version: 2.2.1 + resolution: "ethereum-cryptography@npm:2.2.1" dependencies: - "@noble/curves": 1.4.0 + "@noble/curves": 1.4.2 "@noble/hashes": 1.4.0 "@scure/bip32": 1.4.0 "@scure/bip39": 1.3.0 - checksum: 766939345c39936f32929fae101a91f009f5e28261578d44e7a224dbb70827feebb5135013e81fc39bdcf8d70b321e92b4243670f0947e73add8ae5158717b84 + checksum: c6c7626d393980577b57f709878b2eb91f270fe56116044b1d7afb70d5c519cddc0c072e8c05e4a335e05342eb64d9c3ab39d52f78bb75f76ad70817da9645ef languageName: node linkType: hard @@ -10974,9 +10998,9 @@ __metadata: linkType: hard "forge-std@git+https://github.com/foundry-rs/forge-std.git": - version: 1.8.2 - resolution: "forge-std@https://github.com/foundry-rs/forge-std.git#commit=75b3fcf052cc7886327e4c2eac3d1a1f36942b41" - checksum: b2d1b2ba0de503564530597975650c8ef455f5f1f271590371d0c8f0b0adc2392eccaff5e999621f1dcb60ab4cdb06c4e4dbf02ca85de9b700287f2a8bed2373 + version: 1.9.1 + resolution: "forge-std@https://github.com/foundry-rs/forge-std.git#commit=07263d193d621c4b2b0ce8b4d54af58f6957d97d" + checksum: 0ffda4f278f6911fc3f9c7760292383c085a8201a0996663b1baa70ae0851afbaa9c19c51ff0b0e4a129a48110d69eec9cdc2164663d0334ec3df90e4768ef1b languageName: node linkType: hard @@ -11323,8 +11347,8 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.4.2 - resolution: "glob@npm:10.4.2" + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: ^3.1.0 jackspeak: ^3.1.2 @@ -11334,7 +11358,7 @@ __metadata: path-scurry: ^1.11.1 bin: glob: dist/esm/bin.mjs - checksum: 2c7296695fa75a935f3ad17dc62e4e170a8bb8752cf64d328be8992dd6ad40777939003754e10e9741ff8fbe43aa52fba32d6930d0ffa0e3b74bc3fb5eebaa2f + checksum: 19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e languageName: node linkType: hard @@ -11614,20 +11638,6 @@ __metadata: languageName: node linkType: hard -"history@npm:^4.9.0": - version: 4.10.1 - resolution: "history@npm:4.10.1" - dependencies: - "@babel/runtime": ^7.1.2 - loose-envify: ^1.2.0 - resolve-pathname: ^3.0.0 - tiny-invariant: ^1.0.2 - tiny-warning: ^1.0.0 - value-equal: ^1.0.1 - checksum: 35377694e4f10f2cf056a9cb1a8ee083e04e4b4717a63baeee4afd565658a62c7e73700bf9e82aa53dbe1ec94e0a25a83c080d63bad8ee6b274a98d2fbc5ed4c - languageName: node - linkType: hard - "hmac-drbg@npm:^1.0.1": version: 1.0.1 resolution: "hmac-drbg@npm:1.0.1" @@ -11639,7 +11649,7 @@ __metadata: languageName: node linkType: hard -"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2": +"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2": version: 3.3.2 resolution: "hoist-non-react-statics@npm:3.3.2" dependencies: @@ -11913,12 +11923,12 @@ __metadata: languageName: node linkType: hard -"i18next@npm:^19.7.0": - version: 19.9.2 - resolution: "i18next@npm:19.9.2" +"i18next@npm:^23.11.5": + version: 23.11.5 + resolution: "i18next@npm:23.11.5" dependencies: - "@babel/runtime": ^7.12.0 - checksum: ee4991039a9acfff3ff4d5872ba183fce6ddc7017b689095d3d3df98ca16c0563f7d1333b4a4d3d4de65af5a521661bed36d677a5dd712c62095683e33f33a66 + "@babel/runtime": ^7.23.2 + checksum: b0bec64250a3e529d4c51e2fc511406a85c5dde3d005d3aabe919551ca31dfc0a8f5490bf6e44649822e895a1fa91a58092d112367669cd11b2eb89e6ba90d1a languageName: node linkType: hard @@ -12564,13 +12574,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:0.0.1": - version: 0.0.1 - resolution: "isarray@npm:0.0.1" - checksum: ed1e62da617f71fe348907c71743b5ed550448b455f8d269f89a7c7ddb8ae6e962de3dab6a74a237b06f5eb7f6ece7a45ada8ce96d87fe972926530f91ae3311 - languageName: node - linkType: hard - "isarray@npm:^2.0.5": version: 2.0.5 resolution: "isarray@npm:2.0.5" @@ -12698,15 +12701,15 @@ __metadata: linkType: hard "jackspeak@npm:^3.1.2": - version: 3.4.0 - resolution: "jackspeak@npm:3.4.0" + version: 3.4.2 + resolution: "jackspeak@npm:3.4.2" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 7e42d1ea411b4d57d43ea8a6afbca9224382804359cb72626d0fc45bb8db1de5ad0248283c3db45fe73e77210750d4fcc7c2b4fe5d24fda94aaa24d658295c5f + checksum: 31952961f4d0d51831b8973db5c800233dc0f2181c3ca74af96f02cdc5c3f2b3df147a9ce2b56a643bd459036d782fb8c59f8992658d2bb4564753c42bb80c6c languageName: node linkType: hard @@ -14092,7 +14095,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -14113,9 +14116,9 @@ __metadata: linkType: hard "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": - version: 10.3.0 - resolution: "lru-cache@npm:10.3.0" - checksum: 02d57024d90672774d66e0b76328a8975483b782c68118078363be17b8e0efb4f2bee89d98ce87e72f42d68fe7cb4ad14b1205d43e4f9954f5c91e3be4eaceb8 + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb languageName: node linkType: hard @@ -14553,7 +14556,7 @@ __metadata: languageName: node linkType: hard -"mlly@npm:^1.6.1, mlly@npm:^1.7.0": +"mlly@npm:^1.6.1, mlly@npm:^1.7.1": version: 1.7.1 resolution: "mlly@npm:1.7.1" dependencies: @@ -15051,25 +15054,25 @@ __metadata: ethers: 5.4.7 graphql: ^16.8.1 husky: ^5.0.9 - i18next: ^19.7.0 + i18next: ^23.11.5 jazzicon: ^1.5.0 lint-staged: ^10.5.4 numeral: ^2.0.6 prettier: ^2.2.1 - react: ^17.0.1 + react: ^18.3.1 react-confetti: ^6.0.1 react-cookie-consent: ^5.2.0 react-copy-to-clipboard: ^5.0.2 react-custom-scrollbars: ^4.2.1 react-device-detect: ^1.13.1 - react-dom: ^17.0.1 + react-dom: ^18.3.1 react-feather: ^2.0.9 react-helmet-async: ^1.0.7 react-i18next: ^11.7.2 react-loading-skeleton: ^3.4.0 react-number-format: ^5.2.2 react-paginate: ^6.5.0 - react-router-dom: ^5.3.0 + react-router-dom: ^6.24.1 react-scripts: 5.0.1 react-toastify: ^6.0.9 react-tooltip: ^5.21.1 @@ -15078,10 +15081,8 @@ __metadata: siwe: ^2.3.2 styled-components: ^5.2.0 terser-webpack-plugin: ^5.3.10 + tiny-invariant: ^1.3.3 typescript: ^4.4.3 - peerDependencies: - react: ^18.2.0 - react-dom: ^18.2.0 languageName: unknown linkType: soft @@ -15417,15 +15418,6 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^1.7.0": - version: 1.8.0 - resolution: "path-to-regexp@npm:1.8.0" - dependencies: - isarray: 0.0.1 - checksum: 7b25d6f27a8de03f49406d16195450f5ced694398adea1510b0f949d9660600d1769c5c6c83668583b7e6b503f3caf1ede8ffc08135dbe3e982f034f356fbb5c - languageName: node - linkType: hard - "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -15564,13 +15556,13 @@ __metadata: linkType: hard "pkg-types@npm:^1.1.1": - version: 1.1.1 - resolution: "pkg-types@npm:1.1.1" + version: 1.1.3 + resolution: "pkg-types@npm:1.1.3" dependencies: confbox: ^0.1.7 - mlly: ^1.7.0 + mlly: ^1.7.1 pathe: ^1.1.2 - checksum: c7d167935de7207479e5829086040d70bea289f31fc1331f17c83e996a4440115c9deba2aa96de839ea66e1676d083c9ca44b33886f87bffa6b49740b67b6fcb + checksum: 4cd2c9442dd5e4ae0c61cbd8fdaa92a273939749b081f78150ce9a3f4e625cca0375607386f49f103f0720b239d02369bf181c3ea6c80cf1028a633df03706ad languageName: node linkType: hard @@ -16444,20 +16436,20 @@ __metadata: linkType: hard "postcss@npm:^8.3.5, postcss@npm:^8.4.23, postcss@npm:^8.4.33, postcss@npm:^8.4.4": - version: 8.4.38 - resolution: "postcss@npm:8.4.38" + version: 8.4.39 + resolution: "postcss@npm:8.4.39" dependencies: nanoid: ^3.3.7 - picocolors: ^1.0.0 + picocolors: ^1.0.1 source-map-js: ^1.2.0 - checksum: 955407b8f70cf0c14acf35dab3615899a2a60a26718a63c848cf3c29f2467b0533991b985a2b994430d890bd7ec2b1963e36352b0774a19143b5f591540f7c06 + checksum: 16f5ac3c4e32ee76d1582b3c0dcf1a1fdb91334a45ad755eeb881ccc50318fb8d64047de4f1601ac96e30061df203f0f2e2edbdc0bfc49b9c57bc9fb9bedaea3 languageName: node linkType: hard "preact@npm:^10.16.0, preact@npm:^10.5.9": - version: 10.22.0 - resolution: "preact@npm:10.22.0" - checksum: dc5466c5968c56997e917580c00983cec2f6486a89ea9ba29f1bb88dcfd2f9ff67c8d561a69a1b3acdab17f2bb36b311fef0c348b62e89c332d00c674f7871f0 + version: 10.22.1 + resolution: "preact@npm:10.22.1" + checksum: 9163b97d6fc0ce6b945ed77695d00c4fa07e317d0723e7b9d10c748153d30596abab8b26861ae45591e47bff25515da91406ce7f1c9e66cd9cac7e7f6c927930 languageName: node linkType: hard @@ -16938,16 +16930,15 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^17.0.1": - version: 17.0.2 - resolution: "react-dom@npm:17.0.2" +"react-dom@npm:^18.3.1": + version: 18.3.1 + resolution: "react-dom@npm:18.3.1" dependencies: loose-envify: ^1.1.0 - object-assign: ^4.1.1 - scheduler: ^0.20.2 + scheduler: ^0.23.2 peerDependencies: - react: 17.0.2 - checksum: 51abbcb72450fe527ebf978c3bc989ba266630faaa53f47a2fae5392369729e8de62b2e4683598cbe651ea7873cd34ec7d5127e2f50bf4bfe6bd0c3ad9bddcb0 + react: ^18.3.1 + checksum: a752496c1941f958f2e8ac56239172296fcddce1365ce45222d04a1947e0cc5547df3e8447f855a81d6d39f008d7c32eab43db3712077f09e3f67c4874973e85 languageName: node linkType: hard @@ -17010,7 +17001,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.1, react-is@npm:^16.6.0, react-is@npm:^16.7.0": +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 @@ -17070,39 +17061,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^5.3.0": - version: 5.3.4 - resolution: "react-router-dom@npm:5.3.4" +"react-router-dom@npm:^6.24.1": + version: 6.24.1 + resolution: "react-router-dom@npm:6.24.1" dependencies: - "@babel/runtime": ^7.12.13 - history: ^4.9.0 - loose-envify: ^1.3.1 - prop-types: ^15.6.2 - react-router: 5.3.4 - tiny-invariant: ^1.0.2 - tiny-warning: ^1.0.0 + "@remix-run/router": 1.17.1 + react-router: 6.24.1 peerDependencies: - react: ">=15" - checksum: f04f727e2ed2e9d1d3830af02cc61690ff67b1524c0d18690582bfba0f4d14142ccc88fb6da6befad644fddf086f5ae4c2eb7048c67da8a0b0929c19426421b0 + react: ">=16.8" + react-dom: ">=16.8" + checksum: 458c6c539304984c47b0ad8d5d5b1f8859cc0845e47591d530cb4fcb13498f70a89b42bc4daeea55d57cfa08408b453bcf601cabb2c987f554cdcac13805caa8 languageName: node linkType: hard -"react-router@npm:5.3.4": - version: 5.3.4 - resolution: "react-router@npm:5.3.4" +"react-router@npm:6.24.1": + version: 6.24.1 + resolution: "react-router@npm:6.24.1" dependencies: - "@babel/runtime": ^7.12.13 - history: ^4.9.0 - hoist-non-react-statics: ^3.1.0 - loose-envify: ^1.3.1 - path-to-regexp: ^1.7.0 - prop-types: ^15.6.2 - react-is: ^16.6.0 - tiny-invariant: ^1.0.2 - tiny-warning: ^1.0.0 + "@remix-run/router": 1.17.1 peerDependencies: - react: ">=15" - checksum: e15c00dfef199249b4c6e6d98e5e76cc352ce66f3270f13df37cc069ddf7c05e43281e8c308fc407e4435d72924373baef1d2890e0f6b0b1eb423cf47315a053 + react: ">=16.8" + checksum: f50c78ca52c5154ab933c17708125e8bf71ccf2072993a80302526a0a23db9ceac6e36d5c891d62ccd16f13e60cd1b6533a2036523d1b09e0148ac49e34b2e83 languageName: node linkType: hard @@ -17187,15 +17166,15 @@ __metadata: linkType: hard "react-tooltip@npm:^5.21.1": - version: 5.27.0 - resolution: "react-tooltip@npm:5.27.0" + version: 5.27.1 + resolution: "react-tooltip@npm:5.27.1" dependencies: "@floating-ui/dom": ^1.6.1 classnames: ^2.3.0 peerDependencies: react: ">=16.14.0" react-dom: ">=16.14.0" - checksum: 4b105dcef7b3d166e359b97fdbbef9c622de3c91e3c9387f959495c66d4caefb25e38cd75e0258dac104c3814c0ae74b97807382d36f45dfae6200645bafd3a3 + checksum: 5ffba1bb0e9cf4f0b1576657a4500c911a1a18efc452f0d73e5696ac761968df712ea504d4ac9520159c9f32516305c48830b9767eb93528edd400d64f48c5c4 languageName: node linkType: hard @@ -17214,13 +17193,12 @@ __metadata: languageName: node linkType: hard -"react@npm:^17.0.1": - version: 17.0.2 - resolution: "react@npm:17.0.2" +"react@npm:^18.3.1": + version: 18.3.1 + resolution: "react@npm:18.3.1" dependencies: loose-envify: ^1.1.0 - object-assign: ^4.1.1 - checksum: 07ae8959acf1596f0550685102fd6097d461a54a4fd46a50f88a0cd7daaa97fdd6415de1dcb4bfe0da6aa43221a6746ce380410fa848acc60f8ac41f6649c148 + checksum: 283e8c5efcf37802c9d1ce767f302dd569dd97a70d9bb8c7be79a789b9902451e0d16334b05d73299b20f048cbc3c7d288bbbde10b701fa194e2089c237dbea3 languageName: node linkType: hard @@ -17531,13 +17509,6 @@ __metadata: languageName: node linkType: hard -"resolve-pathname@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-pathname@npm:3.0.0" - checksum: c6ec49b670dc35b9a303c47fa83ba9348a71e92d64a4c4bb85e1b659a29b407aa1ac1cb14a9b5b502982132ca77482bd80534bca147439d66880d35a137fe723 - languageName: node - linkType: hard - "resolve-url-loader@npm:^4.0.0": version: 4.0.0 resolution: "resolve-url-loader@npm:4.0.0" @@ -17858,13 +17829,12 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.20.2": - version: 0.20.2 - resolution: "scheduler@npm:0.20.2" +"scheduler@npm:^0.23.2": + version: 0.23.2 + resolution: "scheduler@npm:0.23.2" dependencies: loose-envify: ^1.1.0 - object-assign: ^4.1.1 - checksum: b0982e4b0f34f4ffa4f2f486161c0fd9ce9b88680b045dccbf250eb1aa4fd27413570645455187a83535e2370f5c667a251045547765408492bd883cbe95fcdb + checksum: 26383305e249651d4c58e6705d5f8425f153211aef95f15161c151f7b8de885f24751b377e4a0b3dd42cce09aad3f87a61dab7636859c0d89b7daf1a1e2a5c78 languageName: node linkType: hard @@ -19183,21 +19153,21 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.0.2": +"tiny-invariant@npm:^1.3.3": version: 1.3.3 resolution: "tiny-invariant@npm:1.3.3" checksum: 65af4a07324b591a059b35269cd696aba21bef2107f29b9f5894d83cc143159a204b299553435b03874ebb5b94d019afa8b8eff241c8a4cfee95872c2e1c1c4a languageName: node linkType: hard -"tiny-warning@npm:^1.0.0, tiny-warning@npm:^1.0.3": +"tiny-warning@npm:^1.0.3": version: 1.0.3 resolution: "tiny-warning@npm:1.0.3" checksum: ef8531f581b30342f29670cb41ca248001c6fd7975ce22122bd59b8d62b4fc84ad4207ee7faa95cde982fa3357cd8f4be650142abc22805538c3b1392d7084fa languageName: node linkType: hard -"tmp@npm:~0.2.1": +"tmp@npm:~0.2.3": version: 0.2.3 resolution: "tmp@npm:0.2.3" checksum: 3e809d9c2f46817475b452725c2aaa5d11985cf18d32a7a970ff25b568438e2c076c2e8609224feef3b7923fa9749b74428e3e634f6b8e520c534eef2fd24125 @@ -19917,9 +19887,9 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.16": - version: 1.0.16 - resolution: "update-browserslist-db@npm:1.0.16" +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" dependencies: escalade: ^3.1.2 picocolors: ^1.0.1 @@ -19927,7 +19897,7 @@ __metadata: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 5995399fc202adbb51567e4810e146cdf7af630a92cc969365a099150cb00597e425cc14987ca7080b09a4d0cfd2a3de53fbe72eebff171aed7f9bb81f9bf405 + checksum: a7452de47785842736fb71547651c5bbe5b4dc1e3722ccf48a704b7b34e4dcf633991eaa8e4a6a517ffb738b3252eede3773bef673ef9021baa26b056d63a5b9 languageName: node linkType: hard @@ -20079,13 +20049,6 @@ __metadata: languageName: node linkType: hard -"value-equal@npm:^1.0.1": - version: 1.0.1 - resolution: "value-equal@npm:1.0.1" - checksum: 79068098355483ef29f4d3753999ad880875b87625d7e9055cad9346ea4b7662aad3a66f87976801b0dd7a6f828ba973d28b1669ebcd37eaf88cc5f687c1a691 - languageName: node - linkType: hard - "vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" @@ -20905,8 +20868,8 @@ __metadata: linkType: hard "ws@npm:^8.13.0": - version: 8.17.1 - resolution: "ws@npm:8.17.1" + version: 8.18.0 + resolution: "ws@npm:8.18.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -20915,7 +20878,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe + checksum: 25eb33aff17edcb90721ed6b0eb250976328533ad3cd1a28a274bd263682e7296a6591ff1436d6cbc50fa67463158b062f9d1122013b361cec99a05f84680e06 languageName: node linkType: hard From 4fef37429eb1853c9d5ba8326ad91f123d17e9ae Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:39:44 -0500 Subject: [PATCH 14/21] Issue #557: View internal balances (#633) * initial balance draft * initial balance draft * bump sdk version * fix lock file * fix lock file * fix lock file * fix vault block issue --- package.json | 2 +- src/components/VaultBlock.tsx | 8 +++++++ src/components/VaultStats.tsx | 45 +++++++++++++++++++++++++++++++++++ src/utils/i18n/en.json | 1 + yarn.lock | 10 ++++---- 5 files changed, 60 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1cd79a1f..16798b23 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@ethersproject/address": "^5.0.10", "@ethersproject/experimental": "5.4.0", "@ethersproject/providers": "5.4.5", - "@opendollar/sdk": "1.7.4-rc.1", + "@opendollar/sdk": "1.7.4-rc.2", "@opendollar/svg-generator": "1.0.5", "@react-spring/web": "^9.7.3", "@sentry/cli": "^2.31.0", diff --git a/src/components/VaultBlock.tsx b/src/components/VaultBlock.tsx index 939719d7..dc37c457 100644 --- a/src/components/VaultBlock.tsx +++ b/src/components/VaultBlock.tsx @@ -12,6 +12,7 @@ interface VaultBlockProps { collateralRatio: string liquidationPrice: string className?: string + internalCollateralBalance: string } const VaultBlock = ({ @@ -23,6 +24,7 @@ const VaultBlock = ({ collateralRatio, liquidationPrice, className, + internalCollateralBalance, }: VaultBlockProps) => { const stateClass = returnState(riskState) ? returnState(riskState).toLowerCase() : 'dimmed' @@ -63,6 +65,12 @@ const VaultBlock = ({
{returnState(riskState) ? returnState(riskState) : 'Closed'}
+ {Number(internalCollateralBalance) > 0 && ( + + + {formatWithCommas(internalCollateralBalance)} + + )} diff --git a/src/components/VaultStats.tsx b/src/components/VaultStats.tsx index 4e58b040..755216ea 100644 --- a/src/components/VaultStats.tsx +++ b/src/components/VaultStats.tsx @@ -20,6 +20,8 @@ import { Tooltip as ReactTooltip } from 'react-tooltip' import { generateSvg } from '@opendollar/svg-generator' import { useWeb3React } from '@web3-react/core' import { useAddress } from '~/hooks/useAddress' + +import useGeb from '~/hooks/useGeb' import Skeleton from 'react-loading-skeleton' const VaultStats = ({ @@ -39,6 +41,7 @@ const VaultStats = ({ liquidationPrice: newLiquidationPrice, account, } = useSafeInfo(isModifying ? (isDeposit ? 'deposit_borrow' : 'repay_withdraw') : 'info') + const geb = useGeb() const { safeModel: safeState } = useStoreState((state) => state) const { singleSafe, liquidationData } = safeState @@ -111,6 +114,21 @@ const VaultStats = ({ return false }, [isModifying, parsedAmounts.leftInput, parsedAmounts.rightInput]) + const handleClaimClick = async () => { + if (!account) return + try { + const proxy = await geb.getProxyAction(account) + await proxy.collectTokenCollateral( + geb.contracts.safeManager.address, + geb.contracts.tokenCollateralJoin[collateralName].address, + Number(singleSafe?.id), + Number(singleSafe?.internalCollateralBalance) + ) + } catch (e) { + console.debug(e, 'Error in claiming internal balance') + } + } + return ( <> @@ -333,6 +351,23 @@ const VaultStats = ({ {`${returnRedRate()}%`} + {Number(singleSafe?.internalCollateralBalance) > 0 ? ( + + Internal Balance + + + + CLAIM + + {formatWithCommas(singleSafe?.internalCollateralBalance || '0', 2, 2)} + + + ) : ( + <> + )} @@ -534,3 +569,13 @@ const InfoIcon = styled.div` margin-top: 4px; } ` + +const ClaimLink = styled.span` + cursor: pointer; + font-family: 'Open Sans', sans-serif; + font-size: ${(props) => props.theme.font.xxSmall}; + text-decoration: underline; + color: ${(props) => props.theme.colors.blueish}; + margin-left: 5px; + padding-top: 1px; +` diff --git a/src/utils/i18n/en.json b/src/utils/i18n/en.json index 25bb5f0a..b8516342 100644 --- a/src/utils/i18n/en.json +++ b/src/utils/i18n/en.json @@ -76,6 +76,7 @@ "repay_withdraw": "Repay & Withdraw", "confirmations_info": "You need to wait for 10 block confirmations to make sure that your account address does not change.", "annual_redemption_tip": "Rate at which OD is devalued or revalued over 1 year.", + "internal_balance_tip": "The internal balance of the Vault left in the system after the Vault is liquidated.", "liquidation_price_tip": "Collateral price under which this Vault can get liquidated. The liquidation price varies with the redemption price.", "liquidation_penalty_tip": "Liquidations ask for more OD than you have minted in your Vault, and apply a discount on the latest oracle price in order to incentivize bidding.", "app": "App", diff --git a/yarn.lock b/yarn.lock index 30345f33..f444afe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3695,15 +3695,15 @@ __metadata: languageName: node linkType: hard -"@opendollar/sdk@npm:1.7.4-rc.1": - version: 1.7.4-rc.1 - resolution: "@opendollar/sdk@npm:1.7.4-rc.1" +"@opendollar/sdk@npm:1.7.4-rc.2": + version: 1.7.4-rc.2 + resolution: "@opendollar/sdk@npm:1.7.4-rc.2" dependencies: "@opendollar/abis": 0.0.0-605371bd ethers: 5.4.7 peerDependencies: utf-8-validate: ^5.0.2 - checksum: 74974d2ca6af9030f04bb3bfeb692cd2028d83cc1fa606708069fba03bf0f3fdb9a4368dfbfb9f4403f3c4df04ac6bd7ad7d1e48d7a9852afb865dcb10fa2aed + checksum: f589ecf8c9e86fcf920841bb9ec142c59e482f6afb44c4140e63d982f9cc9638c7e5a84efea39d6000a3be5fe6ff9bddf3bef522d6fb1d755ff32c68d5f81fe0 languageName: node linkType: hard @@ -15006,7 +15006,7 @@ __metadata: "@ethersproject/address": ^5.0.10 "@ethersproject/experimental": 5.4.0 "@ethersproject/providers": 5.4.5 - "@opendollar/sdk": 1.7.4-rc.1 + "@opendollar/sdk": 1.7.4-rc.2 "@opendollar/svg-generator": 1.0.5 "@react-spring/web": ^9.7.3 "@sentry/cli": ^2.31.0 From 24ff2c444615a3c1d2863eca9b6ca5066a67ffe0 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:40:07 -0500 Subject: [PATCH 15/21] fix infinite loop when pushed from other page (#640) --- src/containers/Explore/ExploreTable.tsx | 166 ++++++++++++------------ src/containers/Vaults/VaultDetails.tsx | 2 +- 2 files changed, 83 insertions(+), 85 deletions(-) diff --git a/src/containers/Explore/ExploreTable.tsx b/src/containers/Explore/ExploreTable.tsx index fd509df7..7e3100e8 100644 --- a/src/containers/Explore/ExploreTable.tsx +++ b/src/containers/Explore/ExploreTable.tsx @@ -12,6 +12,7 @@ import './index.css' import styled from 'styled-components' import Button from '~/components/Button' import { useState } from 'react' +import { useHistory } from 'react-router-dom' type Vault = { id: string @@ -36,94 +37,91 @@ const parseDebtAmount = (value: string): number => { } const columnHelper = createColumnHelper() -const columns: ColumnDef[] = [ - columnHelper.accessor('id', { - header: () => 'ID', - cell: (info) => info.getValue(), - sortingFn: 'alphanumeric', - enableSorting: true, - }), - columnHelper.accessor('image', { - header: () => '', - cell: (info) => { - const image = info.row.original.image - const vaultID = info.row.original.id - return image ? ( - - - - ) : null - }, - enableSorting: false, - }), - columnHelper.accessor('collateralAmount', { - header: () => 'Collateral Amount', - cell: (info) => info.getValue().toLocaleString(), - sortingFn: (rowA, rowB) => { - const a = rowA.getValue('collateralAmount') - const b = rowB.getValue('collateralAmount') - return a - b - }, - filterFn: (row, columnId, filterValue) => { - const value = row.getValue(columnId) - return value.toString().includes(filterValue) - }, - }), - columnHelper.accessor('collateral', { - header: () => 'Collateral', - cell: (info) => info.getValue(), - sortingFn: 'alphanumeric', - enableSorting: true, - }), - columnHelper.accessor('debtAmount', { - header: () => 'Debt Amount', - cell: (info) => info.getValue(), - sortingFn: (rowA, rowB) => { - const a = parseDebtAmount(rowA.getValue('debtAmount')) - const b = parseDebtAmount(rowB.getValue('debtAmount')) - return a - b - }, - filterFn: (row, columnId, filterValue) => { - const value = parseDebtAmount(row.getValue(columnId)) - return value.toString().includes(filterValue) - }, - }), - columnHelper.accessor('riskStatus', { - header: () => 'Risk Status', - cell: (info) => info.getValue().toLocaleString(), - sortingFn: (rowA, rowB) => { - const a = riskStatusMapping[rowA.getValue('riskStatus')] || 1 - const b = riskStatusMapping[rowB.getValue('riskStatus')] || 1 - return a - b - }, - filterFn: (row, columnId, filterValue) => { - const value = row.getValue(columnId) - return value.includes(filterValue) - }, - }), - columnHelper.accessor('actions', { - header: '', - cell: (info) => { - return ( - - - - ) - }, - enableSorting: false, - }), -] const ExploreTable = ({ data }: { data: Vault[] }) => { const [sorting, setSorting] = useState([]) const [globalFilter, setGlobalFilter] = useState('') + const history = useHistory() + + const columns: ColumnDef[] = [ + columnHelper.accessor('id', { + header: () => 'ID', + cell: (info) => info.getValue(), + sortingFn: 'alphanumeric', + enableSorting: true, + }), + columnHelper.accessor('image', { + header: () => '', + cell: (info) => { + const image = info.row.original.image + const vaultID = info.row.original.id + return image ? ( + + + + ) : null + }, + enableSorting: false, + }), + columnHelper.accessor('collateralAmount', { + header: () => 'Collateral Amount', + cell: (info) => info.getValue().toLocaleString(), + sortingFn: (rowA, rowB) => { + const a = rowA.getValue('collateralAmount') + const b = rowB.getValue('collateralAmount') + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = row.getValue(columnId) + return value.toString().includes(filterValue) + }, + }), + columnHelper.accessor('collateral', { + header: () => 'Collateral', + cell: (info) => info.getValue(), + sortingFn: 'alphanumeric', + enableSorting: true, + }), + columnHelper.accessor('debtAmount', { + header: () => 'Debt Amount', + cell: (info) => info.getValue(), + sortingFn: (rowA, rowB) => { + const a = parseDebtAmount(rowA.getValue('debtAmount')) + const b = parseDebtAmount(rowB.getValue('debtAmount')) + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = parseDebtAmount(row.getValue(columnId)) + return value.toString().includes(filterValue) + }, + }), + columnHelper.accessor('riskStatus', { + header: () => 'Risk Status', + cell: (info) => info.getValue().toLocaleString(), + sortingFn: (rowA, rowB) => { + const a = riskStatusMapping[rowA.getValue('riskStatus')] || 1 + const b = riskStatusMapping[rowB.getValue('riskStatus')] || 1 + return a - b + }, + filterFn: (row, columnId, filterValue) => { + const value = row.getValue(columnId) + return value.includes(filterValue) + }, + }), + columnHelper.accessor('actions', { + header: '', + cell: (info) => { + return ( + + + + ) + }, + enableSorting: false, + }), + ] const table = useReactTable({ data: data, diff --git a/src/containers/Vaults/VaultDetails.tsx b/src/containers/Vaults/VaultDetails.tsx index eb76aa11..45fa0d50 100644 --- a/src/containers/Vaults/VaultDetails.tsx +++ b/src/containers/Vaults/VaultDetails.tsx @@ -95,7 +95,7 @@ const VaultDetails = () => { safeActions.setSingleSafe(null) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [safe, safeActions, geb, liquidationData, safeActions.setLiquidationData, account]) + }, [safeId, geb]) useEffect(() => { if (!account || !provider) return From 206eb244bae19cd6b91592a7e688686711ba4853 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Thu, 18 Jul 2024 15:40:34 -0500 Subject: [PATCH 16/21] Issue #630: Explore page design improvements (#639) * explore page improvements * reuse function * fix svg rendering issue --- src/containers/Explore/ExploreTable.tsx | 10 +- src/containers/Explore/index.tsx | 31 ++----- src/utils/generateSVGRing.ts | 117 ++++++++++++++++++++++++ src/utils/helper.ts | 2 +- 4 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 src/utils/generateSVGRing.ts diff --git a/src/containers/Explore/ExploreTable.tsx b/src/containers/Explore/ExploreTable.tsx index 7e3100e8..f671d7d2 100644 --- a/src/containers/Explore/ExploreTable.tsx +++ b/src/containers/Explore/ExploreTable.tsx @@ -308,15 +308,13 @@ const SVGContainer = styled.div` display: flex; align-items: center; justify-content: center; - width: 139px; - height: 139px; + width: 70px; + height: 70px; position: relative; - margin: 20px 10px 20px 10px; - box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.3), 0 12px 40px 0 rgba(0, 0, 0, 0.25); @media (max-width: 768px) { - width: 294px; - height: 294px; + width: 140px; + height: 140px; justify-content: center; margin-left: auto; margin-right: auto; diff --git a/src/containers/Explore/index.tsx b/src/containers/Explore/index.tsx index f8d64744..5c7450e9 100644 --- a/src/containers/Explore/index.tsx +++ b/src/containers/Explore/index.tsx @@ -1,21 +1,12 @@ import styled from 'styled-components' import { useState, useEffect } from 'react' -// @ts-ignore -import { generateSvg } from '@opendollar/svg-generator' import ExploreTable from './ExploreTable' import { ethers } from 'ethers' -import { - parseRay, - formatDataNumber, - multiplyRates, - transformToAnnualRate, - calculateRiskStatusText, - ratioChecker, - parseFormattedNumber, -} from '~/utils' +import { parseRay, formatDataNumber, calculateRiskStatusText, ratioChecker, parseFormattedNumber } from '~/utils' import { AllVaults, useVaultSubgraph } from '~/hooks/useVaultSubgraph' import useAnalyticsData from '~/hooks/useAnalyticsData' import useGeb from '~/hooks/useGeb' +import { generateSVGRing } from '~/utils/generateSVGRing' const Explore: React.FC = () => { const [isLoading, setIsLoading] = useState(true) @@ -28,7 +19,7 @@ const Explore: React.FC = () => { return parseFloat(value.replace(/,/g, '')) } - const getSafeData = async () => { + const getSafeData = () => { setIsLoading(true) const tableRows = [] @@ -41,14 +32,6 @@ const Explore: React.FC = () => { +ethers.utils.formatUnits(analyticsData.tokenAnalyticsData[vault.collateralType].currentPrice) ).toFixed(2)}` - const stabilityFee = transformToAnnualRate( - multiplyRates( - analyticsData.tokenAnalyticsData[vault.collateralType].stabilityFee.toString(), - analyticsData.redemptionRate?.toString() - ) || '0', - 27 - ) - const formattedDebt = parseFormattedNumber(formatDataNumber(vault.debt)) let cratio = 0 if (formattedDebt !== 0) { @@ -62,13 +45,11 @@ const Explore: React.FC = () => { correctCollateralizationRatio = '∞' } else if (Number(cratio) === 0 && parseFormattedNumber(formatDataNumber(vault.collateral)) === 0) { correctCollateralizationRatio = 0 + } else { + correctCollateralizationRatio = 0 } const svgData = { - vaultID: vault.id, - stabilityFee, - debtAmount: formatDataNumber(vault.debt), - collateralAmount: formatDataNumber(vault.collateral) + ' ' + vault.collateralType, collateralizationRatio: correctCollateralizationRatio, liqRatio: Number( parseRay(analyticsData.tokenAnalyticsData[vault.collateralType].liquidationCRatio) @@ -86,7 +67,7 @@ const Explore: React.FC = () => { let svg = null try { - svg = await generateSvg(svgData) + svg = generateSVGRing(svgData, 210, 420, `svg-${vault.id}`) } catch (e) { console.error(e) } diff --git a/src/utils/generateSVGRing.ts b/src/utils/generateSVGRing.ts new file mode 100644 index 00000000..8be437ea --- /dev/null +++ b/src/utils/generateSVGRing.ts @@ -0,0 +1,117 @@ +import { ratioChecker } from '~/utils/helper' + +interface Values { + collateralizationRatio: string | number + liqRatio: number + safetyRatio: number +} + +const calculateColor = (riskStatus: string): string => { + switch (riskStatus) { + case 'LIQUIDATION': + return '#E45200' + case 'HIGH': + return '#E45200' + case 'ELEVATED': + return '#FCBF3B' + case 'LOW': + return '#459d00' + case 'NO': + return '#5DBA14' + default: + return '#459d00' + } +} + +const calculateRiskStatusText = (riskStatusNumeric: number): string => { + switch (riskStatusNumeric) { + case 0: + return 'NO' + case 1: + return 'LOW' + case 2: + return 'ELEVATED' + case 3: + return 'HIGH' + case 4: + return 'LIQUIDATION' + default: + return 'LOW' + } +} + +export const generateSVGRing = (values: Values, width: number, height: number, id: string): string => { + const { collateralizationRatio, liqRatio, safetyRatio } = values + + const riskStatusNumeric = ratioChecker(collateralizationRatio as number, liqRatio, safetyRatio) + let riskStatus: string + + riskStatus = calculateRiskStatusText(riskStatusNumeric) + + const actualBackgroundGradientColor = calculateColor(riskStatus) + + let strokeDashArrayValue = parseFloat(collateralizationRatio.toString()) + + if ((strokeDashArrayValue <= 100 && strokeDashArrayValue !== 0) || strokeDashArrayValue >= 200) { + strokeDashArrayValue = 100 + } else if (strokeDashArrayValue === 0 || Number.isNaN(strokeDashArrayValue)) { + strokeDashArrayValue = 0 + } else { + strokeDashArrayValue = strokeDashArrayValue - 100 + } + + const uniqueClassName = `chart-${id}` + + const ringParts = [ + ` + + + + + + + `, + ] + + return ringParts.join('') +} diff --git a/src/utils/helper.ts b/src/utils/helper.ts index ef509e36..5bf21e51 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -292,7 +292,7 @@ export const calculateRiskStatusText = (riskStatusNumeric: Number) => { */ export const ratioChecker = (currentLiquidationRatio: number, liqRatio: number, safetyRatio: number) => { if (currentLiquidationRatio == null || Number.isNaN(currentLiquidationRatio) || !liqRatio || !safetyRatio) { - console.error('Error calculating risk state') + console.debug('Error calculating risk state') return 1 } const currentLiquidationRatioAsDecimal = currentLiquidationRatio / 100 From 041f7c6608d26eead4defeb7b69346c2ab6573c3 Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Mon, 22 Jul 2024 11:29:09 -0500 Subject: [PATCH 17/21] fix navigate issue (#643) --- src/containers/Explore/ExploreTable.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/containers/Explore/ExploreTable.tsx b/src/containers/Explore/ExploreTable.tsx index f671d7d2..90b61e11 100644 --- a/src/containers/Explore/ExploreTable.tsx +++ b/src/containers/Explore/ExploreTable.tsx @@ -12,7 +12,7 @@ import './index.css' import styled from 'styled-components' import Button from '~/components/Button' import { useState } from 'react' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' type Vault = { id: string @@ -41,7 +41,7 @@ const columnHelper = createColumnHelper() const ExploreTable = ({ data }: { data: Vault[] }) => { const [sorting, setSorting] = useState([]) const [globalFilter, setGlobalFilter] = useState('') - const history = useHistory() + const navigate = useNavigate() const columns: ColumnDef[] = [ columnHelper.accessor('id', { @@ -113,7 +113,7 @@ const ExploreTable = ({ data }: { data: Vault[] }) => { cell: (info) => { return ( - From ce85d498063c572d8225d0b84cee4e5eab8d8565 Mon Sep 17 00:00:00 2001 From: Patrick Gallagher Date: Mon, 22 Jul 2024 16:50:29 -0700 Subject: [PATCH 18/21] Add GRT (#652) * Bump sdk to v1.7.4-rc.3 * lint --- package.json | 2 +- public/index.html | 4 +- src/assets/grt.svg | 11 +++++ src/chains.ts | 2 +- src/containers/Vaults/CreateVault.tsx | 63 ++++++++++++------------ src/containers/Vaults/ModifyVault.tsx | 69 +++++++++++---------------- src/utils/tokens.ts | 5 ++ yarn.lock | 10 ++-- 8 files changed, 85 insertions(+), 81 deletions(-) create mode 100644 src/assets/grt.svg diff --git a/package.json b/package.json index 16798b23..1c63525e 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@ethersproject/address": "^5.0.10", "@ethersproject/experimental": "5.4.0", "@ethersproject/providers": "5.4.5", - "@opendollar/sdk": "1.7.4-rc.2", + "@opendollar/sdk": "1.7.4-rc.3", "@opendollar/svg-generator": "1.0.5", "@react-spring/web": "^9.7.3", "@sentry/cli": "^2.31.0", diff --git a/public/index.html b/public/index.html index bd43f768..2dea807c 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,7 @@ script-src 'self' blob: https://kb.wowto.ai https://app.wowto.ai http://cdn.matomo.cloud/usekeyp.matomo.cloud/matomo.js https://cdn.matomo.cloud/usekeyp.matomo.cloud/matomo.js https://cdn.matomo.cloud/matomo.js https://usekeyp.matomo.cloud/matomo.js; media-src 'self'; img-src 'self' data: blob: https://explorer-api.walletconnect.com https://usekeyp.matomo.cloud https://app.opendollar.com; - connect-src 'self' blob: https://eth-pokt.nodies.app http://localhost:3000 https://*.quiknode.pro https://api.opensea.io https://api.fuul.xyz https://api.camelot.exchange https://opt-mainnet.g.alchemy.com https://arb-mainnet.g.alchemy.com https://mainnet.optimism.io/ https://eth.llamarpc.com https://base.llamarpc.com https://polygon-bor-rpc.publicnode.com https://eth-pokt.nodies.app https://polygon-pokt.nodies.app https://op-pokt.nodies.app https://arb-pokt.nodies.app https://holy-damp-firefly.arbitrum-mainnet.quiknode.pro https://api.studio.thegraph.com https://od-subgraph-node-image.onrender.com https://usekeyp.matomo.cloud https://o1016103.ingest.us.sentry.io/api/4507153379295232/envelope/ https://o1016103.ingest.us.sentry.io/api/4507153379295232/security/ https://arbitrum-sepolia.infura.io https://arbitrum-sepolia.blockpi.network/v1/rpc/public https://arbitrum.blockpi.network/v1/rpc/public https://optimism.blockpi.network wss://relay.walletconnect.com/ https://verify.walletconnect.org wss://www.walletlink.org/rpc https://explorer-api.walletconnect.com https://chain-proxy.wallet.coinbase.com https://rpc.walletconnect.com https://bot.opendollar.com https://bot.dev.opendollar.com https://subgraph.reflexer.finance/subgraphs/name/reflexer-labs/rai https://api.country.is/ ; + connect-src 'self' blob: https://virtual.arbitrum.rpc.tenderly.co https://eth-pokt.nodies.app http://localhost:3000 https://*.quiknode.pro https://api.opensea.io https://api.fuul.xyz https://api.camelot.exchange https://opt-mainnet.g.alchemy.com https://arb-mainnet.g.alchemy.com https://mainnet.optimism.io/ https://eth.llamarpc.com https://base.llamarpc.com https://polygon-bor-rpc.publicnode.com https://eth-pokt.nodies.app https://polygon-pokt.nodies.app https://op-pokt.nodies.app https://arb-pokt.nodies.app https://holy-damp-firefly.arbitrum-mainnet.quiknode.pro https://api.studio.thegraph.com https://od-subgraph-node-image.onrender.com https://usekeyp.matomo.cloud https://o1016103.ingest.us.sentry.io/api/4507153379295232/envelope/ https://o1016103.ingest.us.sentry.io/api/4507153379295232/security/ https://arbitrum-sepolia.infura.io https://arbitrum-sepolia.blockpi.network/v1/rpc/public https://arbitrum.blockpi.network/v1/rpc/public https://optimism.blockpi.network wss://relay.walletconnect.com/ https://verify.walletconnect.org wss://www.walletlink.org/rpc https://explorer-api.walletconnect.com https://chain-proxy.wallet.coinbase.com https://rpc.walletconnect.com https://bot.opendollar.com https://bot.dev.opendollar.com https://subgraph.reflexer.finance/subgraphs/name/reflexer-labs/rai https://api.country.is/ ; object-src 'self' blob:; form-action 'self'; font-src 'self' data: https://fonts.gstatic.com; @@ -61,7 +61,7 @@ - + diff --git a/src/assets/grt.svg b/src/assets/grt.svg new file mode 100644 index 00000000..c9c33753 --- /dev/null +++ b/src/assets/grt.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/chains.ts b/src/chains.ts index 47783e05..51a60f47 100644 --- a/src/chains.ts +++ b/src/chains.ts @@ -28,7 +28,7 @@ const ETH: AddEthereumChainParameter['nativeCurrency'] = { export const RPC_URL_ETHEREUM = process.env.REACT_APP_RPC_URL_ETHEREUM ? process.env.REACT_APP_RPC_URL_ETHEREUM : 'https://eth.llamarpc.com' -export const RPC_URL_ARBITRUM = 'https://arbitrum.blockpi.network/v1/rpc/public' +export const RPC_URL_ARBITRUM = RPC_URL || 'https://arbitrum.blockpi.network/v1/rpc/public' export const RPC_URL_OPTIMISM = 'https://op-pokt.nodies.app' export const RPC_URL_POLYGON = 'https://polygon-bor-rpc.publicnode.com' export const RPC_URL_BASE = 'https://base.llamarpc.com' diff --git a/src/containers/Vaults/CreateVault.tsx b/src/containers/Vaults/CreateVault.tsx index 7f61100f..4a31fb71 100644 --- a/src/containers/Vaults/CreateVault.tsx +++ b/src/containers/Vaults/CreateVault.tsx @@ -8,7 +8,7 @@ import { Tooltip as ReactTooltip } from 'react-tooltip' import styled from 'styled-components' import { ethers } from 'ethers' import { useTransactionAdder } from '~/hooks' -import { DEFAULT_SAFE_STATE, getTokenLogo, formatNumber, formatWithCommas, checkUserHasBalance } from '~/utils' +import { DEFAULT_SAFE_STATE, getTokenLogo, formatNumber, formatWithCommas } from '~/utils' import { useStoreActions, useStoreState } from '~/store' import TokenInput from '~/components/TokenInput' import Modal from '~/components/Modals/Modal' @@ -55,13 +55,12 @@ const CreateVault = ({ safeModel: safeActions, connectWalletModel: connectWalletActions, popupsModel: popupsActions, - bridgeModel: bridgeModelActions, } = useStoreActions((state) => state) const { leftInput, rightInput } = parsedAmounts const { onLeftInput, onRightInput, onClearAll: clearAll } = useInputsHandlers() const { t } = useTranslation() const isValid = !error - const [needsBridge, setNeedsBridge] = useState(false) + // const [needsBridge, setNeedsBridge] = useState(false) const formattedCollateralBalances = useMemo(() => { return collaterals.reduce((acc, collateral) => { const balance = tokensFetchedData[collateral.symbol]?.balanceE18 || '0' @@ -229,22 +228,22 @@ const CreateVault = ({ connectWalletActions.setIsStepLoading(false) } - useEffect(() => { - if (!account || !provider || !selectedCollateral) return - const checkNeedsBridge = async () => { - setNeedsBridge( - await checkUserHasBalance(selectedCollateral.address, account, provider, parsedAmounts.leftInput) - ) - } - checkNeedsBridge() - }, [account, provider, selectedCollateral, parsedAmounts.leftInput]) - - const setBridge = (reason: string) => { - bridgeModelActions.setReason(reason) - bridgeModelActions.setFromTokenSymbol(selectedCollateral?.symbol) - bridgeModelActions.setToTokenAddress(selectedCollateral?.address) - navigate('/bridge') - } + // useEffect(() => { + // if (!account || !provider || !selectedCollateral) return + // const checkNeedsBridge = async () => { + // setNeedsBridge( + // await checkUserHasBalance(selectedCollateral.address, account, provider, parsedAmounts.leftInput) + // ) + // } + // checkNeedsBridge() + // }, [account, provider, selectedCollateral, parsedAmounts.leftInput]) + + // const setBridge = (reason: string) => { + // bridgeModelActions.setReason(reason) + // bridgeModelActions.setFromTokenSymbol(selectedCollateral?.symbol) + // bridgeModelActions.setToTokenAddress(selectedCollateral?.address) + // navigate('/bridge') + // } return ( <> @@ -298,7 +297,7 @@ const CreateVault = ({ )} - {needsBridge && !parsedAmounts.leftInput && ( + {/* {needsBridge && !parsedAmounts.leftInput && ( {`Insufficient funds. Move assets to Arbitrum using the `} - )} + )} */} @@ -336,7 +335,7 @@ const CreateVault = ({ data_test_id="deposit_borrow" decimals={Number(selectedCollateralDecimals)} /> - {needsBridge && parsedAmounts.leftInput && ( + {/* {needsBridge && parsedAmounts.leftInput && ( {`Insufficient funds. Move assets to Arbitrum using the `} - )} + )} */}
props.theme.colors.primary}; ` -const BridgeLabel = styled.div` - color: #e39806; - font-size: 14px; - margin-top: 10px; -` +// const BridgeLabel = styled.div` +// color: #e39806; +// font-size: 14px; +// margin-top: 10px; +// ` -const BridgeButton = styled.span` - color: ${(props) => props.theme.colors.primary}; - cursor: pointer; -` +// const BridgeButton = styled.span` +// color: ${(props) => props.theme.colors.primary}; +// cursor: pointer; +// ` diff --git a/src/containers/Vaults/ModifyVault.tsx b/src/containers/Vaults/ModifyVault.tsx index 37c32401..65d153a5 100644 --- a/src/containers/Vaults/ModifyVault.tsx +++ b/src/containers/Vaults/ModifyVault.tsx @@ -1,14 +1,7 @@ import { useEffect, useState } from 'react' import { BigNumber, ethers } from 'ethers' import styled from 'styled-components' -import { - DEFAULT_SAFE_STATE, - formatNumber, - formatWithCommas, - getTokenLogo, - checkUserHasBalance, - bridgeTokens, -} from '~/utils' +import { DEFAULT_SAFE_STATE, formatNumber, formatWithCommas, getTokenLogo } from '~/utils' import useGeb, { useProxyAddress } from '~/hooks/useGeb' import Review from './Review' import { useStoreActions, useStoreState } from '~/store' @@ -26,22 +19,18 @@ import { useTokenApproval, ApprovalState, } from '~/hooks' -import { useNavigate } from 'react-router-dom' const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOwner: boolean; vaultId: string }) => { - const [needsBridge, setNeedsBridge] = useState(false) const { safeModel: safeState, connectWalletModel } = useStoreState((state) => state) - const { provider, account, chainId } = useActiveWeb3React() + const { provider, account } = useActiveWeb3React() const geb = useGeb() const [showPreview, setShowPreview] = useState(false) const { singleSafe } = safeState - const navigate = useNavigate() const type = isDeposit ? 'deposit_borrow' : 'repay_withdraw' const { safeModel: safeActions, connectWalletModel: connectWalletActions, popupsModel: popupsActions, - bridgeModel: bridgeModelActions, } = useStoreActions((state) => state) const { @@ -117,14 +106,14 @@ const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOw true, parsedAmounts.rightInput === availableHai && availableHai !== '0' ) - useEffect(() => { - if (!account || !provider || !singleSafe?.collateralName || !chainId || !bridgeTokens[chainId]) return - const token = bridgeTokens[chainId].tokens.find((token: any) => token.name === singleSafe?.collateralName) - const checkNeedsBridge = async () => { - setNeedsBridge(await checkUserHasBalance(token.address, account, provider, parsedAmounts.leftInput)) - } - checkNeedsBridge() - }, [account, provider, chainId, singleSafe?.collateralName, parsedAmounts.leftInput]) + // useEffect(() => { + // if (!account || !provider || !singleSafe?.collateralName || !chainId || !bridgeTokens[chainId]) return + // const token = bridgeTokens[chainId].tokens.find((token: any) => token.name === singleSafe?.collateralName) + // const checkNeedsBridge = async () => { + // setNeedsBridge(await checkUserHasBalance(token.address, account, provider, parsedAmounts.leftInput)) + // } + // checkNeedsBridge() + // }, [account, provider, chainId, singleSafe?.collateralName, parsedAmounts.leftInput]) const onMaxLeftInput = () => { if (isDeposit) { @@ -250,12 +239,12 @@ const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOw } } - const setBridge = (reason: string) => { - if (!singleSafe) return - bridgeModelActions.setReason(reason) - bridgeModelActions.setFromTokenSymbol(singleSafe?.collateralName) - navigate('/bridge') - } + // const setBridge = (reason: string) => { + // if (!singleSafe) return + // bridgeModelActions.setReason(reason) + // bridgeModelActions.setFromTokenSymbol(singleSafe?.collateralName) + // navigate('/bridge') + // } return ( <> @@ -412,7 +401,7 @@ const ModifyVault = ({ isDeposit, isOwner, vaultId }: { isDeposit: boolean; isOw {error && (leftInput || rightInput) && ( - {needsBridge && parsedAmounts.leftInput && ( + {/* {needsBridge && parsedAmounts.leftInput && ( {`Insufficient funds. Move assets to Arbitrum using the `} - )} - {!needsBridge && (leftInput || rightInput) &&

Error: {error}

} + )} */} + {(leftInput || rightInput) &&

Error: {error}

}
)} @@ -564,13 +553,13 @@ const SideLabel = styled.div` line-height: 26.4px; margin-bottom: 10px; ` -const BridgeLabel = styled.div` - color: #e39806; - font-size: 14px; - margin-top: 10px; -` - -const BridgeButton = styled.span` - color: ${(props) => props.theme.colors.primary}; - cursor: pointer; -` +// const BridgeLabel = styled.div` +// color: #e39806; +// font-size: 14px; +// margin-top: 10px; +// ` + +// const BridgeButton = styled.span` +// color: ${(props) => props.theme.colors.primary}; +// cursor: pointer; +// ` diff --git a/src/utils/tokens.ts b/src/utils/tokens.ts index d18c9c65..92908167 100644 --- a/src/utils/tokens.ts +++ b/src/utils/tokens.ts @@ -2,6 +2,8 @@ import WETH from '../assets/eth.svg' import OP from '../assets/op-img.svg' import OD from '../assets/od-token.svg' import ODG from '../assets/odg-token.svg' +import GRT from '../assets/grt.svg' + import WSTETH from '../assets/wsteth.svg' import CBETH from '../assets/cbETH.svg' import RETH from '../assets/rETH.svg' @@ -36,6 +38,8 @@ const importTokenIcon = (tokenName: string) => { return MAGIC case 'PUFETH': return PUFETH + case 'GRT': + return GRT default: return require('../assets/unknown-token.svg').default } @@ -62,6 +66,7 @@ export const TOKEN_LOGOS: { [key: string]: string } = { ARB: importTokenIcon('ARB'), MAGIC: importTokenIcon('MAGIC'), PUFETH: importTokenIcon('PUFETH'), + GRT: importTokenIcon('GRT'), ETH: importTokenIcon('WETH'), } diff --git a/yarn.lock b/yarn.lock index f444afe3..dd4a640f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3695,15 +3695,15 @@ __metadata: languageName: node linkType: hard -"@opendollar/sdk@npm:1.7.4-rc.2": - version: 1.7.4-rc.2 - resolution: "@opendollar/sdk@npm:1.7.4-rc.2" +"@opendollar/sdk@npm:1.7.4-rc.3": + version: 1.7.4-rc.3 + resolution: "@opendollar/sdk@npm:1.7.4-rc.3" dependencies: "@opendollar/abis": 0.0.0-605371bd ethers: 5.4.7 peerDependencies: utf-8-validate: ^5.0.2 - checksum: f589ecf8c9e86fcf920841bb9ec142c59e482f6afb44c4140e63d982f9cc9638c7e5a84efea39d6000a3be5fe6ff9bddf3bef522d6fb1d755ff32c68d5f81fe0 + checksum: 8ed9174b048af9d688f1160ecc470c929da2874f0f4f6624f703cafde7b298914996afa0e0fb10f4dcbe0f9d2dd507db441278a7fa24c190c336cdc92c763bf8 languageName: node linkType: hard @@ -15006,7 +15006,7 @@ __metadata: "@ethersproject/address": ^5.0.10 "@ethersproject/experimental": 5.4.0 "@ethersproject/providers": 5.4.5 - "@opendollar/sdk": 1.7.4-rc.2 + "@opendollar/sdk": 1.7.4-rc.3 "@opendollar/svg-generator": 1.0.5 "@react-spring/web": ^9.7.3 "@sentry/cli": ^2.31.0 From 6ce1e4f62c488a084f41ca75cd925a6a080b603a Mon Sep 17 00:00:00 2001 From: Jacob Habib <47253537+jahabeebs@users.noreply.github.com> Date: Mon, 22 Jul 2024 18:54:03 -0500 Subject: [PATCH 19/21] Issue #642: Reconnect on refresh (#644) * reconnect on refresh * fix loading logic --- src/components/CreateVaultStep.tsx | 8 +-- .../connectorCards/WalletConnectV2Card.tsx | 4 +- src/containers/Vaults/index.tsx | 54 +++++++------------ src/hooks/useActiveWeb3React.ts | 19 ++++--- 4 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/components/CreateVaultStep.tsx b/src/components/CreateVaultStep.tsx index 924cad3a..e7d8bd9c 100644 --- a/src/components/CreateVaultStep.tsx +++ b/src/components/CreateVaultStep.tsx @@ -10,11 +10,11 @@ interface Props { btnText: string handleClick: () => void isDisabled: boolean - isLoading: boolean + isStepLoading: boolean id: string } -const CreateVaultStep = ({ stepNumber, title, text, isDisabled, isLoading, btnText, handleClick }: Props) => { +const CreateVaultStep = ({ stepNumber, title, text, isDisabled, isStepLoading, btnText, handleClick }: Props) => { const { t } = useTranslation() return ( @@ -27,8 +27,8 @@ const CreateVaultStep = ({ stepNumber, title, text, isDisabled, isLoading, btnTe