Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

New all chains #3491

Merged
merged 36 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
1629fb5
new-all-chains, Test speed
PseudoElement Jan 31, 2025
2002ad5
new-all-chains, use dev2 url
PseudoElement Jan 31, 2025
b324326
new-all-chains, add filter by balances and rank more than 7
PseudoElement Jan 31, 2025
df60cae
new-all-chains, fix balance patching for lastQueriedTokens
PseudoElement Feb 3, 2025
9ccdf8c
new-all-chains, revert update
PseudoElement Feb 3, 2025
e4dc9b7
new-all-chains, load 10_000 tokens
PseudoElement Feb 3, 2025
6fc2fdb
new-all-chains, delete pipe
PseudoElement Feb 3, 2025
c176435
new-all-chains, add background balance loading on wallet changed
PseudoElement Feb 4, 2025
b0f71d4
new-all-chains, set pageSize 5000
PseudoElement Feb 4, 2025
e549678
change 5k to 7.5k
usrbad Feb 5, 2025
7d681b5
new-all-chains, fix duplicates in patchTokensBalances
PseudoElement Feb 5, 2025
19107cb
new-all-chains, fix balanceCalculatedStatus when empty list laoded
PseudoElement Feb 5, 2025
ff2e1b6
new-all-chains, load balance for allchains on addressChanged if not l…
PseudoElement Feb 5, 2025
3d4b3ef
new-all-chains, set timeout 20sec
PseudoElement Feb 5, 2025
da75b4b
new-all-chains, fix low perfomance of patchTokensBalances, use effici…
PseudoElement Feb 5, 2025
8d27d8a
new-all-chains, fix convertTokensListToMap
PseudoElement Feb 5, 2025
b168f44
new-all-chains, add map in patchLastQueriedTokensBalances
PseudoElement Feb 5, 2025
12331eb
new-all-chains, merge allchains with balances with common tokensList,…
PseudoElement Feb 6, 2025
3ceab32
new-all-chains, delete worker
PseudoElement Feb 6, 2025
9161a01
new-all-chains, delete class
PseudoElement Feb 6, 2025
464acde
new-all-chains, fix keys of map
PseudoElement Feb 6, 2025
febfcf4
new-all-chains, delete log
PseudoElement Feb 6, 2025
2ac789c
new-all-chains, add treigger on balancePatching
PseudoElement Feb 6, 2025
6a3799e
new-all-chains, fix tokens$ undefined after cookie and cache clean
PseudoElement Feb 6, 2025
d4cd871
new-all-chains, load allTokens on wallet change, updateTokensList on…
PseudoElement Feb 7, 2025
86f0fe3
new-all-chains, fix balance shown after fast wallet disconnect
PseudoElement Feb 7, 2025
03120e9
new-all-chains. remove resetter
PseudoElement Feb 7, 2025
e2e773a
new-all-chains, fix not removed balances after wallet disconnect, fix…
PseudoElement Feb 7, 2025
20b174a
new-all-chains, delete log
PseudoElement Feb 7, 2025
e1d5a04
new-all-chains, fix metis NATIVE
PseudoElement Feb 10, 2025
99731e5
new-all-chains, add comment
PseudoElement Feb 10, 2025
9637399
new-all-chains, fix metis native double
PseudoElement Feb 10, 2025
1cda2bb
new-all-chains, filter metis token in fetchTokensListForAllChains
PseudoElement Feb 10, 2025
547f020
new-all-chains, remove hardcoded url v2/tokens/top
PseudoElement Feb 10, 2025
8baee92
Merge branch 'master' into new-all-chains
PseudoElement Feb 10, 2025
01ff0bc
new-all-chains, replace utils to service
PseudoElement Feb 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@
"karmaConfig": "src/karma.conf.js",
"styles": ["src/styles.scss"],
"scripts": [],
"assets": ["src/favicon.ico", "src/assets"]
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
Expand Down
33 changes: 20 additions & 13 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AfterViewInit, Component, Inject, isDevMode } from '@angular/core';
import { AfterViewInit, ChangeDetectorRef, Component, Inject, isDevMode } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { CookieService } from 'ngx-cookie-service';
Expand All @@ -8,7 +8,7 @@
import { QueryParamsService } from '@core/services/query-params/query-params.service';
import { GoogleTagManagerService } from '@core/services/google-tag-manager/google-tag-manager.service';
import { isSupportedLanguage } from '@shared/models/languages/supported-languages';
import { catchError, first, map, switchMap } from 'rxjs/operators';
import { catchError, first, map } from 'rxjs/operators';
import { forkJoin, Observable, of } from 'rxjs';
import { WINDOW } from '@ng-web-apis/common';
import { RubicWindow } from '@shared/utils/rubic-window';
Expand All @@ -18,6 +18,7 @@
import { TokensStoreService } from './core/services/tokens/tokens-store.service';
import { BalanceLoadingStateService } from './core/services/tokens/balance-loading-state.service';
import { AssetsSelectorStateService } from './features/trade/components/assets-selector/services/assets-selector-state/assets-selector-state.service';
import { TradePageService } from './features/trade/services/trade-page/trade-page.service';

