Skip to content

Commit

Permalink
Move addressParamLoader logic to API level
Browse files Browse the repository at this point in the history
  • Loading branch information
lubej committed Dec 1, 2023
1 parent 419c2fa commit 53f5284
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 73 deletions.
1 change: 0 additions & 1 deletion src/app/components/Account/ContractCreatorInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ export const DelayedContractCreatorInfo: FC<{
contractOasisAddress: string | undefined
}> = ({ scope, contractOasisAddress }) => {
const accountQuery = useGetRuntimeAccountsAddress(
undefined,
scope.network,
scope.layer as Runtime,
contractOasisAddress!,
Expand Down
25 changes: 25 additions & 0 deletions src/app/hooks/useTransformToOasisAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useEffect, useState } from 'react'
import { getOasisAddress } from '../utils/helpers'

export const useTransformToOasisAddress = (ethOrOasisAddress: string): string | null => {
const [oasisAddress, setOasisAddress] = useState<string | null>(null)

useEffect(() => {
let shouldUpdate = true

const transformToOasisAddress = async (addr: string) => {
const oasisAddr = await getOasisAddress(addr)
if (shouldUpdate) {
setOasisAddress(oasisAddr)
}
}

transformToOasisAddress(ethOrOasisAddress)

return () => {
shouldUpdate = false
}
}, [ethOrOasisAddress, setOasisAddress])

return oasisAddress
}
33 changes: 26 additions & 7 deletions src/app/pages/AccountDetailsPage/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import { useSearchParamsPagination } from '../../components/Table/useSearchParam
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE } from '../../config'
import { SearchScope } from '../../../types/searchScope'
import { EventFilterMode } from '../../components/RuntimeEvents/EventListFilterSwitch'
import { useTransformToOasisAddress } from '../../hooks/useTransformToOasisAddress'

