Skip to content

Commit

Permalink
scaffold selectors
Browse files Browse the repository at this point in the history
  • Loading branch information
owencraston committed Dec 12, 2024
1 parent 1bedb7b commit 31f3fec
Show file tree
Hide file tree
Showing 2 changed files with 199 additions and 3 deletions.
4 changes: 2 additions & 2 deletions app/reducers/multichain/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MultichainSettingsState } from '../../actions/multichain/state';

export const initialState: MultichainSettingsState = {
bitcoinSupportEnabled: false,
bitcoinTestnetSupportEnabled: false,
bitcoinSupportEnabled: true,
bitcoinTestnetSupportEnabled: true,
};

const multichainReducer = (state = initialState) => state;
Expand Down
198 changes: 197 additions & 1 deletion app/selectors/multichain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,27 @@ import {
} from './accountsController';
import { selectAllTokens } from './tokensController';
import { selectAccountsByChainId } from './accountTrackerController';
import { selectNetworkConfigurations } from './networkController';
import {
selectChainId,
selectNetworkConfigurations,
selectProviderConfig,
selectTicker,
} from './networkController';
import { TokenI } from '../components/UI/Tokens/types';
import { renderFromWei } from '../util/number';
import { toHex } from '@metamask/controller-utils';
import {
selectConversionRate,
selectCurrencyRates,
selectCurrentCurrency,
} from './currencyRateController';
import {
isBtcTestnetAddress,
isBtcMainnetAddress,
} from '../core/Multichain/utils';
import { selectTokenMarketData } from './tokenRatesController';
import { isMainNet, isTestNet } from '../util/networks';
import { isEvmAccountType } from '@metamask/keyring-api';