@Component({
selector: 'app-root',
Expand All @@ -43,7 +44,9 @@
private readonly walletConnectorService: WalletConnectorService,
private readonly tokensStoreService: TokensStoreService,
private readonly balanceLoadingStateService: BalanceLoadingStateService,
private readonly assetsSelectorStateService: AssetsSelectorStateService
private readonly assetsSelectorStateService: AssetsSelectorStateService,
private readonly tradePageService: TradePageService,
private readonly cdr: ChangeDetectorRef
) {
this.printTimestamp();
this.setupLanguage();
Expand All @@ -58,16 +61,20 @@
}

private subscribeOnWalletChanges(): void {
this.walletConnectorService.addressChange$
.pipe(
switchMap(() => {
this.balanceLoadingStateService.resetBalanceCalculatingStatuses();
return this.tokensStoreService.startBalanceCalculating(
this.assetsSelectorStateService.assetType
);
})
)
.subscribe();
this.walletConnectorService.addressChange$.subscribe(() => {

Check warning on line 64 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / Check code quality

Calling `subscribe` in a component is forbidden; use an `async` pipe instead

Check warning on line 64 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / Check code quality

Forbids calling `subscribe` without an accompanying `takeUntil`
this.balanceLoadingStateService.resetBalanceCalculatingStatuses();

// load allchains in background if token's selector closed if not loaded yet
if (
this.assetsSelectorStateService.assetType !== 'allChains' &&
this.tradePageService.formContent === 'form' &&
!this.balanceLoadingStateService.isBalanceCalculated('allChains')
) {
this.tokensStoreService.startBalanceCalculating('allChains');
}

this.tokensStoreService.startBalanceCalculating(this.assetsSelectorStateService.assetType);
});
}

/**
Expand Down Expand Up @@ -130,7 +137,7 @@
* Waits for all initializing observables to complete.
*/
private initApp(): void {
forkJoin([this.loadPlatformConfig(), this.initQueryParamsSubscription()]).subscribe(

Check warning on line 140 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / Check code quality

Calling `subscribe` in a component is forbidden; use an `async` pipe instead

Check warning on line 140 in src/app/app.component.ts

View workflow job for this annotation

GitHub Actions / Check code quality

Forbids calling `subscribe` without an accompanying `takeUntil`
([isBackendAvailable]) => {
this.isBackendAvailable = isBackendAvailable;
document.getElementById('loader')?.classList.add('disabled');
Expand Down
29 changes: 26 additions & 3 deletions src/app/core/services/backend/tokens-api/tokens-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ import { defaultTokens } from './models/default-tokens';
import { blockchainsToFetch, blockchainsWithOnePage } from './constants/fetch-blockchains';
import {
BackendBlockchain,
BLOCKCHAIN_NAME,
BlockchainName,
FROM_BACKEND_BLOCKCHAINS,
TO_BACKEND_BLOCKCHAINS
} from 'rubic-sdk';
import { ENVIRONMENT } from 'src/environments/environment';

import { compareAddresses, compareTokens } from '@app/shared/utils/utils';

/**
* Perform backend requests and transforms to get valid tokens.
*/
Expand Down Expand Up @@ -292,9 +295,29 @@ export class TokensApiService {
}

public fetchTokensListForAllChains(): Observable<List<Token>> {
return this.httpService
.get<BackendTokenForAllChains[]>('v2/tokens/allchains')
.pipe(map(backendTokens => TokensApiService.prepareTokens(backendTokens)));
return forkJoin([
this.httpService
.get<TokensBackendResponse>('v2/tokens/top')
.pipe(map(backendTokens => TokensApiService.prepareTokens(backendTokens.results))),
this.httpService
.get<BackendTokenForAllChains[]>('v2/tokens/allchains')
.pipe(map(backendTokens => TokensApiService.prepareTokens(backendTokens)))
]).pipe(
map(([topTokens, allChainsTokens]) => {
// filters unique tokens from v2/tokens/allchains and api/v2/tokens/?pageSize=5000
return topTokens.concat(allChainsTokens).reduce((acc, token) => {
// not show 2nd metis native token in selector
if (
token.blockchain === BLOCKCHAIN_NAME.METIS &&
compareAddresses(token.address, '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000')
) {
return acc;
}
const repeated = acc.find(t => compareTokens(t, token));
return repeated ? acc : acc.push(token);
}, List() as List<Token>);
})
);
}

public getFakeTokens(): BackendToken[] {
Expand Down
2 changes: 1 addition & 1 deletion src/app/core/services/http/http.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class HttpService {
const request$ = this.http.get<T>((path || SERVER_REST_URL) + (url || ''), {
params: data || {}
});

// @FIX set timeout to 5_000
return path ? request$ : request$.pipe(timeout(5_000), retry(1));
}

Expand Down
112 changes: 84 additions & 28 deletions src/app/core/services/tokens/balance-loader.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
import { TokenAmount } from '@app/shared/models/tokens/token-amount';
import BigNumber from 'bignumber.js';
import { List } from 'immutable';
import { BlockchainName, BlockchainsInfo, Injector, Web3Public, Web3Pure } from 'rubic-sdk';
import {
BlockchainName,
BlockchainsInfo,
Injector,
waitFor,
Web3Public,
Web3Pure
} from 'rubic-sdk';
import { AuthService } from '../auth/auth.service';
import { ChainsToLoadFirstly, isTopChain } from './constants/first-loaded-chains';
import { BalanceLoadingStateService } from './balance-loading-state.service';
import { AssetType } from '@app/features/trade/models/asset';
import { getWeb3PublicSafe } from '@app/shared/utils/is-native-address-safe';
import { Iterable } from './utils/iterable';

type TokensListOfTopChainsWithOtherChains = {
[key in BlockchainName]: Token[];
Expand All @@ -29,8 +37,12 @@

public updateBalancesForAllChains(
tokensList: List<TokenAmount | Token>,
onBalanceLoaded: (tokensWithBalances: List<TokenAmount>, patchAllChains: boolean) => void
onChainLoaded: (tokensWithBalances: List<TokenAmount>, patchAllChains: boolean) => void,
onFinish?: (allChainsTokensWithBalances: List<TokenAmount>) => void
): void {
// can be empty when v2/tokens/allchains response lower then first startBalanceCalculating call in app.component.ts
if (!tokensList.size) return;

const tokensByChain: TokensListOfTopChainsWithOtherChains = {
TOP_CHAINS: {}
} as TokensListOfTopChainsWithOtherChains;
Expand All @@ -51,6 +63,20 @@

this.balanceLoadingStateService.setBalanceLoading('allChains', true);

const allTokensWithPositiveBalances = List([]).asMutable() as List<TokenAmount>;
const chainsCount = Object.keys(tokensByChain).length;
const iterator = new Iterable(chainsCount);

// make some when every chain from tokensByChain loaded tokens with balances
if (onFinish) {
(async () => {
while (!iterator.done && !!this.authService.userAddress) {
await waitFor(100);
}
onFinish(allTokensWithPositiveBalances);
})();
}

for (const key in tokensByChain) {
if (key === 'TOP_CHAINS') {
const topChainsTokens = tokensByChain.TOP_CHAINS;
Expand All @@ -68,20 +94,32 @@
}
);

Promise.all(promises).then(balances => {
const flattenBalances = balances.flat();
const flattenTokens = Object.values(topChainsTokens).flat();
const tokensWithBalances = flattenTokens.map((token, idx) => ({
...token,
amount: flattenBalances[idx]
? Web3Pure.fromWei(flattenBalances[idx], token.decimals)
: new BigNumber(NaN)
})) as TokenAmount[];

onBalanceLoaded(List(tokensWithBalances), true);
this.balanceLoadingStateService.setBalanceCalculated('allChains', true);
this.balanceLoadingStateService.setBalanceLoading('allChains', false);
});
Promise.all(promises)
.then(balances => {
const flattenBalances = balances.flat();
const flattenTokens = Object.values(topChainsTokens).flat();
const tokensWithBalancesList = List(
flattenTokens.map((token, idx) => ({
...token,
amount: flattenBalances[idx]
? Web3Pure.fromWei(flattenBalances[idx], token.decimals)
: new BigNumber(NaN)
})) as TokenAmount[]
);

const tokensWithPositiveBalances = tokensWithBalancesList.filter(
t => !t.amount.isNaN() && t.amount.gt(0)
);
allTokensWithPositiveBalances.concat(tokensWithPositiveBalances);

if (balances.length) {
this.balanceLoadingStateService.setBalanceCalculated('allChains', true);
this.balanceLoadingStateService.setBalanceLoading('allChains', false);
}

onChainLoaded(tokensWithBalancesList, true);
})
.finally(() => iterator.next());
} else {
const chain = key as Exclude<keyof TokensListOfTopChainsWithOtherChains, 'TOP_CHAINS'>;
const chainTokens = tokensByChain[chain];
Expand All @@ -96,31 +134,49 @@
.catch(() => chainTokens.map(() => new BigNumber(NaN)))
: Promise.resolve(chainTokens.map(() => new BigNumber(NaN)));

balancesPromise.then(balances => {
const tokensWithBalances = chainTokens.map((token, idx) => ({
...token,
amount: balances[idx]
? Web3Pure.fromWei(balances[idx], token.decimals)
: new BigNumber(NaN)
})) as TokenAmount[];

onBalanceLoaded(List(tokensWithBalances), true);
});
balancesPromise
.then(balances => {
const tokensWithBalancesList = List(
chainTokens.map((token, idx) => ({
...token,
amount: balances[idx]
? Web3Pure.fromWei(balances[idx], token.decimals)
: new BigNumber(NaN)
})) as TokenAmount[]
);

const tokensWithPositiveBalances = tokensWithBalancesList.filter(t => {
// not show 2nd metis native token in selector
// if (
// t.blockchain === BLOCKCHAIN_NAME.METIS &&
// compareAddresses(t.address, '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000')
// ) {
// return false;
// }
if (t.amount.isNaN() || t.amount.lte(0)) return false;

return false;
});
allTokensWithPositiveBalances.concat(tokensWithPositiveBalances);

onChainLoaded(tokensWithBalancesList, true);
})
.finally(() => iterator.next());
}
}
}

public async updateBalancesForSpecificChain(
tokensList: List<Token>,
blockchain: AssetType,
onBalanceLoaded: (tokensWithBalances: List<TokenAmount>, patchAllChains: boolean) => void
onFinish: (tokensWithBalances: List<TokenAmount>, userAddress: string | undefined) => void
): Promise<void> {
this.balanceLoadingStateService.setBalanceLoading(blockchain, true);
const tokensWithBalances = await this.getTokensWithBalance(tokensList);

onBalanceLoaded(tokensWithBalances, false);
this.balanceLoadingStateService.setBalanceCalculated(blockchain, true);
this.balanceLoadingStateService.setBalanceLoading(blockchain, false);
onFinish(tokensWithBalances, this.authService.userAddress);
}

/**
Expand Down Expand Up @@ -168,7 +224,7 @@

return List(allTokensWithAmountArray);
} catch (err) {
console.log('%cgetAllChainsTokenBalances_ERROR', 'color: red; font-size: 20px;', err);

Check warning on line 227 in src/app/core/services/tokens/balance-loader.service.ts

View workflow job for this annotation

GitHub Actions / Check code quality

Unexpected console statement
return List([]);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ export class BalanceLoadingStateService {
public isBalanceLoading$(blockchain: AssetType): Observable<boolean> {
return this._isBalanceLoading$[blockchain].asObservable();
}

public isBalanceLoading(blockchain: AssetType): boolean {
return this._isBalanceLoading$[blockchain].value;
}
}
9 changes: 6 additions & 3 deletions src/app/core/services/tokens/tokens-network.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { List } from 'immutable';
import { Token } from '@shared/models/tokens/token';
import { BalanceLoaderService } from './balance-loader.service';
import { BalanceLoadingStateService } from './balance-loading-state.service';
import { TokensUpdaterService } from './tokens-updater.service';

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -50,7 +51,8 @@ export class TokensNetworkService {
private readonly balanceLoaderService: BalanceLoaderService,
private readonly balanceLoadingStateService: BalanceLoadingStateService,
private readonly tokensApiService: TokensApiService,
private readonly authService: AuthService
private readonly authService: AuthService,
private readonly tokensUpdaterService: TokensUpdaterService
) {
this.setupSubscriptions();
}
Expand All @@ -63,7 +65,7 @@ export class TokensNetworkService {
}),
tap(backendTokens => {
this.tokensStoreService.updateStorageTokens(backendTokens);
this.tokensStoreService.patchTokens(backendTokens, false);
this.tokensStoreService.patchTokens(backendTokens);
}),
switchMap(backendTokens => {
const uniqueBlockchains = [...new Set(backendTokens.map(bT => bT.blockchain))];
Expand Down Expand Up @@ -142,7 +144,8 @@ export class TokensNetworkService {
})
)
.subscribe((tokens: TokenAmount[]) => {
this.tokensStoreService.patchTokens(List(tokens), false);
this.tokensStoreService.patchTokens(List(tokens));
this.tokensUpdaterService.triggerUpdateTokens();
});
}
}
Loading
Loading