export const useAccount = (scope: SearchScope, oasisAddress: string, searchParam?: string) => {
export const useAccount = (scope: SearchScope, address: string) => {
const { network, layer } = scope
if (layer === Layer.consensus) {
// There can be no ERC-20 or ERC-721 tokens on consensus
throw AppErrors.UnsupportedLayer
}
const query = useGetRuntimeAccountsAddress(searchParam, network, layer, oasisAddress!)
const query = useGetRuntimeAccountsAddress(network, layer, address)
const account = query.data?.data
const { isLoading, isError, isFetched } = query

Expand All @@ -33,13 +34,20 @@ export const useAccountTransactions = (scope: SearchScope, address: string) => {
// Loading transactions on the consensus layer is not supported yet.
// We should use useGetConsensusTransactions()
}

const oasisAddress = useTransformToOasisAddress(address)
const query = useGetRuntimeTransactions(
network,
layer, // This is OK since consensus has been handled separately
{
limit: NUMBER_OF_ITEMS_ON_SEPARATE_PAGE,
offset: offset,
rel: address,
rel: oasisAddress!,
},
{
query: {
enabled: !!oasisAddress,
},
},
)
const { isFetched, isLoading, data } = query
Expand Down Expand Up @@ -69,10 +77,21 @@ export const useAccountEvents = (scope: SearchScope, address: string, filterMode
// Loading events on the consensus layer is not supported yet.
// We should use useGetConsensusEvents()
}
const query = useGetRuntimeEvents(network, layer, {
rel: address,
// TODO: implement filtering for non-transactional events
})

const oasisAddress = useTransformToOasisAddress(address)
const query = useGetRuntimeEvents(
network,
layer,
{
rel: oasisAddress!,
// TODO: implement filtering for non-transactional events
},
{
query: {
enabled: !!oasisAddress,
},
},
)
const { isFetched, isLoading, isError, data } = query
const events = data?.data.events.filter(
event => filterMode === EventFilterMode.All || event.type !== RuntimeEventType.accountstransfer,
Expand Down
11 changes: 5 additions & 6 deletions src/app/pages/AccountDetailsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { SearchScope } from '../../../types/searchScope'
import { AccountDetailsCard } from './AccountDetailsCard'
import { AccountEventsCard } from './AccountEventsCard'
import { EventFilterMode } from '../../components/RuntimeEvents/EventListFilterSwitch'
import { AddressLoaderData } from '../../../types/loaders'

export type AccountDetailsContext = {
scope: SearchScope
Expand All @@ -32,10 +31,10 @@ export const AccountDetailsPage: FC = () => {
const { t } = useTranslation()

const scope = useRequiredScopeParam()
const { searchParam, oasisAddress } = useLoaderData() as AddressLoaderData
const { account, isLoading: isAccountLoading, isError } = useAccount(scope, oasisAddress, searchParam)
const address = useLoaderData() as string
const { account, isLoading: isAccountLoading, isError } = useAccount(scope, address)
const isContract = !!account?.evm_contract
const { token, isLoading: isTokenLoading } = useTokenInfo(scope, oasisAddress, isContract)
const { token, isLoading: isTokenLoading } = useTokenInfo(scope, address, isContract)

const tokenPriceInfo = useTokenPrice(account?.ticker || Ticker.ROSE)
const [eventFilterMode, setEventFilterMode] = useState<EventFilterMode>(EventFilterMode.All)
Expand All @@ -44,7 +43,7 @@ export const AccountDetailsPage: FC = () => {
isLoading: areEventsLoading,
isError: isEventsError,
events,
} = useAccountEvents(scope, oasisAddress, eventFilterMode)
} = useAccountEvents(scope, address, eventFilterMode)

const tokenTransfersLink = useHref(`token-transfers#${accountTokenTransfersContainerId}`)
const erc20Link = useHref(`tokens/erc-20#${accountTokenContainerId}`)
Expand All @@ -56,7 +55,7 @@ export const AccountDetailsPage: FC = () => {

const isLoading = isAccountLoading || isTokenLoading

const context: AccountDetailsContext = { scope, address: oasisAddress, account }
const context: AccountDetailsContext = { scope, address, account }

return (
<PageLayout>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/SearchResultsPage/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function useRuntimeAccountConditionally(
.map(scope =>
// See explanation above
// eslint-disable-next-line react-hooks/rules-of-hooks
useGetRuntimeAccountsAddress(undefined, scope.network, scope.layer as Runtime, address!, {
useGetRuntimeAccountsAddress(scope.network, scope.layer as Runtime, address!, {
query: {
enabled: !!address,
},
Expand Down
49 changes: 40 additions & 9 deletions src/app/pages/TokenDashboardPage/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SearchScope } from '../../../types/searchScope'
import { useSearchParamsPagination } from '../../components/Table/useSearchParamsPagination'
import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE } from '../../config'
import { useComprehensiveSearchParamsPagination } from '../../components/Table/useComprehensiveSearchParamsPagination'
import { useTransformToOasisAddress } from '../../hooks/useTransformToOasisAddress'

export const useTokenInfo = (scope: SearchScope, address: string, enabled = true) => {
const { network, layer } = scope
Expand Down Expand Up @@ -43,16 +44,23 @@ export const useTokenTransfers = (scope: SearchScope, address: string) => {
// Loading transactions on the consensus layer is not supported yet.
// We should use useGetConsensusTransactions()
}

const oasisAddress = useTransformToOasisAddress(address)
const query = useGetRuntimeEvents(
network,
layer, // This is OK since consensus has been handled separately
{
...pagination.paramsForQuery,
rel: address,
rel: oasisAddress!,
type: 'evm.log',
// The following is the hex-encoded signature for Transfer(address,address,uint256)
evm_log_signature: 'ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
},
{
query: {
enabled: !!oasisAddress,
},
},
)

const { isFetched, isLoading, data } = query
Expand All @@ -78,10 +86,22 @@ export const useTokenHolders = (scope: SearchScope, address: string) => {
throw AppErrors.UnsupportedLayer
// There are no token holders on the consensus layer.
}
const query = useGetRuntimeEvmTokensAddressHolders(network, layer, address, {
limit: NUMBER_OF_ITEMS_ON_SEPARATE_PAGE,
offset: offset,
})

const oasisAddress = useTransformToOasisAddress(address)
const query = useGetRuntimeEvmTokensAddressHolders(
network,
layer,
oasisAddress!,
{
limit: NUMBER_OF_ITEMS_ON_SEPARATE_PAGE,
offset: offset,
},
{
query: {
enabled: !!oasisAddress,
},
},
)

const { isFetched, isLoading, data } = query

Expand Down Expand Up @@ -115,10 +135,21 @@ export const useTokenInventory = (scope: SearchScope, address: string) => {
throw AppErrors.UnsupportedLayer
// There are no tokens on the consensus layer.
}
const query = useGetRuntimeEvmTokensAddressNfts(network, layer, address, {
limit: NUMBER_OF_INVENTORY_ITEMS,
offset: offset,
})
const oasisAddress = useTransformToOasisAddress(address)
const query = useGetRuntimeEvmTokensAddressNfts(
network,
layer,
oasisAddress!,
{
limit: NUMBER_OF_INVENTORY_ITEMS,
offset: offset,
},
{
query: {
enabled: !!oasisAddress,
},
},
)
const { isFetched, isLoading, data } = query
const inventory = data?.data.evm_nfts

Expand Down
13 changes: 6 additions & 7 deletions src/app/pages/TokenDashboardPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { contractCodeContainerId } from '../AccountDetailsPage/ContractCodeCard'
import { tokenHoldersContainerId } from './TokenHoldersCard'
import { SearchScope } from '../../../types/searchScope'
import { tokenInventoryContainerId } from './TokenInventoryCard'
import { AddressLoaderData } from '../../../types/loaders'

export type TokenDashboardContext = {
scope: SearchScope
Expand All @@ -28,9 +27,9 @@ export const TokenDashboardPage: FC = () => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()
const scope = useRequiredScopeParam()
const { oasisAddress } = useLoaderData() as AddressLoaderData
const address = useLoaderData() as string

const { isError } = useTokenInfo(scope, oasisAddress)
const { isError } = useTokenInfo(scope, address)

if (isError) {
throw AppErrors.InvalidAddress
Expand All @@ -43,15 +42,15 @@ export const TokenDashboardPage: FC = () => {

const context: TokenDashboardContext = {
scope,
address: oasisAddress,
address,
}

return (
<PageLayout>
<TokenTitleCard scope={scope} address={oasisAddress} />
<TokenSnapshot scope={scope} address={oasisAddress} />
<TokenTitleCard scope={scope} address={address} />
<TokenSnapshot scope={scope} address={address} />
{!isMobile && <Divider variant="layout" sx={{ mt: isMobile ? 4 : 0 }} />}
<TokenDetailsCard scope={scope} address={oasisAddress} />
<TokenDetailsCard scope={scope} address={address} />
<RouterTabs
tabs={[
{ label: t('tokens.transfers'), to: tokenTransfersLink },
Expand Down
15 changes: 4 additions & 11 deletions src/app/utils/route-utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { LoaderFunctionArgs } from 'react-router-dom'
import { getOasisAddress, isValidTxHash } from './helpers'
import { isValidTxHash } from './helpers'
import { isValidBlockHeight, isValidOasisAddress, isValidEthAddress } from './helpers'
import { AppError, AppErrors } from '../../types/errors'
import { EvmTokenType, Layer } from '../../oasis-nexus/api'
import { Network } from '../../types/network'
import { SearchScope } from '../../types/searchScope'
import { AddressLoaderData } from '../../types/loaders'

export type SpecifiedPerEnabledLayer<T = any> = {
[N in keyof (typeof RouteUtils)['ENABLED_LAYERS_FOR_NETWORK']]: {
Expand Down Expand Up @@ -142,16 +141,10 @@ const validateTxHashParam = (hash: string) => {
return true
}

export const addressParamLoader = async ({ params }: LoaderFunctionArgs): Promise<AddressLoaderData> => {
const searchParam = params.address!
validateAddressParam(searchParam)
// TODO: remove conversion when API supports querying by EVM address
const oasisAddress = await getOasisAddress(searchParam)
export const addressParamLoader = ({ params }: LoaderFunctionArgs): string => {
validateAddressParam(params.address!)

return {
oasisAddress,
searchParam,
}
return params.address!
}

export const blockHeightParamLoader = async ({ params }: LoaderFunctionArgs) => {
Expand Down
Loading

0 comments on commit 53f5284

Please sign in to comment.