interface NativeTokenBalance {
balance: string;
Expand Down Expand Up @@ -232,3 +244,187 @@ export function selectIsBitcoinSupportEnabled(state: RootState) {
export function selectIsBitcoinTestnetSupportEnabled(state: RootState) {
return state.multichainSettings.bitcoinTestnetSupportEnabled;
}

export const selectMultichainIsEvm = createSelector(
selectSelectedInternalAccount,
(selectedAccount) => {
// If no account selected, assume EVM for onboarding scenario
if (!selectedAccount) {
return true;
}
return isEvmAccountType(selectedAccount.type);
},
);

export const selectMultichainDefaultToken = createSelector(
selectMultichainIsEvm,
selectProviderConfig,
(isEvm, providerConfig) => {
const symbol = isEvm
? providerConfig?.ticker ?? 'ETH'
: providerConfig?.ticker;
return { symbol };
},
);

export const selectMultichainIsBitcoin = createSelector(
selectMultichainIsEvm,
selectMultichainDefaultToken,
(isEvm, token) => !isEvm && token.symbol === 'BTC',
);

export const selectMultichainProviderConfig = createSelector(
selectProviderConfig,
(providerConfig) => providerConfig,
);

export const selectMultichainCurrentNetwork = selectMultichainProviderConfig;

export const selectMultichainNativeCurrency = createSelector(
selectMultichainIsEvm,
selectTicker,
selectProviderConfig,
(isEvm, ticker, providerConfig) => (isEvm ? ticker : providerConfig?.ticker),
);

export const selectMultichainCurrentCurrency = createSelector(
selectMultichainIsEvm,
selectCurrentCurrency,
selectProviderConfig,
(isEvm, currentCurrency, providerConfig) => {
if (isEvm) {
return currentCurrency;
}
// For non-EVM:
return currentCurrency?.toLowerCase() === 'usd'
? 'usd'
: providerConfig.ticker;
},
);

export const selectMultichainShouldShowFiat = createSelector(
selectMultichainIsEvm,
selectChainId,
(state: RootState) => state.settings.showFiatOnTestnets,
selectSelectedInternalAccount,
selectMultichainIsBitcoin,
(isEvm, chainId, showFiatOnTestnets, selectedAccount, isBitcoin) => {
if (isEvm) {
// EVM logic: show fiat on mainnet or showFiatOnTestnets if testnet
if (!isTestNet(chainId)) {
return true; // mainnet
}
return showFiatOnTestnets;
}

// Non-EVM logic: currently we only have Bitcoin as example
// Show fiat if mainnet or if testnet + showFiatOnTestnets is true
if (isBitcoin && selectedAccount) {
const isMainnet = isBtcMainnetAddress(selectedAccount.address);
const isTestnet = isBtcTestnetAddress(selectedAccount.address);

if (isMainnet) return true;
if (isTestnet) return showFiatOnTestnets;
}

// If other non-EVM networks are supported, adjust logic as needed.
return true;
},
);

export const selectMultichainCurrentChainId = selectChainId;

export const selectMultichainIsMainnet = createSelector(
selectMultichainIsEvm,
selectSelectedInternalAccount,
selectChainId,
selectMultichainIsBitcoin,
(isEvm, selectedAccount, chainId, isBitcoin) => {
if (isEvm) {
return isMainNet(chainId);
}

// Non-EVM: Currently only Bitcoin
if (isBitcoin && selectedAccount) {
return isBtcMainnetAddress(selectedAccount.address);
}

// If other non-EVM networks: adjust accordingly
return false;
},
);

export const selectMultichainIsTestnet = createSelector(
selectMultichainIsEvm,
selectSelectedInternalAccount,
selectChainId,
selectMultichainIsBitcoin,
(isEvm, selectedAccount, chainId, isBitcoin) => {
if (isEvm) {
return isTestNet(chainId);
}

if (isBitcoin && selectedAccount) {
return isBtcTestnetAddress(selectedAccount.address);
}

// For other non-EVM networks, implement similar logic
return false;
},
);

/**
* If MultichainBalancesController state is integrated into the engine background state,
* adapt the following selector. If not, please provide that part of the state so we can adjust.
*/
export const selectMultichainBalances = createSelector(
// Placeholder: adapt to where balances from MultichainBalancesController are stored.
(state: RootState) =>
state.engine.backgroundState.MultichainBalancesController?.balances ?? {},
(balances) => balances,
);

export const selectMultichainCoinRates = selectCurrencyRates;

export const selectMultichainSelectedAccountCachedBalance = createSelector(
selectSelectedInternalAccountFormattedAddress,
selectAccountsByChainId,
selectMultichainIsEvm,
selectChainId,
selectSelectedInternalAccount,
(selectedAddress, accountsByChainId, isEvm, chainId, selectedAccount) => {

Check failure on line 395 in app/selectors/multichain.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'isEvm' is defined but never used. Allowed unused args must match /[_]+/u

Check failure on line 395 in app/selectors/multichain.ts

View workflow job for this annotation

GitHub Actions / scripts (lint)

'selectedAccount' is defined but never used. Allowed unused args must match /[_]+/u
if (!selectedAddress || !chainId) return '0x0';
const account = accountsByChainId[chainId]?.[selectedAddress];
if (!account) return '0x0';

// For EVM: `account.balance` should be a hex string (e.g. '0x1234...')
// For Bitcoin: If the MultichainBalancesController stores balance as a decimal or something else,
// convert or adapt accordingly. If it stores amounts in sats, for example, convert if needed.
return account.balance || '0x0';
},
);

export const selectMultichainSelectedAccountCachedBalanceIsZero =
createSelector(
selectMultichainSelectedAccountCachedBalance,
selectMultichainIsEvm,
(balance, isEvm) => {
const base = isEvm ? 16 : 10;
const numericValue = parseInt(balance, base);
return numericValue === 0;
},
);

export const selectMultichainConversionRate = createSelector(
selectMultichainIsEvm,
selectConversionRate,
selectCurrencyRates,
selectProviderConfig,
(isEvm, evmConversionRate, currencyRates, providerConfig) => {
if (isEvm) {
return evmConversionRate;
}
const ticker = providerConfig?.ticker?.toLowerCase();
return ticker ? currencyRates?.[ticker]?.conversionRate : undefined;
},
);

0 comments on commit 31f3fec

Please sign in to comment.