Skip to content
This repository has been archived by the owner on Mar 11, 2024. It is now read-only.

Commit

Permalink
Merge pull request #777 from alephium/fetch-tokens
Browse files Browse the repository at this point in the history
Improve loading experience (like, a lot!)
  • Loading branch information
nop33 authored Aug 14, 2023
2 parents 1ff64d1 + 2fd8f00 commit f7a2002
Show file tree
Hide file tree
Showing 18 changed files with 343 additions and 127 deletions.
136 changes: 115 additions & 21 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
"electron-updater": "^5.3.0"
},
"devDependencies": {
"@alephium/sdk": "0.7.2",
"@alephium/token-list": "^0.0.8",
"@alephium/sdk": "0.7.5",
"@alephium/token-list": "^0.0.11",
"@alephium/walletconnect-provider": "^0.13.0",
"@alephium/web3": "^0.13.0",
"@alephium/web3": "^0.16.1",
"@electron/notarize": "^1.2.3",
"@json-rpc-tools/utils": "^1.7.6",
"@reduxjs/toolkit": "^1.9.1",
Expand Down
76 changes: 53 additions & 23 deletions src/api/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,73 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { TokenBalances } from '@alephium/sdk'
import { explorer } from '@alephium/web3'

import client from '@/api/client'
import { Address, AddressDataSyncResult, AddressHash } from '@/types/addresses'
import {
Address,
AddressBalancesSyncResult,
AddressHash,
AddressTokensSyncResult,
AddressTransactionsSyncResult
} from '@/types/addresses'

export const fetchAddressesData = async (addressHashes: AddressHash[]): Promise<AddressDataSyncResult[]> => {
const results = [] as AddressDataSyncResult[]
export const fetchAddressesTokens = async (addressHashes: AddressHash[]): Promise<AddressTokensSyncResult[]> => {
const results = []
let pageTotalResults
let page = 1

for (const hash of addressHashes) {
const tokenBalances = []

while (pageTotalResults === undefined || pageTotalResults === 100) {
const pageResults = await client.explorer.addresses.getAddressesAddressTokensBalance(hash, { limit: 100, page })

tokenBalances.push(...pageResults)

pageTotalResults = pageResults.length
page += 1
}

results.push({
hash,
tokenBalances
})
}

return results
}

export const fetchAddressesTransactions = async (
addressHashes: AddressHash[]
): Promise<AddressTransactionsSyncResult[]> => {
const results = []

for (const addressHash of addressHashes) {
const balances = await client.explorer.addresses.getAddressesAddressBalance(addressHash)
const txNumber = await client.explorer.addresses.getAddressesAddressTotalTransactions(addressHash)
const transactions = await client.explorer.addresses.getAddressesAddressTransactions(addressHash, { page: 1 })
const mempoolTransactions = await client.explorer.addresses.getAddressesAddressMempoolTransactions(addressHash)
const tokenIds = await client.explorer.addresses.getAddressesAddressTokens(addressHash)

const tokenResults = await Promise.allSettled(
tokenIds.map((id) =>
client.explorer.addresses
.getAddressesAddressTokensTokenIdBalance(addressHash, id)
.then((data) => ({ id, ...data }))
)
)
results.push({
hash: addressHash,
txNumber,
transactions,
mempoolTransactions
})
}

return results
}

export const fetchAddressesBalances = async (addressHashes: AddressHash[]): Promise<AddressBalancesSyncResult[]> => {
const results = []

const tokens = (
tokenResults.filter(({ status }) => status === 'fulfilled') as PromiseFulfilledResult<TokenBalances>[]
).map(({ value }) => value)
for (const addressHash of addressHashes) {
const balances = await client.explorer.addresses.getAddressesAddressBalance(addressHash)

results.push({
hash: addressHash,
details: {
...balances,
txNumber
},
transactions,
mempoolTransactions,
tokens
...balances
})
}

Expand Down
8 changes: 1 addition & 7 deletions src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,11 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { ExplorerProvider, NodeProvider } from '@alephium/web3'
import fetchRetry from 'fetch-retry'

import { exponentialBackoffFetchRetry } from '@/api/fetchRetry'
import { defaultSettings } from '@/storage/settings/settingsPersistentStorage'
import { NetworkSettings } from '@/types/settings'

export const exponentialBackoffFetchRetry = fetchRetry(fetch, {
retryOn: [429],
retries: 10,
retryDelay: (attempt) => Math.pow(2, attempt) * 1000
})

export class Client {
explorer: ExplorerProvider
node: NodeProvider
Expand Down
25 changes: 25 additions & 0 deletions src/api/fetchRetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
Copyright 2018 - 2023 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import fetchRetry from 'fetch-retry'

export const exponentialBackoffFetchRetry = fetchRetry(fetch, {
retryOn: [429],
retries: 10,
retryDelay: (attempt) => Math.pow(2, attempt) * 1000
})
2 changes: 1 addition & 1 deletion src/components/TransactionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const TransactionList = ({
const confirmedTxs = useAppSelector((s) => selectAddressesConfirmedTransactions(s, addressHashes))
const pendingTxs = useAppSelector((s) => selectAddressesPendingTransactions(s, addressHashes))
const stateUninitialized = useAppSelector(selectIsStateUninitialized)
const finishedLoadingData = useAppSelector((s) => !s.addresses.loading)
const finishedLoadingData = useAppSelector((s) => !s.addresses.loadingTransactions)
const allAddressTxPagesLoaded = useAppSelector(selectHaveAllPagesLoaded)

const [selectedTransaction, setSelectedTransaction] = useState<AddressConfirmedTransaction>()
Expand Down
2 changes: 1 addition & 1 deletion src/modals/SendModals/AssetAmountsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ const AssetAmountsInput = ({
}

useEffect(() => {
const addressTokenIds = address.tokens.map((token) => token.id)
const addressTokenIds = address.tokens.map((token) => token.tokenId)
const filteredAssetAmounts = assetAmounts.filter(
(asset) => addressTokenIds.includes(asset.id) || asset.id === ALPH.id
)
Expand Down
Loading

0 comments on commit f7a2002

Please sign in to comment.