Skip to content

Commit

Permalink
refactor(HW-630): refactor explorer urls (#2050)
Browse files Browse the repository at this point in the history
Co-authored-by: iGroza <[email protected]>
  • Loading branch information
iGroza and iGroza committed Aug 23, 2024
1 parent fec3ca1 commit 3e3fd5e
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 56 deletions.
4 changes: 2 additions & 2 deletions src/components/account-detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import {
InfoBlock,
Text,
} from '@app/components/ui';
import {app} from '@app/contexts';
import {createTheme} from '@app/helpers';
import {I18N} from '@app/i18n';
import {RemoteProviderConfig} from '@app/models/provider';
import {Wallet} from '@app/models/wallet';
import {sendNotification} from '@app/services';
import {GRADIENT_END, GRADIENT_START} from '@app/variables/common';
Expand Down Expand Up @@ -76,7 +76,7 @@ export const AccountDetail = observer(
title={I18N.evmTitle}
component={null}
/>
{RemoteProviderConfig.isBech32Enabled && (
{app.provider.config.isBech32Enabled && (
<TopTabNavigator.Tab
name={TabNames.bech32}
title={I18N.bech32Title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import {
Text,
TextVariant,
} from '@app/components/ui';
import {app} from '@app/contexts';
import {createTheme} from '@app/helpers';
import {AddressUtils} from '@app/helpers/address-utils';
import {Feature, isFeatureEnabled} from '@app/helpers/is-feature-enabled';
import {useCalculatedDimensionsValue} from '@app/hooks/use-calculated-dimensions-value';
import {I18N} from '@app/i18n';
import {RemoteProviderConfig} from '@app/models/provider';
import {Wallet} from '@app/models/wallet';
import {sendNotification} from '@app/services';
import {WalletType} from '@app/types';
Expand Down Expand Up @@ -117,7 +117,7 @@ export const SettingsAccountDetail = observer(

<Text variant={TextVariant.t14}>{wallet?.address}</Text>
</TouchableOpacity>
{RemoteProviderConfig.isBech32Enabled && (
{app.provider.config.isBech32Enabled && (
<>
<View style={styles.hDevider} />
<TouchableOpacity
Expand Down
5 changes: 2 additions & 3 deletions src/components/swap/swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {shortAddress} from '@app/helpers/short-address';
import {useSumAmount} from '@app/hooks';
import {I18N} from '@app/i18n';
import {Contracts} from '@app/models/contracts';
import {RemoteProviderConfig} from '@app/models/provider';
import {Wallet} from '@app/models/wallet';
import {Balance} from '@app/services/balance';
import {
Expand Down Expand Up @@ -254,9 +253,9 @@ export const Swap = observer(
{(isWrapTx || isUnwrapTx) && (
<EstimatedValue
title={I18N.swapScreenRoutingSource}
value={`${Contracts.getById(RemoteProviderConfig.wethAddress)
value={`${Contracts.getById(app.provider.config.wethAddress)
?.name}${STRINGS.NBSP}${shortAddress(
RemoteProviderConfig.wethAddress!,
app.provider.config.wethAddress!,
'•',
true,
)}`}
Expand Down
4 changes: 2 additions & 2 deletions src/components/ui/copy-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import Popover from '@app/components/ui/popover';
import {RTLReverse} from '@app/components/ui/rtl-reverse';
import {Spacer} from '@app/components/ui/spacer';
import {Text, TextVariant} from '@app/components/ui/text';
import {app} from '@app/contexts';
import {createTheme} from '@app/helpers';
import {AddressUtils} from '@app/helpers/address-utils';
import {useTypedNavigation} from '@app/hooks';
import {I18N} from '@app/i18n';
import {RemoteProviderConfig} from '@app/models/provider';
import {sendNotification} from '@app/services';

export type CopyMenuProps = ViewProps & {
Expand Down Expand Up @@ -86,7 +86,7 @@ export const CopyMenu = observer(
<Icon i22 name={IconsName.copy} color={Color.textBase1} />
</RTLReverse>
</MenuOption>
{RemoteProviderConfig.isBech32Enabled && (
{app.provider.config.isBech32Enabled && (
<>
<SolidLine width="100%" color={Color.graphicSecond2} />
<MenuOption onSelect={onBech32CopyPress} style={styles.option}>
Expand Down
2 changes: 1 addition & 1 deletion src/event-actions/on-provider-changed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const onProviderChanged = createAsyncTask(async () => {
await Transaction.fetchLatestTransactions(Wallet.addressList(), true);
await Currencies.fetchCurrencies();

if (RemoteProviderConfig.isNftEnabled) {
if (app.provider.config.isNftEnabled) {
await Nft.fetchNft();
}
Provider.fetchProviders();
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/nft/use-show-nft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import {useEffect, useState} from 'react';

import {autorun} from 'mobx';

import {RemoteProviderConfig} from '@app/models/provider';
import {app} from '@app/contexts';

export const useShowNft = () => {
const [showNft, setShowNft] = useState(RemoteProviderConfig.isNftEnabled);
const [showNft, setShowNft] = useState(app.provider.config.isNftEnabled);

useEffect(() => {
const disposer = autorun(() => {
setShowNft(RemoteProviderConfig.isNftEnabled);
setShowNft(app.provider.config.isNftEnabled);
});

return () => {
Expand Down
77 changes: 77 additions & 0 deletions src/models/provider/provider-config-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {ProviderConfig} from '@app/services/indexer';

export class ProviderConfigModel {
constructor(public config: ProviderConfig) {}

get isNftEnabled() {
return Boolean(this.config?.nft_exists);
}

get isBech32Enabled() {
return Boolean(this.config?.bech32_exists);
}

get swapEnabled() {
return Boolean(this.config?.swap_enabled);
}
get swapRouterV3() {
return this.config?.swap_router_v3 ?? '';
}
get wethAddress() {
return this.config?.weth_address ?? '';
}

get wethSymbol() {
return this.config?.weth_symbol ?? '';
}

/**
* Get the EVM explorer URL template for an address.
* @returns {string} The explorer address URL template or an empty string if not configured.
* Usage: Replace {{address}} with the actual address.
* @example "https://explorer.haqq.network/address/{{address}}"
*/
get explorerAddressUrl() {
return this.config?.explorer_address_url ?? '';
}

/**
* Get the explorer URL template for a Cosmos transaction.
* @returns {string} The explorer Cosmos transaction URL template or an empty string if not configured.
* Usage: Replace {{tx_hash}} with the actual transaction hash.
* @example "https://ping.pub/haqq/tx/{{tx_hash}}"
*/
get explorerCosmosTxUrl() {
return this.config?.explorer_cosmos_tx_url ?? '';
}

/**
* Get the EVM explorer URL template for a token.
* @returns {string} The explorer token URL template or an empty string if not configured.
* Usage: Replace {{address}} with the actual token address.
* @example "https://explorer.haqq.network/token/{{address}}"
*/
get explorerTokenUrl() {
return this.config?.explorer_token_url ?? '';
}

/**
* Get the EVM explorer URL template for a transaction.
* @returns {string} The explorer transaction URL template or an empty string if not configured.
* Usage: Replace {{tx_hash}} with the actual transaction hash.
* @example "https://explorer.haqq.network/tx/{{tx_hash}}"
*/
get explorerTxUrl() {
return this.config?.explorer_tx_url ?? '';
}

/**
* Get the EVM explorer URL template for a token ID.
* @returns {string} The explorer token ID URL template or an empty string if not configured.
* Usage: Replace {{address}} with the token contract address and {{token_id}} with the token ID.
* @example "https://explorer.haqq.network/token/{{address}}/instance/{{token_id}}"
*/
get explorerTokenIdUrl() {
return this.config?.explorer_token_id_url ?? '';
}
}
65 changes: 42 additions & 23 deletions src/models/provider/provider-config.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,68 @@
import {makeAutoObservable, runInAction} from 'mobx';
import {makePersistable} from 'mobx-persist-store';

import {app} from '@app/contexts';
import {Indexer} from '@app/services/indexer';
import {ProviderConfig} from '@app/services/indexer/indexer.types';
import {storage} from '@app/services/mmkv';
import {ChainId} from '@app/types';

import {Provider} from './provider';
import {ProviderConfigModel} from './provider-config-model';

class ProviderConfigStore {
config: ProviderConfig | null = null;
private _data: Record<ChainId, ProviderConfig> = {};

constructor() {
makeAutoObservable(this);
makePersistable(this, {
name: this.constructor.name,
properties: ['config'],
properties: ['_data'] as (keyof this)[],
storage: storage,
});
}

init = async () => {
const newConfig = await Indexer.instance.getProviderConfig();
runInAction(() => {
this.config = newConfig;
});
try {
const config = await Indexer.instance.getProviderConfig();
runInAction(() => {
this._data[app.provider.ethChainId] = config;
});
this.lazyLoadOtherConfig();
return Promise.resolve();
} catch (error) {
Logger.captureException(error, 'ProviderConfigStore:init');
}
};

get isNftEnabled() {
return Boolean(this.config?.nft_exists);
get data() {
return this._data;
}

get isBech32Enabled() {
return Boolean(this.config?.bech32_exists);
}
lazyLoadOtherConfig = async () => {
const providers = Provider.getAll().filter(
p => p.ethChainId !== app.provider.ethChainId,
);

get swapEnabled() {
return Boolean(this.config?.swap_enabled);
}
get swapRouterV3() {
return this.config?.swap_router_v3 ?? '';
}
get wethAddress() {
return this.config?.weth_address ?? '';
}
for await (const p of providers) {
try {
if (this._data[p.ethChainId]) {
continue;
}
const indexer = new Indexer(p.ethChainId);
const c = await indexer.getProviderConfig();
runInAction(() => {
this._data[p.ethChainId] = c;
});
} catch (error) {
Logger.captureException(error, 'failed to initialize provider config:');
}
}
};

get wethSymbol() {
return this.config?.weth_symbol ?? '';
}
getConfig = (chainId: ChainId) => {
return new ProviderConfigModel(this.data[chainId]);
};
}

const instance = new ProviderConfigStore();
Expand Down
38 changes: 35 additions & 3 deletions src/models/provider/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,17 @@ import {storage} from '@app/services/mmkv';
import {createAsyncTask, sleep} from '@app/utils';
import {DEFAULT_PROVIDERS, ISLM_DENOM} from '@app/variables/common';

import {RemoteProviderConfig} from './provider-config';
import {ProviderID} from './provider.types';

import {VariablesString} from '../variables-string';

const HAQQ_BENCH_32_PREFIX = 'haqq';
const EXPLORER_URL_TEMPLATES = {
ADDRESS: '{{address}}',
TOKEN_ID: '{{token_id}}',
TX: '{{tx_hash}}',
};

const logger = Logger.create('NetworkProvider:store', {
stringifyJson: true,
Expand Down Expand Up @@ -240,6 +246,10 @@ export class Provider {
return this.model.coin_name;
}

get config() {
return RemoteProviderConfig.getConfig(this.ethChainId);
}

toJSON() {
return {
ethChainIdHex: this.ethChainIdHex,
Expand All @@ -261,14 +271,36 @@ export class Provider {
}

if (txHash.startsWith('0x') || txHash.startsWith('0X')) {
return `${this.explorer}/tx/${txHash}`;
return this.config.explorerTxUrl.replace(
EXPLORER_URL_TEMPLATES.TX,
txHash,
);
}

return `${this.cosmosExplorer}/${this.bench32Prefix}/tx/${txHash}`;
return this.config.explorerCosmosTxUrl.replace(
EXPLORER_URL_TEMPLATES.TX,
txHash,
);
}

getAddressExplorerUrl(address: string) {
return `${this.explorer}/address/${AddressUtils.toEth(address)}`;
return this.config.explorerAddressUrl.replace(
EXPLORER_URL_TEMPLATES.ADDRESS,
AddressUtils.toEth(address),
);
}

getCollectionExplorerUrl(address: string) {
return this.config.explorerTokenUrl.replace(
EXPLORER_URL_TEMPLATES.ADDRESS,
AddressUtils.toEth(address),
);
}

getTokenExplorerUrl(address: string, tokenId: string | number) {
return this.config.explorerTokenIdUrl
.replace(EXPLORER_URL_TEMPLATES.ADDRESS, AddressUtils.toEth(address))
.replace(EXPLORER_URL_TEMPLATES.TOKEN_ID, tokenId.toString());
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/screens/HomeStack/NftStack/nft-item-details.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, {memo, useCallback} from 'react';

import {app} from '@app/contexts';
import {AddressUtils} from '@app/helpers/address-utils';
import {useTypedNavigation, useTypedRoute} from '@app/hooks';
import {
HomeStackRoutes,
Expand Down Expand Up @@ -29,10 +28,10 @@ export const NftItemDetailsScreen = memo(() => {
}, [params.item, navigation]);

const onPressExplorer = useCallback(() => {
// https://explorer.haqq.network/token/0xe5C15B68cfE3182c106f60230A1bE377ceaad483/instance/2998
const url = `${app.provider.explorer}/token/${AddressUtils.toEth(
const url = app.provider.getTokenExplorerUrl(
params.item.contract,
)}/instance/${params.item.tokenId}`;
params.item.tokenId,
);
return openInAppBrowser(url);
}, [params.item]);

Expand Down
Loading

0 comments on commit 3e3fd5e

Please sign in to comment.