diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 64aab4b5c56..1158dba00d6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -15,7 +15,7 @@ PODS: - disklet (0.5.2): - React - DoubleConversion (1.1.6) - - edge-core-js (2.35.0): + - edge-core-js (2.37.0): - React-Core - edge-currency-accountbased (4.66.0): - React-Core @@ -3333,7 +3333,7 @@ SPEC CHECKSUMS: CNIOWindows: 3047f2d8165848a3936a0a755fee27c6b5ee479b disklet: 8a20bf8a568635b6e6bb8f93297dac13ee5cef98 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb - edge-core-js: 2e9266c5197e8f556058acf4874e5e554985e590 + edge-core-js: 248f7d28942a5ea6c9835eca6f9f16969c89476c edge-currency-accountbased: 434044274f205514017b18fe3dd3cb942231e233 edge-currency-plugins: 0d8a1a8da63672342cbc9bd5055feb4b397544e7 edge-exchange-plugins: a97b9ea3ede379b8aad026c5bd3f67d042b09983 diff --git a/package.json b/package.json index 815009db56e..a70ef51b2f3 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "deprecated-react-native-prop-types": "^5.0.0", "detect-bundler": "^1.1.0", "disklet": "^0.5.2", - "edge-core-js": "^2.35.0", + "edge-core-js": "^2.37.0", "edge-currency-accountbased": "^4.66.0", "edge-currency-monero": "^2.0.1", "edge-currency-plugins": "^3.8.9", diff --git a/src/__tests__/reducers/__snapshots__/RootReducer.test.ts.snap b/src/__tests__/reducers/__snapshots__/RootReducer.test.ts.snap index b3985e66a10..3caf6936468 100644 --- a/src/__tests__/reducers/__snapshots__/RootReducer.test.ts.snap +++ b/src/__tests__/reducers/__snapshots__/RootReducer.test.ts.snap @@ -85,6 +85,7 @@ exports[`initialState 1`] = ` }, "fio": { "connectedWalletsByFioAddress": {}, + "fioWallets": [], }, "fioAddress": { "fioAddresses": [], @@ -156,11 +157,6 @@ exports[`initialState 1`] = ` "walletsSort": "manual", }, "subcategories": [], - "wallets": { - "fioWallets": [], - "selectedCurrencyCode": "", - "selectedWalletId": "", - }, }, } `; diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index a8aba13f6f1..e61fefb3c3d 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from '@jest/globals' import { log10 } from 'biggystring' -import { selectDisplayDenomByCurrencyCode } from '../selectors/DenominationSelectors' +import { selectDisplayDenom } from '../selectors/DenominationSelectors' import { btcCurrencyInfo } from '../util/fake/fakeBtcInfo' import { makeFakeCurrencyConfig } from '../util/fake/fakeCurrencyConfig' import { ethCurrencyInfo } from '../util/fake/fakeEthInfo' @@ -393,15 +393,18 @@ describe('getDisplayDenomination', function () { const input = [ { pluginId: 'bitcoin', - currencyCode: 'BTC' + currencyCode: 'BTC', + tokenId: null }, { pluginId: 'ethereum', - currencyCode: 'ETH' + currencyCode: 'ETH', + tokenId: null }, { pluginId: 'ethereum', - currencyCode: 'TKN' + currencyCode: 'TKN', + tokenId: '1985365e9f78359a9B6AD760e32412f4a445E862' } ] as const const output = [ @@ -425,10 +428,10 @@ describe('getDisplayDenomination', function () { const currencyConfig = state.core.account.currencyConfig[currency.pluginId] expect( - selectDisplayDenomByCurrencyCode( + selectDisplayDenom( state as any, currencyConfig as any, - currency.currencyCode + currency.tokenId ) ).toMatchObject(output[index]) }) diff --git a/src/actions/CreateWalletActions.tsx b/src/actions/CreateWalletActions.tsx index c4c84171589..a16e6ac3607 100644 --- a/src/actions/CreateWalletActions.tsx +++ b/src/actions/CreateWalletActions.tsx @@ -19,13 +19,12 @@ import type { import { Airship } from '../components/services/AirshipInstance' import { SPECIAL_CURRENCY_INFO } from '../constants/WalletAndCurrencyConstants' import { lstrings } from '../locales/strings' -import { getExchangeDenomByCurrencyCode } from '../selectors/DenominationSelectors' +import { getExchangeDenom } from '../selectors/DenominationSelectors' import type { TokenWalletCreateItem } from '../selectors/getCreateWalletList' import { config } from '../theme/appConfig' import type { ThunkAction } from '../types/reduxTypes' import type { NavigationBase } from '../types/routerTypes' import type { EdgeAsset } from '../types/types' -import { getWalletTokenId } from '../util/CurrencyInfoHelpers' import { logActivity } from '../util/logger' import { filterNull } from '../util/safeFilters' import { logEvent } from '../util/tracking' @@ -155,16 +154,12 @@ export function createAccountTransaction( createdCurrencyWallet.currencyInfo.currencyCode const currencyPlugin = account.currencyConfig[createdCurrencyWallet.currencyInfo.pluginId] - const { paymentAddress, amount, currencyCode } = activationPaymentInfo + const { paymentAddress, amount, tokenId } = activationPaymentInfo const handleAvailability = await currencyPlugin.otherMethods.validateAccount(accountName) - const paymentDenom = getExchangeDenomByCurrencyCode( - paymentWallet.currencyConfig, - currencyCode - ) + const paymentDenom = getExchangeDenom(paymentWallet.currencyConfig, tokenId) let nativeAmount = mul(amount, paymentDenom.multiplier) nativeAmount = toFixed(nativeAmount, 0, 0) - const tokenId = getWalletTokenId(paymentWallet, currencyCode) if (handleAvailability.result === 'AccountAvailable') { navigation.push('send2', { diff --git a/src/actions/FioActions.tsx b/src/actions/FioActions.tsx index bad49f83636..a3f5d17cb9e 100644 --- a/src/actions/FioActions.tsx +++ b/src/actions/FioActions.tsx @@ -27,7 +27,7 @@ export const refreshConnectedWallets = async ( getState: GetState ) => { const wallets: EdgeCurrencyWallet[] = [] - const fioWallets: EdgeCurrencyWallet[] = getState().ui.wallets.fioWallets + const fioWallets: EdgeCurrencyWallet[] = getState().ui.fio.fioWallets const currencyWallets = getState().core.account.currencyWallets for (const walletId of Object.keys(currencyWallets)) { wallets.push(currencyWallets[walletId]) @@ -69,7 +69,7 @@ export function checkFioObtData( let loopCount = 0 while (true) { account = state.core.account - fioWallets = state.ui.wallets.fioWallets + fioWallets = state.ui.fio.fioWallets if (account?.currencyConfig != null && fioWallets.length > 0) break if (loopCount++ > MAX_OBT_DATA_CHECKS) return await snooze(400) diff --git a/src/actions/FioAddressActions.ts b/src/actions/FioAddressActions.ts index 30d0213c39e..ab1ddba37bf 100644 --- a/src/actions/FioAddressActions.ts +++ b/src/actions/FioAddressActions.ts @@ -31,7 +31,7 @@ export function refreshAllFioAddresses(): ThunkAction> { }) const state = getState() const { currencyWallets } = state.core.account - const fioWallets: EdgeCurrencyWallet[] = state.ui.wallets.fioWallets + const fioWallets: EdgeCurrencyWallet[] = state.ui.fio.fioWallets const { fioAddresses, fioDomains, fioWalletsById } = await refreshFioNames( fioWallets diff --git a/src/actions/LoginActions.tsx b/src/actions/LoginActions.tsx index 033ee4f2fdd..033ea132aea 100644 --- a/src/actions/LoginActions.tsx +++ b/src/actions/LoginActions.tsx @@ -1,4 +1,8 @@ -import type { EdgeAccount, EdgeCreateCurrencyWallet } from 'edge-core-js/types' +import type { + EdgeAccount, + EdgeCreateCurrencyWallet, + EdgeTokenId +} from 'edge-core-js/types' import { getSupportedBiometryType, hasSecurityAlerts, @@ -53,7 +57,7 @@ const MIN_CREATE_WALLET_TIMEOUT = 20000 function getFirstActiveWalletInfo(account: EdgeAccount): { walletId: string - currencyCode: string + tokenId: EdgeTokenId } { // Find the first wallet: const [walletId] = account.activeWalletIds @@ -64,13 +68,13 @@ function getFirstActiveWalletInfo(account: EdgeAccount): { for (const pluginId of Object.keys(account.currencyConfig)) { const { currencyInfo } = account.currencyConfig[pluginId] if (currencyInfo.walletType === walletKey.type) { - return { walletId, currencyCode: currencyInfo.currencyCode } + return { walletId, tokenId: null } } } } // The user has no wallets: - return { walletId: '', currencyCode: '' } + return { walletId: '', tokenId: null } } export function initializeAccount( @@ -257,7 +261,7 @@ export function initializeAccount( let accountInitObject: AccountInitPayload = { ...initialState, account, - currencyCode: '', + tokenId: null, pinLoginEnabled: false, isTouchEnabled: await isTouchEnabled(account), isTouchSupported: (await getSupportedBiometryType()) !== false, @@ -267,9 +271,9 @@ export function initializeAccount( try { if (!newAccount) { // We have a wallet - const { walletId, currencyCode } = getFirstActiveWalletInfo(account) + const { walletId, tokenId } = getFirstActiveWalletInfo(account) accountInitObject.walletId = walletId - accountInitObject.currencyCode = currencyCode + accountInitObject.tokenId = tokenId } accountInitObject = { ...accountInitObject, ...syncedSettings } diff --git a/src/actions/ScanActions.tsx b/src/actions/ScanActions.tsx index 1687af869ed..166856d4dfd 100644 --- a/src/actions/ScanActions.tsx +++ b/src/actions/ScanActions.tsx @@ -25,15 +25,13 @@ import { } from '../components/services/AirshipInstance' import { getSpecialCurrencyInfo } from '../constants/WalletAndCurrencyConstants' import { lstrings } from '../locales/strings' +import { getExchangeDenom } from '../selectors/DenominationSelectors' import { getExchangeRate } from '../selectors/WalletSelectors' import { config } from '../theme/appConfig' import type { RequestAddressLink } from '../types/DeepLinkTypes' import type { Dispatch, RootState, ThunkAction } from '../types/reduxTypes' import type { NavigationBase } from '../types/routerTypes' -import { - getCurrencyCode, - getCurrencyCodeMultiplier -} from '../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../util/CurrencyInfoHelpers' import { parseDeepLink } from '../util/DeepLinkParser' import { logActivity } from '../util/logger' import { runOnce } from '../util/runOnce' @@ -401,10 +399,7 @@ async function sweepPrivateKeys( // Check for a $50 maximum sweep for light accounts: const sendNativeAmount = abs(unsignedTx.nativeAmount) - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - wallet.currencyInfo.currencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, null) const sendExchangeAmount = div( sendNativeAmount, multiplier, diff --git a/src/actions/WalletActions.tsx b/src/actions/WalletActions.tsx index 224e0a7469c..ade771c82ab 100644 --- a/src/actions/WalletActions.tsx +++ b/src/actions/WalletActions.tsx @@ -28,16 +28,15 @@ import { SPECIAL_CURRENCY_INFO } from '../constants/WalletAndCurrencyConstants' import { lstrings } from '../locales/strings' -import { selectDisplayDenomByCurrencyCode } from '../selectors/DenominationSelectors' +import { + getExchangeDenom, + selectDisplayDenom +} from '../selectors/DenominationSelectors' import { convertCurrency } from '../selectors/WalletSelectors' import type { ThunkAction } from '../types/reduxTypes' import type { NavigationBase } from '../types/routerTypes' import type { MapObject } from '../types/types' -import { - getCurrencyCode, - getCurrencyCodeMultiplier, - isKeysOnlyPlugin -} from '../util/CurrencyInfoHelpers' +import { getCurrencyCode, isKeysOnlyPlugin } from '../util/CurrencyInfoHelpers' import { getWalletName } from '../util/CurrencyWalletHelpers' import { fetchInfo } from '../util/network' @@ -77,9 +76,6 @@ export function selectWalletToken({ const currencyCode = getCurrencyCode(wallet, tokenId) dispatch(updateMostRecentWalletsSelected(walletId, tokenId)) - const currentWalletId = state.ui.wallets.selectedWalletId - const currentWalletCurrencyCode = state.ui.wallets.selectedCurrencyCode - if (tokenId != null) { const { unactivatedTokenIds } = wallet if ( @@ -90,15 +86,7 @@ export function selectWalletToken({ await dispatch(activateWalletTokens(navigation, wallet, [tokenId])) return false } - if ( - walletId !== currentWalletId || - currencyCode !== currentWalletCurrencyCode - ) { - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { walletId, currencyCode } - }) - } + return true } @@ -107,11 +95,7 @@ export function selectWalletToken({ ) if (isAccountActivationRequired) { // activation-required wallets need different path in case not activated yet - if ( - alwaysActivate || - walletId !== currentWalletId || - currencyCode !== currentWalletCurrencyCode - ) { + if (alwaysActivate) { return await dispatch( selectActivationRequiredWallet(navigation, walletId, currencyCode) ) @@ -119,15 +103,6 @@ export function selectWalletToken({ return true } - if ( - walletId !== currentWalletId || - currencyCode !== currentWalletCurrencyCode - ) { - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { walletId, currencyCode } - }) - } return true } } @@ -146,10 +121,6 @@ function selectActivationRequiredWallet( if (publicAddress !== '') { // already activated - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { walletId, currencyCode } - }) return true } else { // not activated yet @@ -185,16 +156,14 @@ export function updateMostRecentWalletsSelected( return (dispatch, getState) => { const state = getState() const { account } = state.core - const wallet = account.currencyWallets[walletId] - const currencyCode = getCurrencyCode(wallet, tokenId) const { mostRecentWallets } = state.ui.settings const currentMostRecentWallets = mostRecentWallets.filter(wallet => { - return wallet.id !== walletId || wallet.currencyCode !== currencyCode + return wallet.id !== walletId || wallet.tokenId !== tokenId }) if (currentMostRecentWallets.length === 100) { currentMostRecentWallets.pop() } - currentMostRecentWallets.unshift({ id: walletId, currencyCode }) + currentMostRecentWallets.unshift({ id: walletId, tokenId }) writeMostRecentWalletsSelected(account, currentMostRecentWallets) .then(() => { @@ -257,17 +226,12 @@ export function activateWalletTokens( if (currencyPluginId !== pluginId) throw new Error('Internal Error: Fee asset mismatch.') - const paymentCurrencyCode = getCurrencyCode(wallet, feeTokenId) - - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - paymentCurrencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, feeTokenId) const exchangeNetworkFee = div(nativeFee, multiplier, multiplier.length) - const feeDenom = selectDisplayDenomByCurrencyCode( + const feeDenom = selectDisplayDenom( state, wallet.currencyConfig, - paymentCurrencyCode + feeTokenId ) const displayFee = div( nativeFee, diff --git a/src/actions/scene/StakingActions.tsx b/src/actions/scene/StakingActions.tsx index 6be9f0b1cc1..aa103f7b4a4 100644 --- a/src/actions/scene/StakingActions.tsx +++ b/src/actions/scene/StakingActions.tsx @@ -1,5 +1,5 @@ import { add } from 'biggystring' -import type { EdgeAccount, EdgeCurrencyWallet } from 'edge-core-js' +import type { EdgeAccount, EdgeCurrencyWallet, EdgeTokenId } from 'edge-core-js' import { SPECIAL_CURRENCY_INFO } from '../../constants/WalletAndCurrencyConstants' import { ENV } from '../../env' @@ -15,7 +15,7 @@ import { getPositionAllocations } from '../../util/stakeUtils' import { datelog } from '../../util/utils' export const updateStakingState = ( - currencyCode: string, + tokenId: EdgeTokenId, wallet: EdgeCurrencyWallet ): ThunkAction> => { return async (dispatch, getState) => { @@ -43,7 +43,7 @@ export const updateStakingState = ( const stakePolicies = stakePlugin.getPolicies({ pluginId, wallet, - currencyCode + tokenId }) for (const stakePolicy of stakePolicies) { stakePolicyMap[stakePolicy.stakePolicyId] = stakePolicy @@ -58,9 +58,7 @@ export const updateStakingState = ( stakePositionMap[stakePolicy.stakePolicyId] = stakePosition const { staked, earned } = getPositionAllocations(stakePosition) total = [...staked, ...earned] - .filter( - p => p.currencyCode === currencyCode && p.pluginId === pluginId - ) + .filter(p => p.tokenId === tokenId && p.pluginId === pluginId) .reduce((prev, curr) => add(prev, curr.nativeAmount), '0') } catch (err) { console.error(err) diff --git a/src/components/FioAddress/FioActionSubmit.tsx b/src/components/FioAddress/FioActionSubmit.tsx index f8a36acfea4..12cf775ac0c 100644 --- a/src/components/FioAddress/FioActionSubmit.tsx +++ b/src/components/FioAddress/FioActionSubmit.tsx @@ -354,7 +354,7 @@ export function FioActionSubmit(props: OwnProps): React.ReactElement { state => selectDisplayDenom(state, props.fioWallet.currencyConfig, null).multiplier ) - const fioWallets = useSelector(state => state.ui.wallets.fioWallets) + const fioWallets = useSelector(state => state.ui.fio.fioWallets) return ( { + if ( + swapData.payoutTokenId === undefined && + destinationWallet.currencyInfo.currencyCode !== swapData.payoutCurrencyCode + ) { + swapData.payoutTokenId = getTokenId( + destinationWallet.currencyConfig, + swapData.payoutCurrencyCode + ) + } else if (swapData.payoutTokenId === undefined) { + swapData.payoutTokenId = null + } + + return swapData +} + export function SwapDetailsCard(props: Props) { const { swapData, transaction, wallet } = props const theme = useTheme() @@ -46,25 +67,32 @@ export function SwapDetailsCard(props: Props) { const { currencyInfo } = wallet const walletName = useWalletName(wallet) const walletDefaultDenom = useSelector(state => - currencyInfo.currencyCode === transaction.currencyCode + transaction.tokenId === null ? getExchangeDenom(wallet.currencyConfig, tokenId) : selectDisplayDenom(state, wallet.currencyConfig, tokenId) ) + // The wallet may have been deleted: + const account = useSelector(state => state.core.account) + const currencyWallets = useWatch(account, 'currencyWallets') + const destinationWallet = currencyWallets[swapData.payoutWalletId] + const destinationWalletName = + destinationWallet == null ? '' : getWalletName(destinationWallet) + const { isEstimate, orderId, orderUri, payoutAddress, - payoutWalletId, + payoutCurrencyCode, + payoutTokenId, plugin, refundAddress - } = swapData + } = upgradeSwapData(wallet, swapData) const formattedOrderUri = orderUri == null ? undefined : orderUri.replace(TXID_PLACEHOLDER, transaction.txid) - const payoutCurrencyCode = swapData.payoutCurrencyCode const handleExchangeDetails = useHandler(async () => { await Airship.show(bridge => ( @@ -123,19 +151,13 @@ export function SwapDetailsCard(props: Props) { } } - // The wallet may have been deleted: - const account = useSelector(state => state.core.account) - const currencyWallets = useWatch(account, 'currencyWallets') - const destinationWallet = currencyWallets[payoutWalletId] - const destinationWalletName = - destinationWallet == null ? '' : getWalletName(destinationWallet) const destinationDenomination = useSelector(state => - destinationWallet == null + destinationWallet == null || payoutTokenId === undefined ? undefined - : selectDisplayDenomByCurrencyCode( + : selectDisplayDenom( state, destinationWallet.currencyConfig, - payoutCurrencyCode + payoutTokenId ) ) if (destinationDenomination == null) return null @@ -158,8 +180,7 @@ export function SwapDetailsCard(props: Props) { destinationDenomination.multiplier )(swapData.payoutNativeAmount) const destinationAssetName = - payoutCurrencyCode === - getExchangeDenom(destinationWallet.currencyConfig, null).name + payoutTokenId == null ? payoutCurrencyCode : `${payoutCurrencyCode} (${ getExchangeDenom(destinationWallet.currencyConfig, null).name diff --git a/src/components/modals/WcSmartContractModal.tsx b/src/components/modals/WcSmartContractModal.tsx index 3773ed6be45..0a8359961a8 100644 --- a/src/components/modals/WcSmartContractModal.tsx +++ b/src/components/modals/WcSmartContractModal.tsx @@ -28,7 +28,6 @@ import { useWalletConnect } from '../../hooks/useWalletConnect' import { lstrings } from '../../locales/strings' import { asEdgeTokenId } from '../../types/types' import { getCurrencyIconUris } from '../../util/CdnUris' -import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { getWalletName } from '../../util/CurrencyWalletHelpers' import { zeroString } from '../../util/utils' import { EdgeCard } from '../cards/EdgeCard' @@ -67,8 +66,6 @@ export const WcSmartContractModal = (props: Props) => { const walletName = getWalletName(wallet) - const amountCurrencyCode = getCurrencyCode(wallet, tokenId) - const { currencyCode: feeCurrencyCode, displayName: feeDisplayName, @@ -96,7 +93,7 @@ export const WcSmartContractModal = (props: Props) => { ) const isInsufficientBal = - amountCurrencyCode === feeCurrencyCode + tokenId == null ? gt(abs(totalNativeCrypto), feeCurrencyBalance) : gt(networkFee, feeCurrencyBalance) diff --git a/src/components/rows/TxCryptoAmountRow.tsx b/src/components/rows/TxCryptoAmountRow.tsx index 64e3a0adc27..a61d35ea3ab 100644 --- a/src/components/rows/TxCryptoAmountRow.tsx +++ b/src/components/rows/TxCryptoAmountRow.tsx @@ -40,7 +40,7 @@ export function TxCryptoAmountRow(props: Props) { // Find the denomination to use: const walletDefaultDenom: EdgeDenomination = useSelector(state => - currencyInfo.currencyCode === currencyCode + tokenId === null ? getExchangeDenom(wallet.currencyConfig, tokenId) : selectDisplayDenom(state, wallet.currencyConfig, tokenId) ) diff --git a/src/components/scenes/CoinRankingDetailsScene.tsx b/src/components/scenes/CoinRankingDetailsScene.tsx index 7d913e6a590..5ea6b5fa6be 100644 --- a/src/components/scenes/CoinRankingDetailsScene.tsx +++ b/src/components/scenes/CoinRankingDetailsScene.tsx @@ -42,6 +42,7 @@ import { useDispatch, useSelector } from '../../types/reactRedux' import type { EdgeAppSceneProps, NavigationBase } from '../../types/routerTypes' import type { EdgeAsset } from '../../types/types' import { CryptoAmount } from '../../util/CryptoAmount' +import { getTokenId } from '../../util/CurrencyInfoHelpers' import { fetchRates } from '../../util/network' import { getBestApyText, isStakingSupported } from '../../util/stakeUtils' import { getUkCompliantString } from '../../util/ukComplianceUtils' @@ -254,11 +255,12 @@ const CoinRankingDetailsSceneComponent: React.FC = props => { for (const wallet of uninitializedStakingWallets) { const walletState = walletStakingStateMap[wallet.id] if (walletState != null && !walletState.isLoading) continue - dispatch(updateStakingState(currencyCode, wallet)).catch( - (err: unknown) => { + const tokenId = getTokenId(wallet.currencyConfig, currencyCode) + if (tokenId !== undefined) { + dispatch(updateStakingState(tokenId, wallet)).catch(err => { showError(err) - } - ) + }) + } } } // We don't want other dependencies to cause a flood of update requests that @@ -623,7 +625,7 @@ const CoinRankingDetailsSceneComponent: React.FC = props => { lstrings.select_wallet ) if (walletListResult == null) return - const { walletId } = walletListResult + const { walletId, tokenId } = walletListResult // Handle FIO staking if (currencyCode === 'FIO') { @@ -634,7 +636,7 @@ const CoinRankingDetailsSceneComponent: React.FC = props => { } else { navigation.push('stakeOptions', { walletId, - currencyCode + tokenId }) } }) diff --git a/src/components/scenes/CreateWalletAccountSelectScene.tsx b/src/components/scenes/CreateWalletAccountSelectScene.tsx index 4d2d22b7ec7..dd7d6dbcfff 100644 --- a/src/components/scenes/CreateWalletAccountSelectScene.tsx +++ b/src/components/scenes/CreateWalletAccountSelectScene.tsx @@ -1,4 +1,4 @@ -import type { EdgeCurrencyWallet } from 'edge-core-js' +import type { EdgeCurrencyWallet, EdgeTokenId } from 'edge-core-js' import * as React from 'react' import { View } from 'react-native' import { cacheStyles } from 'react-native-patina' @@ -15,15 +15,12 @@ import { import { useAsyncEffect } from '../../hooks/useAsyncEffect' import { useHandler } from '../../hooks/useHandler' import { lstrings } from '../../locales/strings' -import { getExchangeDenomByCurrencyCode } from '../../selectors/DenominationSelectors' +import { getExchangeDenom } from '../../selectors/DenominationSelectors' import { config } from '../../theme/appConfig' import { useDispatch, useSelector } from '../../types/reactRedux' import type { EdgeAppSceneProps, NavigationBase } from '../../types/routerTypes' import type { EdgeAsset } from '../../types/types' -import { - getCurrencyCode, - getWalletTokenId -} from '../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { getWalletName } from '../../util/CurrencyWalletHelpers' import { logEvent } from '../../util/tracking' import { ButtonsView } from '../buttons/ButtonsView' @@ -58,7 +55,7 @@ export interface HandleActivationInfo { export interface AccountActivationPaymentInfo { paymentAddress: string amount: string - currencyCode: string + tokenId: EdgeTokenId expireTime: number } @@ -76,21 +73,20 @@ export const CreateWalletAccountSelectScene = withWallet((props: Props) => { existingWallet.currencyInfo const account = useSelector(state => state.core.account) - const [activationPaymentInfo, setActivationPaymentInfo] = - React.useState({ - paymentAddress: '', - amount: '', - currencyCode: '', - expireTime: 0 - }) - const paymentCurrencyCode = activationPaymentInfo.currencyCode - const amount = activationPaymentInfo.amount + const [activationPaymentInfo, setActivationPaymentInfo] = React.useState< + AccountActivationPaymentInfo | undefined + >() + const paymentCurrencyCode = + activationPaymentInfo?.tokenId !== undefined + ? getCurrencyCode(existingWallet, activationPaymentInfo?.tokenId) + : '' + const amount = activationPaymentInfo?.amount ?? '' const paymentDenominationSymbol = - paymentCurrencyCode == null + activationPaymentInfo == null ? '' - : getExchangeDenomByCurrencyCode( + : getExchangeDenom( existingWallet.currencyConfig, - paymentCurrencyCode + activationPaymentInfo.tokenId ).symbol ?? '' const [ @@ -121,10 +117,7 @@ export const CreateWalletAccountSelectScene = withWallet((props: Props) => { const paymentWallet = account.currencyWallets[walletId] const isRenderSelect = walletId === '' || walletAccountActivationQuoteError - const paymentTokenId = - paymentCurrencyCode === '' - ? null - : getWalletTokenId(paymentWallet, paymentCurrencyCode) + const paymentTokenId = activationPaymentInfo?.tokenId ?? null const handleRenameAndReturnWallet = useHandler(async () => { await existingWallet.renameWallet(accountName) @@ -177,6 +170,7 @@ export const CreateWalletAccountSelectScene = withWallet((props: Props) => { const handleSubmit = useHandler(async () => { const createdWalletInstance = await handleRenameAndReturnWallet() + if (activationPaymentInfo == null) return dispatch( createAccountTransaction( props.navigation as NavigationBase, diff --git a/src/components/scenes/DevTestScene.tsx b/src/components/scenes/DevTestScene.tsx index e86a4a31934..7aef481eed4 100644 --- a/src/components/scenes/DevTestScene.tsx +++ b/src/components/scenes/DevTestScene.tsx @@ -1,7 +1,7 @@ import { useNavigation } from '@react-navigation/native' import { addBreadcrumb, captureException } from '@sentry/react-native' import { eq } from 'biggystring' -import { InsufficientFundsError } from 'edge-core-js' +import { type EdgeCurrencyWallet, InsufficientFundsError } from 'edge-core-js' import * as React from 'react' import { type ReturnKeyType, View } from 'react-native' import type { AirshipBridge } from 'react-native-airship' @@ -10,11 +10,10 @@ import { showBackupModal } from '../../actions/BackupModalActions' import { launchDeepLink } from '../../actions/DeepLinkingActions' import { Fontello } from '../../assets/vector' import { ENV } from '../../env' -import { useSelectedWallet } from '../../hooks/useSelectedWallet' import { lstrings } from '../../locales/strings' import type { HomeAddress } from '../../types/FormTypes' import { useState } from '../../types/reactHooks' -import { useDispatch } from '../../types/reactRedux' +import { useDispatch, useSelector } from '../../types/reactRedux' import type { EdgeTabsSceneProps, NavigationBase @@ -69,9 +68,12 @@ export const DevTestScene: React.FC = props => { const dispatch = useDispatch() // TODO: Make this scene work without useSelectedWallet() for unit testing compatibility - const selectedWallet = useSelectedWallet() - const walletId = selectedWallet?.wallet.id ?? '' - const tokenId = selectedWallet?.tokenId ?? null + const { id: walletId, tokenId } = useSelector( + state => state.ui.settings.mostRecentWallets[0] ?? { id: '', tokenId: null } + ) + const account = useSelector(state => state.core.account) + const wallet: EdgeCurrencyWallet | undefined = + account.currencyWallets[walletId] const [value0, setValue0] = useState('') const [value1, setValue1] = useState('') @@ -122,13 +124,13 @@ export const DevTestScene: React.FC = props => { } const handleFlipInputModal = (): void => { - if (selectedWallet == null) return + if (wallet == null) return Airship.show(bridge => { - if (selectedWallet == null) return null + if (wallet == null) return null return ( = props => { }) } - const coreWallet = selectedWallet?.wallet - let balance = coreWallet?.balanceMap.get(tokenId) ?? '' + let balance = wallet?.balanceMap.get(tokenId) ?? '' if (eq(balance, '0')) balance = '' const headerText = 'Select Wallet' const handleHeaderPress = (): void => { @@ -221,17 +222,17 @@ export const DevTestScene: React.FC = props => { // Hack. If wallet name first char is lowercase, start with crypto focused, otherwise default to fiat const defaultField = - (coreWallet?.name?.charAt(0).toLowerCase() ?? '') === - (coreWallet?.name?.charAt(0) ?? '') + (wallet?.name?.charAt(0).toLowerCase() ?? '') === + (wallet?.name?.charAt(0) ?? '') // Hack. If wallet name 2nd char is lowercase, start with keyboard down const keyboardVisible = - (coreWallet?.name?.charAt(1).toLowerCase() ?? '') !== - (coreWallet?.name?.charAt(1) ?? '') + (wallet?.name?.charAt(1).toLowerCase() ?? '') !== + (wallet?.name?.charAt(1) ?? '') const editable = - (coreWallet?.name?.charAt(2).toLowerCase() ?? '') === - (coreWallet?.name?.charAt(2) ?? '') + (wallet?.name?.charAt(2).toLowerCase() ?? '') === + (wallet?.name?.charAt(2) ?? '') const returnKeyType: ReturnKeyType = 'done' return ( @@ -452,12 +453,12 @@ export const DevTestScene: React.FC = props => { label="InsufficientFeesModal" marginRem={0.25} onPress={async () => { - if (coreWallet == null) return + if (wallet == null) return await showInsufficientFeesModal({ coreError: new InsufficientFundsError({ tokenId: null }), countryCode: 'US', navigation: navigation as NavigationBase, - wallet: coreWallet + wallet }) }} /> @@ -589,11 +590,11 @@ export const DevTestScene: React.FC = props => { /> Ensure errors above don't push me down - {selectedWallet == null ? null : ( + {wallet == null ? null : ( builtInToken.currencyCode === currencyCode - ) != null - const approveAdd = !isMatchingBuiltinCurrencyCode - ? true - : await Airship.show(bridge => ( - - )) - - if (approveAdd) { - // Check if custom token input conflicts with custom tokens. - if (currencyConfig.customTokens[newTokenId] != null) { - // Always override changes to custom tokens - // TODO: Fine for if they are on this scene intentionally modifying a - // custom token, but maybe warn about this override if they are trying - // to add a new custom token with the same contract address as an - // existing custom token - await currencyConfig.changeCustomToken(newTokenId, customTokenInput) - } else { - await currencyConfig.addCustomToken(customTokenInput) - } - - await wallet.changeEnabledTokenIds([ - ...wallet.enabledTokenIds, - newTokenId - ]) - logActivity( - `Add Custom Token: ${account.username} -- ${getWalletName( - wallet - )} -- ${ - wallet.type - } -- ${newTokenId} -- ${currencyCode} -- ${decimals}` - ) + // Check if custom token input conflicts with custom tokens. + if (currencyConfig.customTokens[newTokenId] != null) { + // Always override changes to custom tokens + // TODO: Fine for if they are on this scene intentionally modifying a + // custom token, but maybe warn about this override if they are trying + // to add a new custom token with the same contract address as an + // existing custom token + await currencyConfig.changeCustomToken(newTokenId, customTokenInput) + } else { + await currencyConfig.addCustomToken(customTokenInput) } + + await wallet.changeEnabledTokenIds([ + ...wallet.enabledTokenIds, + newTokenId + ]) + logActivity( + `Add Custom Token: ${account.username} -- ${getWalletName(wallet)} -- ${ + wallet.type + } -- ${newTokenId} -- ${currencyCode} -- ${decimals}` + ) navigation.goBack() } }) diff --git a/src/components/scenes/Fio/FioAddressDetailsScene.tsx b/src/components/scenes/Fio/FioAddressDetailsScene.tsx index 726fd9cf90b..f5c4b8337e4 100644 --- a/src/components/scenes/Fio/FioAddressDetailsScene.tsx +++ b/src/components/scenes/Fio/FioAddressDetailsScene.tsx @@ -201,7 +201,7 @@ const getStyles = cacheStyles((theme: Theme) => ({ export const FioAddressDetailsScene = connect( state => ({ - fioWallets: state.ui.wallets.fioWallets + fioWallets: state.ui.fio.fioWallets }), dispatch => ({}) )(withTheme(FioAddressDetails)) diff --git a/src/components/scenes/Fio/FioAddressListScene.tsx b/src/components/scenes/Fio/FioAddressListScene.tsx index f8042f7c708..826260ad525 100644 --- a/src/components/scenes/Fio/FioAddressListScene.tsx +++ b/src/components/scenes/Fio/FioAddressListScene.tsx @@ -264,7 +264,7 @@ export const FioAddressListScene = connect( state => ({ fioAddresses: state.ui.fioAddress.fioAddresses, fioDomains: state.ui.fioAddress.fioDomains, - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, loading: state.ui.fioAddress.fioAddressesLoading, isConnected: state.network.isConnected }), diff --git a/src/components/scenes/Fio/FioAddressRegisterScene.tsx b/src/components/scenes/Fio/FioAddressRegisterScene.tsx index f60e0a4e38d..533a24db6a7 100644 --- a/src/components/scenes/Fio/FioAddressRegisterScene.tsx +++ b/src/components/scenes/Fio/FioAddressRegisterScene.tsx @@ -667,7 +667,7 @@ export const FioAddressRegisterScene = connect< OwnProps >( state => ({ - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, fioPlugin: state.core.account.currencyConfig.fio ?? typeHack, isConnected: state.network.isConnected }), diff --git a/src/components/scenes/Fio/FioAddressRegisterSelectWalletScene.tsx b/src/components/scenes/Fio/FioAddressRegisterSelectWalletScene.tsx index 4aaf75c487b..1159d46d34e 100644 --- a/src/components/scenes/Fio/FioAddressRegisterSelectWalletScene.tsx +++ b/src/components/scenes/Fio/FioAddressRegisterSelectWalletScene.tsx @@ -25,7 +25,6 @@ import type { } from '../../../types/routerTypes' import type { EdgeAsset, FioDomain } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { getWalletName } from '../../../util/CurrencyWalletHelpers' import { getRegInfo, type PaymentInfo } from '../../../util/FioAddressUtils' import { @@ -76,7 +75,6 @@ interface OwnProps extends EdgeAppSceneProps<'fioAddressRegisterSelectWallet'> { } interface DispatchProps { - onSelectWallet: (walletId: string, currencyCode: string) => void onLogEvent: (event: TrackingEventName, values: TrackingValues) => void } @@ -222,9 +220,6 @@ export class FioAddressRegisterSelectWallet extends React.Component< ownerPublicKey: selectedWallet.publicWalletInfo.keys.publicKey }) } else { - const paymentCurrencyCode = getCurrencyCode(wallet, tokenId) - this.props.onSelectWallet(walletId, paymentCurrencyCode) - const { amount: exchangeAmount } = allPaymentInfo[pluginId][tokenId ?? ''] @@ -240,6 +235,7 @@ export class FioAddressRegisterSelectWallet extends React.Component< bitpayUrl, { wallet, + tokenId, metadata: { name: lstrings.fio_address_register_metadata_name, notes: `${lstrings.title_fio_address_confirmation}\n${fioAddress}` @@ -388,7 +384,7 @@ const FioAddressRegisterSelectWalletConnected = connect< const { wallet } = ownProps return { account: state.core.account, - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, fioPlugin: state.core.account.currencyConfig.fio, fioDisplayDenomination: selectDisplayDenom( state, @@ -400,12 +396,6 @@ const FioAddressRegisterSelectWalletConnected = connect< } }, dispatch => ({ - onSelectWallet(walletId: string, currencyCode: string) { - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { currencyCode, walletId } - }) - }, onLogEvent(event: TrackingEventName, values: TrackingValues) { dispatch(logEvent(event, values)) } diff --git a/src/components/scenes/Fio/FioDomainRegisterScene.tsx b/src/components/scenes/Fio/FioDomainRegisterScene.tsx index 00c0091bfe4..4e1bf58d55a 100644 --- a/src/components/scenes/Fio/FioDomainRegisterScene.tsx +++ b/src/components/scenes/Fio/FioDomainRegisterScene.tsx @@ -394,7 +394,7 @@ export const FioDomainRegisterScene = connect< OwnProps >( state => ({ - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, fioPlugin: state.core.account.currencyConfig.fio ?? typeHack, isConnected: state.network.isConnected }), diff --git a/src/components/scenes/Fio/FioDomainRegisterSelectWalletScene.tsx b/src/components/scenes/Fio/FioDomainRegisterSelectWalletScene.tsx index bac7d0a22c4..065a90099a8 100644 --- a/src/components/scenes/Fio/FioDomainRegisterSelectWalletScene.tsx +++ b/src/components/scenes/Fio/FioDomainRegisterSelectWalletScene.tsx @@ -26,7 +26,6 @@ import type { } from '../../../types/routerTypes' import type { EdgeAsset } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { getWalletName } from '../../../util/CurrencyWalletHelpers' import { getDomainRegInfo, @@ -75,7 +74,6 @@ interface OwnProps extends EdgeAppSceneProps<'fioDomainRegisterSelectWallet'> { } interface DispatchProps { - onSelectWallet: (walletId: string, currencyCode: string) => void onLogEvent: (event: TrackingEventName, values: TrackingValues) => void } @@ -210,9 +208,6 @@ class FioDomainRegisterSelectWallet extends React.PureComponent< ownerPublicKey: selectedWallet.publicWalletInfo.keys.publicKey }) } else { - const paymentCurrencyCode = getCurrencyCode(wallet, tokenId) - this.props.onSelectWallet(walletId, paymentCurrencyCode) - const { amount: exchangeAmount } = allPaymentInfo[pluginId][tokenId ?? ''] @@ -228,6 +223,7 @@ class FioDomainRegisterSelectWallet extends React.PureComponent< bitpayUrl, { wallet, + tokenId, metadata: { name: lstrings.fio_address_register_metadata_name, notes: `${lstrings.title_register_fio_domain}\n${fioDomain}` @@ -369,7 +365,7 @@ const FioDomainRegisterSelectWalletConnected = connect< >( (state, ownProps) => ({ account: state.core.account, - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, fioPlugin: state.core.account.currencyConfig.fio, fioDisplayDenomination: selectDisplayDenom( state, @@ -379,12 +375,6 @@ const FioDomainRegisterSelectWalletConnected = connect< isConnected: state.network.isConnected }), dispatch => ({ - onSelectWallet(walletId: string, currencyCode: string) { - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { currencyCode, walletId } - }) - }, onLogEvent(event: TrackingEventName, values: TrackingValues) { dispatch(logEvent(event, values)) } diff --git a/src/components/scenes/Fio/FioRequestConfirmationScene.tsx b/src/components/scenes/Fio/FioRequestConfirmationScene.tsx index e7d1230acfa..0f9f91fb0a3 100644 --- a/src/components/scenes/Fio/FioRequestConfirmationScene.tsx +++ b/src/components/scenes/Fio/FioRequestConfirmationScene.tsx @@ -524,7 +524,7 @@ export const FioRequestConfirmationScene = withWallet((ownProps: OwnProps) => { defaultIsoFiat ) ) - const fioWallets = useSelector(state => state.ui.wallets.fioWallets) + const fioWallets = useSelector(state => state.ui.fio.fioWallets) const isConnected = useSelector(state => state.network.isConnected) const exchangeDenomination = getExchangeDenom(wallet.currencyConfig, tokenId) diff --git a/src/components/scenes/Fio/FioRequestListScene.tsx b/src/components/scenes/Fio/FioRequestListScene.tsx index 6b6842cfa18..6ccab673b5b 100644 --- a/src/components/scenes/Fio/FioRequestListScene.tsx +++ b/src/components/scenes/Fio/FioRequestListScene.tsx @@ -73,7 +73,6 @@ interface StateProps { } interface DispatchProps { - onSelectWallet: (walletId: string, currencyCode: string) => void refreshAllFioAddresses: () => Promise } @@ -395,7 +394,7 @@ class FioRequestList extends React.Component { showError(lstrings.fio_network_alert_text) return } - const { account, onSelectWallet } = this.props + const { account } = this.props const edgeAsset = fioCodeToEdgeAsset( account, fioRequest.content.chain_code.toUpperCase(), @@ -418,10 +417,6 @@ class FioRequestList extends React.Component { // Just do the send if we have one choice: if (walletIds.length === 1) { const [walletId] = walletIds - const wallet = account.currencyWallets[walletId] - - const currencyCode = getCurrencyCode(wallet, tokenId) - onSelectWallet(walletId, currencyCode) await this.sendCrypto(fioRequest, walletId, tokenId) return } @@ -438,9 +433,6 @@ class FioRequestList extends React.Component { )) if (result?.type === 'wallet') { const { walletId, tokenId } = result - const wallet = account.currencyWallets[walletId] - const currencyCode = getCurrencyCode(wallet, tokenId) - onSelectWallet(walletId, currencyCode) await this.sendCrypto(fioRequest, walletId, tokenId) } return @@ -777,18 +769,12 @@ const getStyles = cacheStyles((theme: Theme) => ({ export const FioRequestListScene = connect( state => ({ account: state.core.account, - fioWallets: state.ui.wallets.fioWallets, + fioWallets: state.ui.fio.fioWallets, fioAddresses: state.ui.fioAddress.fioAddresses, currencyWallets: state.core.account.currencyWallets, isConnected: state.network.isConnected }), dispatch => ({ - onSelectWallet(walletId: string, currencyCode: string) { - dispatch({ - type: 'UI/WALLETS/SELECT_WALLET', - data: { currencyCode, walletId } - }) - }, async refreshAllFioAddresses() { await dispatch(refreshAllFioAddresses()) } diff --git a/src/components/scenes/Fio/FioStakingChangeScene.tsx b/src/components/scenes/Fio/FioStakingChangeScene.tsx index 8d95508d037..07fc8997bd7 100644 --- a/src/components/scenes/Fio/FioStakingChangeScene.tsx +++ b/src/components/scenes/Fio/FioStakingChangeScene.tsx @@ -25,10 +25,7 @@ import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import { convertCurrency } from '../../../selectors/WalletSelectors' import { useDispatch, useSelector } from '../../../types/reactRedux' import type { EdgeAppSceneProps } from '../../../types/routerTypes' -import { - getCurrencyCode, - getCurrencyCodeMultiplier -} from '../../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { type FioStakingBalanceType, getFioStakingBalances @@ -214,9 +211,9 @@ export const FioStakingChangeScene = withWallet((props: Props) => { } case 'unstake': { const nativeAmount = stakingBalances.staked.native - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( currencyWallet.currencyConfig, - 'FIO' + null ) const exchangeAmount = div(nativeAmount, multiplier, multiplier.length) onAmountsChanged({ diff --git a/src/components/scenes/Loans/LoanCreateScene.tsx b/src/components/scenes/Loans/LoanCreateScene.tsx index 6477c85cdab..44398d20eee 100644 --- a/src/components/scenes/Loans/LoanCreateScene.tsx +++ b/src/components/scenes/Loans/LoanCreateScene.tsx @@ -36,12 +36,8 @@ import type { } from '../../../types/routerTypes' import { getWalletPickerExcludeWalletIds } from '../../../util/borrowUtils' import { getBorrowPluginIconUri } from '../../../util/CdnUris' -import { - getCurrencyCode, - getTokenId, - getTokenIdForced -} from '../../../util/CurrencyInfoHelpers' -import { enableTokenCurrencyCode } from '../../../util/CurrencyWalletHelpers' +import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' +import { enableTokens } from '../../../util/CurrencyWalletHelpers' import { DECIMAL_PRECISION, removeIsoPrefix, @@ -60,6 +56,7 @@ import { } from '../../modals/WalletListModal' import { CryptoFiatAmountRow } from '../../rows/CryptoFiatAmountRow' import { Airship, showError } from '../../services/AirshipInstance' +import { LOAN_TOKEN_IDS } from '../../services/LoanManagerService' import { cacheStyles, type Theme, useTheme } from '../../services/ThemeContext' import { Alert } from '../../themed/Alert' import { EdgeText } from '../../themed/EdgeText' @@ -87,8 +84,14 @@ export const LoanCreateScene = (props: Props) => { // Force enable tokens required for loan useAsyncEffect( async () => { - await enableTokenCurrencyCode('WBTC', borrowEngineWallet) - await enableTokenCurrencyCode('USDC', borrowEngineWallet) + await enableTokens( + [LOAN_TOKEN_IDS[borrowEngineWallet.currencyInfo.pluginId].WBTC], + borrowEngineWallet + ) + await enableTokens( + [LOAN_TOKEN_IDS[borrowEngineWallet.currencyInfo.pluginId].USDC], + borrowEngineWallet + ) }, [], 'LoanCreateScene:1' @@ -116,20 +119,9 @@ export const LoanCreateScene = (props: Props) => { // Hard-coded src/dest assets, used as intermediate src/dest steps for cases if the // user selected src/dest that don't involve the borrowEngineWallet. // Currently, the only use case is selecting fiat (bank) as a src/dest. - const hardCollateralCurrencyCode = 'WBTC' - const hardSrcTokenAddr = React.useMemo( - () => - getTokenIdForced( - account, - borrowEnginePluginId, - hardCollateralCurrencyCode - ), - [account, borrowEnginePluginId] - ) - const hardDestTokenAddr = React.useMemo( - () => getTokenIdForced(account, borrowEnginePluginId, 'USDC'), - [account, borrowEnginePluginId] - ) + const hardCollateralTokenId = LOAN_TOKEN_IDS[borrowEnginePluginId].WBTC + const hardSrcTokenAddr = LOAN_TOKEN_IDS[borrowEnginePluginId].WBTC + const hardDestTokenAddr = LOAN_TOKEN_IDS[borrowEnginePluginId].USDC const hardAllowedSrcAsset = [ { pluginId: borrowEnginePluginId, tokenId: hardSrcTokenAddr }, { pluginId: 'bitcoin', tokenId: null } @@ -155,13 +147,9 @@ export const LoanCreateScene = (props: Props) => { const borrowEngineWalletPluginId = borrowEngineWallet.currencyInfo.pluginId - const collateralTokenId = getTokenId( - borrowEngineWallet.currencyConfig, - hardCollateralCurrencyCode - ) const collateralToken = - collateralTokenId != null - ? allTokens[borrowEngineWalletPluginId][collateralTokenId] + hardCollateralTokenId != null + ? allTokens[borrowEngineWalletPluginId][hardCollateralTokenId] : null const collateralDenoms = collateralToken != null @@ -284,7 +272,7 @@ export const LoanCreateScene = (props: Props) => { // conversions have the same quote asset. const collateralToFiatRate = useCurrencyFiatRate({ pluginId: borrowEnginePluginId, - tokenId: collateralTokenId ?? null, + tokenId: hardCollateralTokenId ?? null, isoFiatCurrencyCode: defaultIsoFiat }) diff --git a/src/components/scenes/Loans/LoanManageScene.tsx b/src/components/scenes/Loans/LoanManageScene.tsx index 642b2777027..c91e7f4bc42 100644 --- a/src/components/scenes/Loans/LoanManageScene.tsx +++ b/src/components/scenes/Loans/LoanManageScene.tsx @@ -1,4 +1,5 @@ import { add, gt, max, mul } from 'biggystring' +import type { EdgeTokenId } from 'edge-core-js' import * as React from 'react' import type { AirshipBridge } from 'react-native-airship' import { cacheStyles } from 'react-native-patina' @@ -42,7 +43,6 @@ import { } from '../../../util/ActionProgramUtils' import { getWalletPickerExcludeWalletIds } from '../../../util/borrowUtils' import { getBorrowPluginIconUri } from '../../../util/CdnUris' -import { getTokenIdForced } from '../../../util/CurrencyInfoHelpers' import { getExecutionNetworkFees } from '../../../util/networkFeeUtils' import { removeIsoPrefix, zeroString } from '../../../util/utils' import { FiatAmountInputCard } from '../../cards/FiatAmountInputCard' @@ -60,6 +60,7 @@ import { } from '../../modals/WalletListModal' import { Shimmer } from '../../progress-indicators/Shimmer' import { Airship, showError } from '../../services/AirshipInstance' +import { LOAN_TOKEN_IDS } from '../../services/LoanManagerService' import { type Theme, useTheme } from '../../services/ThemeContext' import { Alert } from '../../themed/Alert' import { EdgeText } from '../../themed/EdgeText' @@ -169,17 +170,12 @@ export const LoanManageSceneComponent = (props: Props) => { // Src/dest Wallet Picker const wallets = useWatch(account, 'currencyWallets') - const hardDebtTokenId = React.useMemo( - () => getTokenIdForced(account, borrowEnginePluginId, 'USDC'), - [account, borrowEnginePluginId] - ) - const hardCollateralTokenId = React.useMemo( - () => getTokenIdForced(account, borrowEnginePluginId, 'WBTC'), - [account, borrowEnginePluginId] - ) - const hardAllowedCollateralAssets = [ - { pluginId: borrowEnginePluginId, tokenId: hardCollateralTokenId } - ] + const hardDebtTokenId = LOAN_TOKEN_IDS[borrowEnginePluginId].USDC + const hardCollateralTokenId = LOAN_TOKEN_IDS[borrowEnginePluginId].WBTC + const hardAllowedCollateralAssets: Array<{ + pluginId: string + tokenId: EdgeTokenId + }> = [{ pluginId: borrowEnginePluginId, tokenId: hardCollateralTokenId }] if (loanManageType === 'loan-manage-deposit') hardAllowedCollateralAssets.push({ pluginId: 'bitcoin', tokenId: null }) const hardAllowedDebtAssets = [ diff --git a/src/components/scenes/ManageTokensScene.tsx b/src/components/scenes/ManageTokensScene.tsx index 3f62eba8f47..317f9bf3749 100644 --- a/src/components/scenes/ManageTokensScene.tsx +++ b/src/components/scenes/ManageTokensScene.tsx @@ -3,7 +3,6 @@ import * as React from 'react' import { SectionList, View } from 'react-native' import { FlatList } from 'react-native-gesture-handler' -import { PREFERRED_TOKENS } from '../../constants/WalletAndCurrencyConstants' import { useHandler } from '../../hooks/useHandler' import { useRowLayout } from '../../hooks/useRowLayout' import { useWalletName } from '../../hooks/useWalletName' @@ -71,32 +70,17 @@ function ManageTokensSceneComponent(props: Props) { // Sort the token list: const sortedTokenIds = React.useMemo(() => { - // Make a table of preferred tokenId's: - const preferredIdSet = new Set() - for (const currencyCode of PREFERRED_TOKENS) { - const tokenId = Object.keys(allTokens).find( - tokenId => allTokens[tokenId].currencyCode === currencyCode - ) - if (tokenId != null) preferredIdSet.add(tokenId) - } - return Object.keys(allTokens).sort((id1, id2) => { const token1 = allTokens[id1] const token2 = allTokens[id2] const isToken1Enabled = enabledTokenSet.has(id1) const isToken2Enabled = enabledTokenSet.has(id2) - const isToken1Preferred = preferredIdSet.has(id1) - const isToken2Preferred = preferredIdSet.has(id2) // Sort enabled tokens first if (isToken1Enabled && !isToken2Enabled) return -1 if (!isToken1Enabled && isToken2Enabled) return 1 - // Then sort preferred tokens - if (isToken1Preferred && !isToken2Preferred) return -1 - if (!isToken1Preferred && isToken2Preferred) return 1 - // Finally, sort by currency code if (token1.currencyCode < token2.currencyCode) return -1 if (token1.currencyCode > token2.currencyCode) return 1 diff --git a/src/components/scenes/SendScene2.tsx b/src/components/scenes/SendScene2.tsx index 88454c80fc7..912573bb7bb 100644 --- a/src/components/scenes/SendScene2.tsx +++ b/src/components/scenes/SendScene2.tsx @@ -532,7 +532,7 @@ const SendComponent = (props: Props): React.ReactElement => { title={title} recipientAddress={publicAddress} coreWallet={coreWallet} - currencyCode={currencyCode} + tokenId={tokenId} onChangeAddress={handleChangeAddress(spendTarget)} resetSendTransaction={handleResetSendTransaction(spendTarget)} lockInputs={lockTilesMap.address} diff --git a/src/components/scenes/Staking/StakeModifyScene.tsx b/src/components/scenes/Staking/StakeModifyScene.tsx index a535e153954..6c8fe07b241 100644 --- a/src/components/scenes/Staking/StakeModifyScene.tsx +++ b/src/components/scenes/Staking/StakeModifyScene.tsx @@ -17,6 +17,7 @@ import { type ChangeQuote, type ChangeQuoteRequest, type QuoteAllocation, + type StakeAssetInfo, StakeBelowLimitError, type StakePlugin, type StakePolicy, @@ -27,11 +28,6 @@ import { HumanFriendlyError } from '../../../types/HumanFriendlyError' import { useDispatch, useSelector } from '../../../types/reactRedux' import type { EdgeAppSceneProps } from '../../../types/routerTypes' import { getCurrencyIconUris } from '../../../util/CdnUris' -import { - getCurrencyCodeMultiplier, - getTokenIdForced, - getWalletTokenId -} from '../../../util/CurrencyInfoHelpers' import { getWalletName } from '../../../util/CurrencyWalletHelpers' import { enableStakeTokens, @@ -108,6 +104,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { quoteAllocations.push({ allocationType: modification, pluginId: asset.pluginId, + tokenId: asset.tokenId, currencyCode: asset.currencyCode, nativeAmount: '0' }) @@ -124,6 +121,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { React.useState({ action: modification, stakePolicyId: stakePolicy.stakePolicyId, + tokenId: null, currencyCode: '', nativeAmount: '0', wallet, @@ -139,7 +137,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { // Ensure required tokens are enabled useAsyncEffect( async () => { - await enableStakeTokens(account, wallet, stakePolicy) + await enableStakeTokens(wallet, stakePolicy) }, [], 'StakeModifyScene' @@ -198,9 +196,9 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { ? lstrings.stake_error_stake_below_minimum : lstrings.stake_error_unstake_below_minimum if (nativeMin != null) { - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( wallet.currencyConfig, - currencyCode + changeQuoteRequest.tokenId ) const minExchangeAmount = div( nativeMin, @@ -246,33 +244,32 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { // const existingStaked = existingAllocations.staked ?? [] - const handleMaxButtonPress = (modCurrencyCode: string): (() => void) => { - return (): void => { - // TODO: Move max amount logic into stake plugin + const handleMaxButtonPress = + (modTokenId: EdgeTokenId, modCurrencyCode: string) => (): void => { + // TODO: Move max amountlogic into stake plugin if (changeQuoteRequest != null) { if (modification === 'unstake') { const allocationToMod = existingStaked.find( - positionAllocation => - positionAllocation.currencyCode === modCurrencyCode + positionAllocation => positionAllocation.tokenId === modTokenId ) if (allocationToMod == null) - throw new Error(`Existing stake not found for ${modCurrencyCode}`) + throw new Error(`Existing stake not found for ${modTokenId}`) setChangeQuoteRequest({ ...changeQuoteRequest, currencyCode: modCurrencyCode, + tokenId: modTokenId, nativeAmount: allocationToMod.nativeAmount }) } else if (modification === 'stake' && existingStaked.length === 1) { - const tokenId = getWalletTokenId(wallet, modCurrencyCode) setChangeQuoteRequest({ ...changeQuoteRequest, currencyCode: modCurrencyCode, - nativeAmount: wallet.balanceMap.get(tokenId) ?? '0' + tokenId: modTokenId, + nativeAmount: wallet.balanceMap.get(modTokenId) ?? '0' }) } } } - } const handleSlideComplete = (reset: () => void): void => { const message = { @@ -349,7 +346,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { const hideMaxButton = existingStaked.length > 1 || (disableMaxStake ?? false) const changeQuoteAllocation = changeQuoteAllocations.find( - allocation => allocation.currencyCode === currencyCode + allocation => allocation.tokenId === tokenId ) const changeQuoteAllocationNativeAmount = changeQuoteAllocation?.nativeAmount ?? '0' @@ -366,7 +363,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { : changeQuoteAllocationNativeAmount } onAmountsChanged={() => {}} - onMaxSet={handleMaxButtonPress(currencyCode)} + onMaxSet={handleMaxButtonPress(tokenId, currencyCode)} headerText={sprintf(header, getWalletName(wallet))} hideMaxButton={hideMaxButton} /> @@ -446,6 +443,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { const { currencyCode, pluginId, + tokenId, allocationType, lockInputs = false } = quoteAllocation @@ -454,12 +452,12 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { ? { allocationType, pluginId, + tokenId, currencyCode, nativeAmount: existingAllocations?.staked[0]?.nativeAmount ?? '0' } : quoteAllocation - const tokenId = getTokenIdForced(account, pluginId, currencyCode) const quoteCurrencyCode = currencyCode const quoteDenom = getExchangeDenom( account.currencyConfig[pluginId], @@ -503,7 +501,7 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { const renderStakeFeeAmountRow = ( modification: ChangeQuoteRequest['action'], - asset: { pluginId: string; currencyCode: string } + asset: StakeAssetInfo ): React.ReactElement | null => { if ( !( @@ -513,19 +511,18 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { ) ) return null - const { pluginId, currencyCode } = asset + const { pluginId, tokenId } = asset const quoteAllocation: QuoteAllocation | undefined = changeQuote != null ? changeQuote.allocations.find( allocation => allocation.allocationType === 'deductedFee' && allocation.pluginId === pluginId && - allocation.currencyCode === currencyCode + allocation.tokenId === tokenId ) : undefined if (quoteAllocation == null) return null - const tokenId = getTokenIdForced(account, pluginId, currencyCode) const quoteDenom = getExchangeDenom( account.currencyConfig[pluginId], tokenId @@ -550,22 +547,21 @@ const StakeModifySceneComponent = (props: Props): React.ReactElement => { const renderFutureUnstakeFeeAmountRow = ( modification: ChangeQuoteRequest['action'], - asset: { pluginId: string; currencyCode: string } + asset: StakeAssetInfo ): React.ReactElement | null => { if (modification !== 'stake') return null - const { pluginId, currencyCode } = asset + const { pluginId, tokenId } = asset const quoteAllocation: QuoteAllocation | undefined = changeQuote != null ? changeQuote.allocations.find( allocation => allocation.allocationType === 'futureUnstakeFee' && allocation.pluginId === pluginId && - allocation.currencyCode === currencyCode + allocation.tokenId === tokenId ) : undefined if (quoteAllocation == null) return null - const tokenId = getTokenIdForced(account, pluginId, currencyCode) const quoteDenom = getExchangeDenom( account.currencyConfig[pluginId], tokenId diff --git a/src/components/scenes/Staking/StakeOptionsScene.tsx b/src/components/scenes/Staking/StakeOptionsScene.tsx index 97d4e054847..0f4e8558ca2 100644 --- a/src/components/scenes/Staking/StakeOptionsScene.tsx +++ b/src/components/scenes/Staking/StakeOptionsScene.tsx @@ -1,5 +1,5 @@ import { gt } from 'biggystring' -import type { EdgeCurrencyWallet } from 'edge-core-js' +import type { EdgeCurrencyWallet, EdgeTokenId } from 'edge-core-js' import * as React from 'react' import { FlatList } from 'react-native-gesture-handler' import { sprintf } from 'sprintf-js' @@ -12,7 +12,7 @@ import { getStakePlugins } from '../../../plugins/stake-plugins/stakePlugins' import type { StakePolicy } from '../../../plugins/stake-plugins/types' import { useSelector } from '../../../types/reactRedux' import type { EdgeAppSceneProps } from '../../../types/routerTypes' -import { getTokenIdForced } from '../../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { getPluginFromPolicyId, getPoliciesFromPlugins, @@ -37,35 +37,33 @@ interface Props extends EdgeAppSceneProps<'stakeOptions'> { } export interface StakeOptionsParams { - currencyCode: string + tokenId: EdgeTokenId walletId: string } const StakeOptionsSceneComponent = (props: Props) => { const { navigation, route, wallet } = props - const { currencyCode } = route.params + const { tokenId } = route.params const [stakePlugins = []] = useAsyncValue( async () => await getStakePlugins(wallet.currencyInfo.pluginId) ) const stakePositionMap = useSelector( state => state.staking.walletStakingMap[wallet.id]?.stakePositionMap ?? {} ) - const stakePolicies = getPoliciesFromPlugins( - stakePlugins, - stakePositionMap, - wallet, - currencyCode - ) const theme = useTheme() const account = useSelector(state => state.core.account) const countryCode = useSelector(state => state.ui.countryCode) const pluginId = wallet?.currencyInfo.pluginId - const tokenId = pluginId - ? getTokenIdForced(account, pluginId, currencyCode) - : null const iconColor = useIconColor({ pluginId, tokenId }) + const currencyCode = getCurrencyCode(wallet, tokenId) + const stakePolicies = getPoliciesFromPlugins( + stakePlugins, + stakePositionMap, + wallet, + tokenId + ) const stakePolicyArray = React.useMemo( () => Object.values(stakePolicies), [stakePolicies] diff --git a/src/components/scenes/Staking/StakeOverviewScene.tsx b/src/components/scenes/Staking/StakeOverviewScene.tsx index 4a7ece78d89..e9a290d74f6 100644 --- a/src/components/scenes/Staking/StakeOverviewScene.tsx +++ b/src/components/scenes/Staking/StakeOverviewScene.tsx @@ -18,10 +18,9 @@ import type { StakePolicy, StakePosition } from '../../../plugins/stake-plugins/types' -import { selectDisplayDenomByCurrencyCode } from '../../../selectors/DenominationSelectors' +import { selectDisplayDenom } from '../../../selectors/DenominationSelectors' import { useDispatch, useSelector } from '../../../types/reactRedux' import type { EdgeSceneProps } from '../../../types/routerTypes' -import { getTokenIdForced } from '../../../util/CurrencyInfoHelpers' import { infoServerData } from '../../../util/network' import { makePeriodicTask } from '../../../util/PeriodicTask' import { @@ -95,10 +94,10 @@ const StakeOverviewSceneComponent: React.FC = props => { : [...stakePolicy.stakeAssets, ...stakePolicy.rewardAssets].reduce( (denomMap: DenomMap, asset) => { denomMap[asset.currencyCode] = dispatch((_, getState) => - selectDisplayDenomByCurrencyCode( + selectDisplayDenom( getState(), account.currencyConfig[asset.pluginId], - asset.currencyCode + asset.tokenId ) ) return denomMap @@ -166,7 +165,7 @@ const StakeOverviewSceneComponent: React.FC = props => { useAsyncEffect( async () => { if (stakePolicy == null) return - await enableStakeTokens(account, wallet, stakePolicy) + await enableStakeTokens(wallet, stakePolicy) }, [stakePolicy], 'StakeOverviewSceneComponent 1' @@ -210,7 +209,8 @@ const StakeOverviewSceneComponent: React.FC = props => { }: { item: PositionAllocation }): React.ReactElement => { - const { allocationType, currencyCode, nativeAmount, pluginId } = item + const { allocationType, currencyCode, nativeAmount, pluginId, tokenId } = + item const titleBase = allocationType === 'staked' ? lstrings.stake_s_staked @@ -223,7 +223,6 @@ const StakeOverviewSceneComponent: React.FC = props => { )}${getAllocationLocktimeMessage(item)}` const denomination = displayDenomMap[currencyCode] - const tokenId = getTokenIdForced(account, pluginId, currencyCode) // This is not the wallet we are staking from, but the asset being staked. return ( > = { + ethereum: { + USDC: 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + USDT: 'dac17f958d2ee523a2206206994597c13d831ec7', + DAI: '6b175474e89094c44da98b954eedeac495271d0f', + WBTC: '2260fac5e5542a773aa44fbcfedf7c193bc2c599' + }, + polygon: { + USDC: '2791bca1f2de4661ed88a30c99a7a9449aa84174', + USDT: 'c2132d05d31c914a87c6611c10748aeb04b58e8f', + DAI: '8f3cf7ad23cd3cadbd9735aff958023239c6a063', + WBTC: '1bfd67037b42cf73acf2047067bd4f2c47d9bfd6' + } +} const USD_BASED_TOKEN_IDS: string[] = [ // USDC on Ethereum 'a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', diff --git a/src/components/themed/EdgeProviderComponent.tsx b/src/components/themed/EdgeProviderComponent.tsx index 46cb0df6a6c..f150951a740 100644 --- a/src/components/themed/EdgeProviderComponent.tsx +++ b/src/components/themed/EdgeProviderComponent.tsx @@ -1,4 +1,5 @@ import { uncleaner } from 'cleaners' +import type { EdgeCurrencyWallet } from 'edge-core-js' import * as React from 'react' import { type NativeSyntheticEvent, Platform } from 'react-native' import { WebView, type WebViewMessageEvent } from 'react-native-webview' @@ -17,7 +18,6 @@ import type { GuiPlugin } from '../../types/GuiPluginTypes' import { useDispatch, useSelector } from '../../types/reactRedux' import type { NavigationBase } from '../../types/routerTypes' import type { UriQueryMap } from '../../types/WebTypes' -import { getTokenIdForced } from '../../util/CurrencyInfoHelpers' import { makePluginUri } from '../../util/GuiPluginTools' import { bestOfPlugins } from '../../util/ReferralHelpers' import { setPluginScene } from '../navigation/GuiPluginBackButton' @@ -60,10 +60,7 @@ export function EdgeProviderComponent(props: Props): React.ReactElement { ) const accountReferral = useSelector(state => state.account.accountReferral) const selectedWalletId = useSelector( - state => state.ui.wallets.selectedWalletId - ) - const selectedCurrencyCode = useSelector( - state => state.ui.wallets.selectedCurrencyCode + state => state.ui.settings.mostRecentWallets[0]?.id ?? '' ) const defaultIsoFiat = useSelector(state => state.ui.settings.defaultIsoFiat) const countryCode = useSelector(state => state.ui.settings.countryCode) @@ -147,15 +144,8 @@ export function EdgeProviderComponent(props: Props): React.ReactElement { // Build our EdgeProvider instance one time: const [edgeProvider] = React.useState(() => { - const selectedWallet = account.currencyWallets[selectedWalletId] - const selectedTokenId = - selectedWallet == null - ? null - : getTokenIdForced( - account, - selectedWallet.currencyInfo.pluginId, - selectedCurrencyCode - ) + const selectedWallet: EdgeCurrencyWallet | undefined = + account.currencyWallets[selectedWalletId] return new EdgeProviderServer({ account, defaultIsoFiat, @@ -163,7 +153,6 @@ export function EdgeProviderComponent(props: Props): React.ReactElement { navigation, plugin, reloadWebView, - selectedTokenId, selectedWallet, deepLink: { deepPath, diff --git a/src/components/themed/SendFromFioRows.tsx b/src/components/themed/SendFromFioRows.tsx index 62d102ee9b5..7237bd54f75 100644 --- a/src/components/themed/SendFromFioRows.tsx +++ b/src/components/themed/SendFromFioRows.tsx @@ -316,7 +316,7 @@ export const SendFromFioRows = connect( state => { return { fioAddresses: state.ui.fioAddress.fioAddresses, - fioWallets: state.ui.wallets.fioWallets + fioWallets: state.ui.fio.fioWallets } }, dispatch => ({ diff --git a/src/components/themed/TransactionListTop.tsx b/src/components/themed/TransactionListTop.tsx index f19dec3b204..98367fc86c2 100644 --- a/src/components/themed/TransactionListTop.tsx +++ b/src/components/themed/TransactionListTop.tsx @@ -152,9 +152,7 @@ export class TransactionListTopComponent extends React.PureComponent { // Update staking policies if the wallet changes if (prevProps.wallet !== this.props.wallet) { this.props - .dispatch( - updateStakingState(this.props.currencyCode, this.props.wallet) - ) + .dispatch(updateStakingState(this.props.tokenId, this.props.wallet)) .catch(err => { showError(err) }) @@ -164,7 +162,7 @@ export class TransactionListTopComponent extends React.PureComponent { let lockedNativeAmount = '0' for (const stakePosition of Object.values(this.props.stakePositionMap)) { const { staked, earned } = getPositionAllocations(stakePosition) - total = this.getTotalPosition(this.props.currencyCode, [ + total = this.getTotalPosition(this.props.tokenId, [ ...staked, ...earned ]) @@ -180,19 +178,19 @@ export class TransactionListTopComponent extends React.PureComponent { componentDidMount() { this.props - .dispatch(updateStakingState(this.props.currencyCode, this.props.wallet)) + .dispatch(updateStakingState(this.props.tokenId, this.props.wallet)) .catch(err => { showError(err) }) } getTotalPosition = ( - currencyCode: string, + tokenId: EdgeTokenId, positions: PositionAllocation[] ): string => { const { pluginId } = this.props.wallet.currencyInfo const amount = positions - .filter(p => p.currencyCode === currencyCode && p.pluginId === pluginId) + .filter(p => p.tokenId === tokenId && p.pluginId === pluginId) .reduce((prev, curr) => add(prev, curr.nativeAmount), '0') return amount } @@ -762,12 +760,11 @@ export class TransactionListTopComponent extends React.PureComponent { handleStakePress = () => { triggerHaptic('impactLight') - const { currencyCode, wallet, navigation, stakePolicies, tokenId } = - this.props + const { wallet, navigation, stakePolicies, tokenId } = this.props const { stakePlugins } = this.props // Handle FIO staking - if (currencyCode === 'FIO') { + if (wallet.currencyInfo.pluginId === 'fio' && tokenId == null) { navigation.push('fioStakingOverview', { tokenId, walletId: wallet.id @@ -791,7 +788,7 @@ export class TransactionListTopComponent extends React.PureComponent { // More than one option or stakePolicies are not yet loaded/populated navigation.push('stakeOptions', { walletId: wallet.id, - currencyCode + tokenId }) } } @@ -960,7 +957,7 @@ export function TransactionListTop(props: OwnProps) { stakePlugins, stakePositionMap, wallet, - currencyCode + tokenId ) const displayDenomination = useSelector(state => diff --git a/src/components/themed/WalletList.tsx b/src/components/themed/WalletList.tsx index 66b11f22ecd..37185d120ee 100644 --- a/src/components/themed/WalletList.tsx +++ b/src/components/themed/WalletList.tsx @@ -161,10 +161,9 @@ export const WalletList: React.FC = (props: Props) => { // Find the mentioned wallet, if it still exists: const row = filteredWalletList.find(row => { if (row.type !== 'asset') return false - const { wallet, token } = row + const { wallet, tokenId } = row if (wallet.id !== item.id) return false - const { currencyCode } = token ?? wallet.currencyInfo - return currencyCode.toLowerCase() === item.currencyCode.toLowerCase() + return tokenId === item.tokenId }) if (row != null) out.push({ ...row, key: `recent-${row.key}` }) diff --git a/src/components/themed/WalletListCreateRow.tsx b/src/components/themed/WalletListCreateRow.tsx index 35d8f8cc5a4..a9245e1b8cc 100644 --- a/src/components/themed/WalletListCreateRow.tsx +++ b/src/components/themed/WalletListCreateRow.tsx @@ -15,7 +15,6 @@ import { lstrings } from '../../locales/strings' import type { WalletCreateItem } from '../../selectors/getCreateWalletList' import { useDispatch, useSelector } from '../../types/reactRedux' import type { ThunkAction } from '../../types/reduxTypes' -import { getTokenIdForced } from '../../util/CurrencyInfoHelpers' import { logEvent, type TrackingEventName } from '../../util/tracking' import { EdgeTouchableOpacity } from '../common/EdgeTouchableOpacity' import { CryptoIcon } from '../icons/CryptoIcon' @@ -50,6 +49,7 @@ export const WalletListCreateRowComponent = ( displayName: currencyName = '', keyOptions = {}, pluginId, + tokenId, walletType } = createItem const createWalletIds = @@ -62,8 +62,6 @@ export const WalletListCreateRowComponent = ( const theme = useTheme() const styles = getStyles(theme) - const tokenId = getTokenIdForced(account, pluginId, currencyCode) - const networkName = pluginId != null && tokenId != null ? ` (${account.currencyConfig[pluginId].currencyInfo.displayName})` diff --git a/src/components/themed/WalletListSortableRow.tsx b/src/components/themed/WalletListSortableRow.tsx index e301c87a553..38e68f7c0c5 100644 --- a/src/components/themed/WalletListSortableRow.tsx +++ b/src/components/themed/WalletListSortableRow.tsx @@ -16,7 +16,6 @@ import { } from '../../selectors/DenominationSelectors' import { calculateFiatBalance } from '../../selectors/WalletSelectors' import { useDispatch, useSelector } from '../../types/reactRedux' -import { getWalletTokenId } from '../../util/CurrencyInfoHelpers' import { getWalletName } from '../../util/CurrencyWalletHelpers' import { DECIMAL_PRECISION, @@ -67,9 +66,8 @@ function WalletListSortableRowComponent(props: Props) { const multiplier = displayDenomination.multiplier const name = getWalletName(wallet) const symbol = displayDenomination.symbol - const tokenId = getWalletTokenId(wallet, currencyCode) - const balance = wallet.balanceMap.get(tokenId) ?? '0' + const balance = wallet.balanceMap.get(null) ?? '0' const preliminaryCryptoAmount = truncateDecimals( div(balance, multiplier, DECIMAL_PRECISION) ) @@ -81,6 +79,7 @@ function WalletListSortableRowComponent(props: Props) { : '' const fiatBalance = calculateFiatBalance( wallet, + null, defaultIsoFiat, exchangeDenomination, exchangeRates diff --git a/src/components/themed/WalletListSwipeable.tsx b/src/components/themed/WalletListSwipeable.tsx index 9dea04c6cc3..c8afb1c4edf 100644 --- a/src/components/themed/WalletListSwipeable.tsx +++ b/src/components/themed/WalletListSwipeable.tsx @@ -109,14 +109,12 @@ const WalletListSwipeableComponent: React.FC = props => { // Make a list of recent wallets: const recentWallets: WalletListItem[] = [] - for (const { id, currencyCode } of mostRecentWallets) { + for (const { id, tokenId } of mostRecentWallets) { const item = list.find( item => item.type === 'asset' && item.wallet.id === id && - ( - item.token?.currencyCode ?? item.wallet.currencyInfo.currencyCode - ).toLowerCase() === currencyCode.toLowerCase() + item.tokenId === tokenId ) if (item != null) recentWallets.push(item) } diff --git a/src/components/tiles/AddressTile2.tsx b/src/components/tiles/AddressTile2.tsx index 6c274bc746f..a2bed4b8d6b 100644 --- a/src/components/tiles/AddressTile2.tsx +++ b/src/components/tiles/AddressTile2.tsx @@ -1,6 +1,10 @@ import Clipboard from '@react-native-clipboard/clipboard' import { asMaybe, asObject, asString } from 'cleaners' -import type { EdgeCurrencyWallet, EdgeParsedUri } from 'edge-core-js' +import type { + EdgeCurrencyWallet, + EdgeParsedUri, + EdgeTokenId +} from 'edge-core-js' import { ethers } from 'ethers' import * as React from 'react' import AntDesign from 'react-native-vector-icons/AntDesign' @@ -16,7 +20,7 @@ import { lstrings } from '../../locales/strings' import { PaymentProtoError } from '../../types/PaymentProtoError' import { useSelector } from '../../types/reactRedux' import type { NavigationBase } from '../../types/routerTypes' -import { getTokenId, getTokenIdForced } from '../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { parseDeepLink } from '../../util/DeepLinkParser' import { checkPubAddress } from '../../util/FioAddressUtils' import { resolveName } from '../../util/resolveName' @@ -51,7 +55,7 @@ export interface AddressTileRef { interface Props { coreWallet: EdgeCurrencyWallet - currencyCode: string + tokenId: EdgeTokenId title: string recipientAddress: string onChangeAddress: (changeAddressResult: ChangeAddressResult) => Promise @@ -66,7 +70,7 @@ export const AddressTile2 = React.forwardRef( (props: Props, ref: React.ForwardedRef) => { const { coreWallet, - currencyCode, // Token currency code + tokenId, fioToAddress, isCameraOpen, lockInputs, @@ -122,7 +126,7 @@ export const AddressTile2 = React.forwardRef( const account = useSelector(state => state.core.account) const fioPlugin = account.currencyConfig.fio - const tokenId = getTokenId(coreWallet.currencyConfig, currencyCode) + const currencyCode = getCurrencyCode(coreWallet, tokenId) const { currencyWallets } = account const canSelfTransfer: boolean = Object.keys(currencyWallets).some( @@ -366,7 +370,7 @@ export const AddressTile2 = React.forwardRef( allowedAssets={[ { pluginId, - tokenId: getTokenIdForced(account, pluginId, currencyCode) + tokenId } ]} excludeWalletIds={[coreWallet.id]} diff --git a/src/constants/WalletAndCurrencyConstants.ts b/src/constants/WalletAndCurrencyConstants.ts index 24a2712a60c..9c5d37badf2 100644 --- a/src/constants/WalletAndCurrencyConstants.ts +++ b/src/constants/WalletAndCurrencyConstants.ts @@ -113,9 +113,6 @@ export const WALLET_TYPE_ORDER = [ 'wallet:bobevm' ] -// Put these in reverse order of preference -export const PREFERRED_TOKENS = ['WINGS', 'HERC', 'REPV2', 'RIF'] - export interface ImportKeyOption { optionName: string displayName: string diff --git a/src/controllers/edgeProvider/EdgeProviderServer.tsx b/src/controllers/edgeProvider/EdgeProviderServer.tsx index c0d74db30db..2f73a9265cb 100644 --- a/src/controllers/edgeProvider/EdgeProviderServer.tsx +++ b/src/controllers/edgeProvider/EdgeProviderServer.tsx @@ -30,16 +30,14 @@ import { showToast } from '../../components/services/AirshipInstance' import { lstrings } from '../../locales/strings' +import { getExchangeDenom } from '../../selectors/DenominationSelectors' import type { GuiPlugin } from '../../types/GuiPluginTypes' import type { Dispatch } from '../../types/reduxTypes' import type { NavigationBase } from '../../types/routerTypes' import type { EdgeAsset, MapObject } from '../../types/types' import { getCurrencyIconUris } from '../../util/CdnUris' import { CryptoAmount } from '../../util/CryptoAmount' -import { - getCurrencyCode, - getCurrencyCodeMultiplier -} from '../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { getWalletName } from '../../util/CurrencyWalletHelpers' import { makeCurrencyCodeTable } from '../../util/tokenIdTools' import { logEvent } from '../../util/tracking' @@ -66,7 +64,7 @@ export class EdgeProviderServer implements EdgeProviderMethods { _navigation: NavigationBase _plugin: GuiPlugin _reloadWebView: () => void - _selectedTokenId: EdgeTokenId + _selectedTokenId: EdgeTokenId | undefined _selectedWallet: EdgeCurrencyWallet | undefined // Public properties: @@ -80,7 +78,6 @@ export class EdgeProviderServer implements EdgeProviderMethods { navigation: NavigationBase plugin: GuiPlugin reloadWebView: () => void - selectedTokenId: string | null selectedWallet?: EdgeCurrencyWallet }) { const { @@ -91,7 +88,6 @@ export class EdgeProviderServer implements EdgeProviderMethods { navigation, plugin, reloadWebView, - selectedTokenId, selectedWallet } = opts @@ -101,7 +97,6 @@ export class EdgeProviderServer implements EdgeProviderMethods { this._navigation = navigation this._plugin = plugin this._reloadWebView = reloadWebView - this._selectedTokenId = selectedTokenId this._selectedWallet = selectedWallet this.deepLink = deepLink } @@ -154,13 +149,14 @@ export class EdgeProviderServer implements EdgeProviderMethods { const { walletId, tokenId } = result this._selectedWallet = account.currencyWallets[walletId] - const currencyCode = getCurrencyCode(this._selectedWallet, tokenId) if (this._selectedWallet == null) throw new Error(`Missing wallet for walletId`) + this._selectedTokenId = tokenId + + const currencyCode = getCurrencyCode(this._selectedWallet, tokenId) const chainCode = this._selectedWallet.currencyInfo.currencyCode const tokenCode = currencyCode const { pluginId } = this._selectedWallet.currencyInfo - this._selectedTokenId = tokenId const unfixCode = unfixCurrencyCode( this._plugin.fixCurrencyCodes, @@ -215,7 +211,8 @@ export class EdgeProviderServer implements EdgeProviderMethods { async getCurrentWalletInfo(): Promise { const tokenId = this._selectedTokenId const wallet = this._selectedWallet - if (wallet == null) throw new Error('No selected wallet') + if (wallet == null || tokenId === undefined) + throw new Error('No selected wallet') const { currencyConfig, currencyInfo } = wallet const { currencyCode } = @@ -306,7 +303,8 @@ export class EdgeProviderServer implements EdgeProviderMethods { async getWalletHistory() { const tokenId = this._selectedTokenId const wallet = this._selectedWallet - if (wallet == null) throw new Error('No selected wallet') + if (wallet == null || tokenId === undefined) + throw new Error('No selected wallet') // Prompt user with yes/no modal for permission const confirmTxShare = await Airship.show<'ok' | 'cancel' | undefined>( @@ -357,11 +355,8 @@ export class EdgeProviderServer implements EdgeProviderMethods { const tokenId = this._selectedTokenId const wallet = this._selectedWallet - if (wallet == null) throw new Error('No selected wallet') - - const { currencyConfig, currencyInfo } = wallet - const { currencyCode } = - tokenId == null ? currencyInfo : currencyConfig.allTokens[tokenId] + if (wallet == null || tokenId === undefined) + throw new Error('No selected wallet') // PUBLIC ADDRESS URI const spendTargets: EdgeSpendTarget[] = [] @@ -369,10 +364,7 @@ export class EdgeProviderServer implements EdgeProviderMethods { let { exchangeAmount, nativeAmount, publicAddress, otherParams } = target if (exchangeAmount != null) { - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - currencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, tokenId) nativeAmount = mul(exchangeAmount, multiplier) } spendTargets.push({ @@ -410,7 +402,8 @@ export class EdgeProviderServer implements EdgeProviderMethods { const tokenId = this._selectedTokenId const wallet = this._selectedWallet - if (wallet == null) throw new Error('No selected wallet') + if (wallet == null || tokenId === undefined) + throw new Error('No selected wallet') const { currencyConfig, currencyInfo } = wallet const { currencyCode: selectedCurrencyCode } = @@ -502,9 +495,9 @@ export class EdgeProviderServer implements EdgeProviderMethods { } // Do not expose the entire wallet to the plugin: resolve(cleanTx(transaction)) - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( wallet.currencyConfig, - transaction.currencyCode + transaction.tokenId ) const exchangeAmount = div( transaction.nativeAmount, @@ -517,7 +510,7 @@ export class EdgeProviderServer implements EdgeProviderMethods { conversionType: 'crypto', cryptoAmount: new CryptoAmount({ currencyConfig: wallet.currencyConfig, - currencyCode: transaction.currencyCode, + tokenId: transaction.tokenId, exchangeAmount: abs(exchangeAmount) }), swapProviderId: this._plugin.storeId, diff --git a/src/hooks/useSelectedWallet.ts b/src/hooks/useSelectedWallet.ts deleted file mode 100644 index 5fd6925bf87..00000000000 --- a/src/hooks/useSelectedWallet.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { EdgeCurrencyWallet, EdgeTokenId } from 'edge-core-js' - -import { useWatch } from '../hooks/useWatch' -import { useSelector } from '../types/reactRedux' -import { getTokenId } from '../util/CurrencyInfoHelpers' - -export interface SelectedWallet { - currencyCode: string - tokenId: EdgeTokenId - wallet: EdgeCurrencyWallet -} - -export function useSelectedWallet(): SelectedWallet | undefined { - const walletId = useSelector(state => state.ui.wallets.selectedWalletId) - const currencyCode = useSelector( - state => state.ui.wallets.selectedCurrencyCode - ) - - // Grab the wallet from the account: - const account = useSelector(state => state.core.account) - const currencyWallets = useWatch(account, 'currencyWallets') - const wallet = currencyWallets[walletId] - if (wallet == null) return - - // We cannot use any hooks after the return statement, - // but we don't need to worry about `allTokens` being stale, - // because the selected token must exist before being selected, - // so the selector above will force us to render in any case: - const tokenId = getTokenId(wallet.currencyConfig, currencyCode) - if (tokenId === undefined) return - - return { - currencyCode, - tokenId, - wallet - } -} diff --git a/src/locales/en_US.ts b/src/locales/en_US.ts index a1509a7c8ba..98466e12609 100644 --- a/src/locales/en_US.ts +++ b/src/locales/en_US.ts @@ -147,8 +147,6 @@ const strings = { 'Great, if you ever have any questions, please reach out to our support team at %1$s.', warning_scam_message_yes_1s: `Please proceed with caution! Assistance with account creation has the potential for fraud. Users should never share passwords or private keys. Social media and chat platforms have been involved in attacks. Do not send cryptocurrency to strangers. If you believe you're being taken advantage of, please contact our support team at %1$s.`, - warning_token_code_override_2s: - 'The entered contract address differs from the contract address of built-in token %1$s. Please proceed with caution and verify the contract is legitimate as use of this token can result in loss of funds. If you have questions about this feature or contract please contact %2$s.', warning_token_exists_1s: 'The entered token already exists as a built-in token %1$s', warning_battery_saver: `Battery Saver Detected! Balances may not update. For the best experience, please turn off battery saver mode.`, diff --git a/src/locales/strings/enUS.json b/src/locales/strings/enUS.json index 3b34439c1ef..0c477d435e7 100644 --- a/src/locales/strings/enUS.json +++ b/src/locales/strings/enUS.json @@ -82,7 +82,6 @@ "warning_scam_message": "Has anyone helped you set up this account?", "warning_scam_message_no_1s": "Great, if you ever have any questions, please reach out to our support team at %1$s.", "warning_scam_message_yes_1s": "Please proceed with caution! Assistance with account creation has the potential for fraud. Users should never share passwords or private keys. Social media and chat platforms have been involved in attacks. Do not send cryptocurrency to strangers. If you believe you're being taken advantage of, please contact our support team at %1$s.", - "warning_token_code_override_2s": "The entered contract address differs from the contract address of built-in token %1$s. Please proceed with caution and verify the contract is legitimate as use of this token can result in loss of funds. If you have questions about this feature or contract please contact %2$s.", "warning_token_exists_1s": "The entered token already exists as a built-in token %1$s", "warning_battery_saver": "Battery Saver Detected! Balances may not update. For the best experience, please turn off battery saver mode.", "warning_sending_pix_to_email_title": "Sending PIX payment to email address", diff --git a/src/plugins/borrow-plugins/common/ApprovableCall.ts b/src/plugins/borrow-plugins/common/ApprovableCall.ts index fa9ce652196..a2dc0af1fa0 100644 --- a/src/plugins/borrow-plugins/common/ApprovableCall.ts +++ b/src/plugins/borrow-plugins/common/ApprovableCall.ts @@ -9,7 +9,6 @@ import type { import { ethers } from 'ethers' import type { PendingTxMap } from '../../../controllers/action-queue/types' -import { getWalletTokenId } from '../../../util/CurrencyInfoHelpers' import type { ApprovableAction } from '../types' import { asBigNumber } from './cleaners/asBigNumber' import { SIDE_EFFECT_CURRENCY_CODE } from './constants' @@ -48,9 +47,10 @@ export const makeApprovableCall = async ( pendingTxMap: Readonly ): Promise => { const pendingTxs = pendingTxMap[walletId] - const currencyCode = - spendToken?.currencyCode ?? wallet.currencyInfo.currencyCode - const tokenId = getWalletTokenId(wallet, currencyCode) + const tokenId = + spendToken == null + ? null + : await wallet.currencyConfig.getTokenId(spendToken) const edgeSpendInfo: EdgeSpendInfo = { tokenId, skipChecks: dryrun, diff --git a/src/plugins/gui/amountQuotePlugin.ts b/src/plugins/gui/amountQuotePlugin.ts index ab5bdd61603..435a15a2b74 100644 --- a/src/plugins/gui/amountQuotePlugin.ts +++ b/src/plugins/gui/amountQuotePlugin.ts @@ -5,12 +5,10 @@ import { sprintf } from 'sprintf-js' import { formatNumber, isValidInput } from '../../locales/intl' import { lstrings } from '../../locales/strings' +import { getExchangeDenom } from '../../selectors/DenominationSelectors' import type { EdgeAsset } from '../../types/types' import { getPartnerIconUri } from '../../util/CdnUris' -import { - getCurrencyCode, - getCurrencyCodeMultiplier -} from '../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../util/CurrencyInfoHelpers' import { getHistoricalFiatRate } from '../../util/exchangeRates' import { infoServerData } from '../../util/network' import { @@ -492,9 +490,9 @@ export const amountQuoteFiatPlugin: FiatPluginFactory = async ( tokenId, spendTargets: [{ publicAddress }] }) - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( coreWallet.currencyConfig, - currencyCode + tokenId ) const exchangeAmount = div(maxAmount, multiplier, multiplier.length) diff --git a/src/plugins/gui/providers/banxaProvider.ts b/src/plugins/gui/providers/banxaProvider.ts index 9cb3a380708..01874b30b63 100644 --- a/src/plugins/gui/providers/banxaProvider.ts +++ b/src/plugins/gui/providers/banxaProvider.ts @@ -14,10 +14,10 @@ import URL from 'url-parse' import type { SendScene2Params } from '../../../components/scenes/SendScene2' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { FiatProviderLink } from '../../../types/DeepLinkTypes' import type { StringMap } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { fetchInfo } from '../../../util/network' import { consify, removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed, SendErrorNoTransaction } from '../fiatPlugin' @@ -539,7 +539,6 @@ export const banxaProvider: FiatProviderFactory = { amountType, paymentTypes, fiatCurrencyCode, - displayCurrencyCode, direction, tokenId } = params @@ -795,7 +794,7 @@ export const banxaProvider: FiatProviderFactory = { sourceFiatAmount: priceQuote.fiat_amount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: order.data.order.coin_amount }), fiatProviderId: providerId, @@ -887,12 +886,13 @@ export const banxaProvider: FiatProviderFactory = { status, wallet_address: publicAddress } = order.data.order + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId + ) const nativeAmount = mul( coinAmount.toString(), - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + multiplier ) if (status === 'waitingPayment') { // Launch the SendScene to make payment @@ -930,7 +930,7 @@ export const banxaProvider: FiatProviderFactory = { destFiatAmount: priceQuote.fiat_amount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: coinAmount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/bityProvider.ts b/src/plugins/gui/providers/bityProvider.ts index 07013e9e051..ed47b1c3eb2 100644 --- a/src/plugins/gui/providers/bityProvider.ts +++ b/src/plugins/gui/providers/bityProvider.ts @@ -17,9 +17,9 @@ import type { import { sprintf } from 'sprintf-js' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { HomeAddress, SepaInfo } from '../../../types/FormTypes' import type { StringMap } from '../../../types/types' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { utf8 } from '../../../util/encoding' import { removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed } from '../fiatPlugin' @@ -850,10 +850,8 @@ const completeSellOrder = async ( const { amount: inputAmount, currency: inputCurrencyCode } = input const { amount: fiatAmount } = output - const nativeAmount = mul( - inputAmount, - getCurrencyCodeMultiplier(coreWallet.currencyConfig, inputCurrencyCode) - ) + const { multiplier } = getExchangeDenom(coreWallet.currencyConfig, tokenId) + const nativeAmount = mul(inputAmount, multiplier) if (nativeAmount == null) { // Should not happen - input currencies should be valid before diff --git a/src/plugins/gui/providers/ioniaProvider.ts b/src/plugins/gui/providers/ioniaProvider.ts index 7e6313fb7ed..aa9a63c1905 100644 --- a/src/plugins/gui/providers/ioniaProvider.ts +++ b/src/plugins/gui/providers/ioniaProvider.ts @@ -21,9 +21,9 @@ import { sprintf } from 'sprintf-js' import URLParse from 'url-parse' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import { wasBase64 } from '../../../util/cleaners/asBase64' import { cleanFetch, fetcherWithOptions } from '../../../util/cleanFetch' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { logActivity } from '../../../util/logger' import type { FiatProvider, @@ -490,9 +490,9 @@ export const makeIoniaProvider: FiatProviderFactory = { quoteParams.displayCurrencyCode, RATE_QUOTE_CARD_AMOUNT ) - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( quoteParams.wallet.currencyConfig, - quoteParams.displayCurrencyCode + quoteParams.tokenId ) const rateExchangeAmount = div( rateAmount, diff --git a/src/plugins/gui/providers/kadoProvider.ts b/src/plugins/gui/providers/kadoProvider.ts index 0b97162813f..538c477fc8c 100644 --- a/src/plugins/gui/providers/kadoProvider.ts +++ b/src/plugins/gui/providers/kadoProvider.ts @@ -21,8 +21,8 @@ import type { SendScene2Params } from '../../../components/scenes/SendScene2' import { showError } from '../../../components/services/AirshipInstance' import { ENV } from '../../../env' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { datelog, isHex } from '../../../util/utils' import { SendErrorBackPressed, SendErrorNoTransaction } from '../fiatPlugin' import type { @@ -909,14 +909,12 @@ export const kadoProvider: FiatProviderFactory = { console.log(` blockchain: ${blockchain}`) console.log(` pluginId: ${pluginId}`) console.log(` tokenId: ${tokenId}`) + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId + ) const nativeAmount = round( - mul( - paymentExchangeAmount, - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) - ), + mul(paymentExchangeAmount, multiplier), 0 ) @@ -979,7 +977,7 @@ export const kadoProvider: FiatProviderFactory = { destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: paymentExchangeAmount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/moonpayProvider.ts b/src/plugins/gui/providers/moonpayProvider.ts index 762ba561663..70c064cb801 100644 --- a/src/plugins/gui/providers/moonpayProvider.ts +++ b/src/plugins/gui/providers/moonpayProvider.ts @@ -22,9 +22,9 @@ import URL from 'url-parse' import type { SendScene2Params } from '../../../components/scenes/SendScene2' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { StringMap } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed, SendErrorNoTransaction } from '../fiatPlugin' import type { @@ -660,7 +660,7 @@ export const moonpayProvider: FiatProviderFactory = { sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId: params.tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: providerId, @@ -748,13 +748,11 @@ export const moonpayProvider: FiatProviderFactory = { throw new Error('Moonpay missing parameters') } - const nativeAmount = mul( - baseCurrencyAmount, - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + params.tokenId ) + const nativeAmount = mul(baseCurrencyAmount, multiplier) const assetAction: EdgeAssetAction = { assetActionType: 'sell' @@ -818,7 +816,7 @@ export const moonpayProvider: FiatProviderFactory = { destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId: params.tokenId, exchangeAmount: baseCurrencyAmount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/mtpelerinProvider.ts b/src/plugins/gui/providers/mtpelerinProvider.ts index c96dd157641..907f5276630 100644 --- a/src/plugins/gui/providers/mtpelerinProvider.ts +++ b/src/plugins/gui/providers/mtpelerinProvider.ts @@ -17,8 +17,8 @@ import { toUtf8Bytes } from 'ethers/lib/utils' import type { SendScene2Params } from '../../../components/scenes/SendScene2' import { showError } from '../../../components/services/AirshipInstance' import { ENV } from '../../../env' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { hexToDecimal, removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed } from '../fiatPlugin' import type { @@ -624,9 +624,9 @@ export const mtpelerinProvider: FiatProviderFactory = { const orderId = 'mtpelerin_no_orderid' const orderUri = 'https://mtpelerin.com' - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( coreWallet.currencyConfig, - params.displayCurrencyCode + tokenId ) const exchangeAmount = div( nativeAmount, @@ -709,7 +709,7 @@ export const mtpelerinProvider: FiatProviderFactory = { destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId: params.tokenId, exchangeAmount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/paybisProvider.ts b/src/plugins/gui/providers/paybisProvider.ts index c09d6d5fe71..e7981680d37 100644 --- a/src/plugins/gui/providers/paybisProvider.ts +++ b/src/plugins/gui/providers/paybisProvider.ts @@ -22,10 +22,10 @@ import URL from 'url-parse' import type { SendScene2Params } from '../../../components/scenes/SendScene2' import { locale } from '../../../locales/intl' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { EdgeAsset, StringMap } from '../../../types/types' import { sha512HashAndSign } from '../../../util/crypto' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed, SendErrorNoTransaction } from '../fiatPlugin' import type { @@ -841,7 +841,7 @@ export const paybisProvider: FiatProviderFactory = { sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: providerId, @@ -946,13 +946,11 @@ export const paybisProvider: FiatProviderFactory = { console.log(` network: ${network}`) console.log(` pluginId: ${pluginId}`) console.log(` tokenId: ${tokenId}`) - const nativeAmount = mul( - amount, - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId ) + const nativeAmount = mul(amount, multiplier) const assetAction: EdgeAssetAction = { assetActionType: 'sell' @@ -1023,7 +1021,7 @@ export const paybisProvider: FiatProviderFactory = { destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: amount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/revolutProvider.ts b/src/plugins/gui/providers/revolutProvider.ts index 17884669843..64946534c95 100644 --- a/src/plugins/gui/providers/revolutProvider.ts +++ b/src/plugins/gui/providers/revolutProvider.ts @@ -178,7 +178,7 @@ export const revolutProvider: FiatProviderFactory = { sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: params.displayCurrencyCode, + tokenId: params.tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: providerId, diff --git a/src/plugins/gui/providers/simplexProvider.ts b/src/plugins/gui/providers/simplexProvider.ts index 2b2b59a9150..8e6d3224b95 100644 --- a/src/plugins/gui/providers/simplexProvider.ts +++ b/src/plugins/gui/providers/simplexProvider.ts @@ -471,7 +471,7 @@ export const simplexProvider: FiatProviderFactory = { sourceFiatAmount: quoteFiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId: params.tokenId, exchangeAmount: quoteCryptAmount }), fiatProviderId: providerId, diff --git a/src/plugins/ramps/banxa/banxaRampPlugin.ts b/src/plugins/ramps/banxa/banxaRampPlugin.ts index 82217eeacd4..16b48e309c7 100644 --- a/src/plugins/ramps/banxa/banxaRampPlugin.ts +++ b/src/plugins/ramps/banxa/banxaRampPlugin.ts @@ -20,12 +20,10 @@ import { import { requestPermissionOnSettings } from '../../../components/services/PermissionsManager' import { EDGE_CONTENT_SERVER_URI } from '../../../constants/CdnConstants' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { StringMap } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { - getCurrencyCodeMultiplier, - getTokenId -} from '../../../util/CurrencyInfoHelpers' +import { getTokenId } from '../../../util/CurrencyInfoHelpers' import { fetchInfo } from '../../../util/network' import { makeUuid } from '../../../util/rnUtils' import { removeIsoPrefix } from '../../../util/utils' @@ -1308,7 +1306,7 @@ export const banxaRampPlugin: RampPluginFactory = ( sourceFiatAmount: quoteFiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: order.data.order.coin_amount }), fiatProviderId: pluginId, @@ -1406,12 +1404,13 @@ export const banxaRampPlugin: RampPluginFactory = ( status, wallet_address: publicAddress } = order.data.order + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId + ) const nativeAmount = mul( coinAmount.toString(), - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + multiplier ) if (status === 'waitingPayment') { // Launch the SendScene to make payment @@ -1470,7 +1469,7 @@ export const banxaRampPlugin: RampPluginFactory = ( destFiatAmount: quoteFiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: coinAmount }), fiatProviderId: pluginId, diff --git a/src/plugins/ramps/infinite/infiniteRampPlugin.ts b/src/plugins/ramps/infinite/infiniteRampPlugin.ts index 54442d7f954..94225e44591 100644 --- a/src/plugins/ramps/infinite/infiniteRampPlugin.ts +++ b/src/plugins/ramps/infinite/infiniteRampPlugin.ts @@ -727,7 +727,7 @@ export const infiniteRampPlugin: RampPluginFactory = ( sourceFiatAmount: freshQuote.source.amount.toString(), destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: request.displayCurrencyCode, + tokenId: request.tokenId, exchangeAmount: freshQuote.target.amount.toString() }), fiatProviderId: pluginId, @@ -742,7 +742,7 @@ export const infiniteRampPlugin: RampPluginFactory = ( destFiatAmount: freshQuote.target.amount.toString(), sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: request.displayCurrencyCode, + tokenId: request.tokenId, exchangeAmount: freshQuote.source.amount.toString() }), fiatProviderId: pluginId, diff --git a/src/plugins/ramps/moonpay/moonpayRampPlugin.ts b/src/plugins/ramps/moonpay/moonpayRampPlugin.ts index bf72dc8f165..885c6fa0257 100644 --- a/src/plugins/ramps/moonpay/moonpayRampPlugin.ts +++ b/src/plugins/ramps/moonpay/moonpayRampPlugin.ts @@ -18,12 +18,10 @@ import { } from '../../../components/services/AirshipInstance' import { EDGE_CONTENT_SERVER_URI } from '../../../constants/CdnConstants' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { StringMap } from '../../../types/types' import { CryptoAmount } from '../../../util/CryptoAmount' -import { - findTokenIdByNetworkLocation, - getCurrencyCodeMultiplier -} from '../../../util/CurrencyInfoHelpers' +import { findTokenIdByNetworkLocation } from '../../../util/CurrencyInfoHelpers' import { removeIsoPrefix } from '../../../util/utils' import { SendErrorBackPressed, @@ -856,7 +854,7 @@ export const moonpayRampPlugin: RampPluginFactory = ( sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: pluginId, @@ -949,12 +947,13 @@ export const moonpayRampPlugin: RampPluginFactory = ( throw new Error('Moonpay missing parameters') } + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId + ) const nativeAmount = mul( baseCurrencyAmount, - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + multiplier ) const assetAction: EdgeAssetAction = { @@ -1031,7 +1030,7 @@ export const moonpayRampPlugin: RampPluginFactory = ( destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: baseCurrencyAmount }), fiatProviderId: pluginId, diff --git a/src/plugins/ramps/paybis/paybisRampPlugin.ts b/src/plugins/ramps/paybis/paybisRampPlugin.ts index 9f8f81e383a..562d3d007ff 100644 --- a/src/plugins/ramps/paybis/paybisRampPlugin.ts +++ b/src/plugins/ramps/paybis/paybisRampPlugin.ts @@ -34,10 +34,10 @@ import { requestPermissionOnSettings } from '../../../components/services/Permis import { EDGE_CONTENT_SERVER_URI } from '../../../constants/CdnConstants' import { locale } from '../../../locales/intl' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { EdgeAsset, StringMap } from '../../../types/types' import { sha512HashAndSign } from '../../../util/crypto' import { CryptoAmount } from '../../../util/CryptoAmount' -import { getCurrencyCodeMultiplier } from '../../../util/CurrencyInfoHelpers' import { getHistoricalCryptoRate, getHistoricalFiatRate @@ -1155,7 +1155,7 @@ export const paybisRampPlugin: RampPluginFactory = ( sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: pluginId, @@ -1267,13 +1267,11 @@ export const paybisRampPlugin: RampPluginFactory = ( console.log(` network: ${network}`) console.log(` pluginId: ${pluginId}`) console.log(` tokenId: ${tokenId}`) - const nativeAmount = mul( - amount, - getCurrencyCodeMultiplier( - coreWallet.currencyConfig, - displayCurrencyCode - ) + const { multiplier } = getExchangeDenom( + coreWallet.currencyConfig, + tokenId ) + const nativeAmount = mul(amount, multiplier) const assetAction: EdgeAssetAction = { assetActionType: 'sell' @@ -1367,7 +1365,7 @@ export const paybisRampPlugin: RampPluginFactory = ( destFiatAmount: fiatAmount, sourceAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: amount }), fiatProviderId: pluginId, diff --git a/src/plugins/ramps/revolut/revolutRampPlugin.ts b/src/plugins/ramps/revolut/revolutRampPlugin.ts index 27bbdcd11a9..175a5ad5454 100644 --- a/src/plugins/ramps/revolut/revolutRampPlugin.ts +++ b/src/plugins/ramps/revolut/revolutRampPlugin.ts @@ -415,7 +415,7 @@ export const revolutRampPlugin: RampPluginFactory = ( sourceFiatAmount: fiatAmount, destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: displayCurrencyCode, + tokenId, exchangeAmount: cryptoAmount }), fiatProviderId: pluginId, diff --git a/src/plugins/ramps/simplex/simplexRampPlugin.ts b/src/plugins/ramps/simplex/simplexRampPlugin.ts index b9136c60458..0638fe3d737 100644 --- a/src/plugins/ramps/simplex/simplexRampPlugin.ts +++ b/src/plugins/ramps/simplex/simplexRampPlugin.ts @@ -700,7 +700,7 @@ export const simplexRampPlugin: RampPluginFactory = ( goodQuote.fiat_money.amount.toString(), destAmount: new CryptoAmount({ currencyConfig: coreWallet.currencyConfig, - currencyCode: coreWallet.currencyInfo.currencyCode, + tokenId: request.tokenId, exchangeAmount: goodQuote.digital_money.amount.toString() }), diff --git a/src/plugins/stake-plugins/currency/tronStakePlugin.ts b/src/plugins/stake-plugins/currency/tronStakePlugin.ts index 856b2aca9b3..aa0e0e303b2 100644 --- a/src/plugins/stake-plugins/currency/tronStakePlugin.ts +++ b/src/plugins/stake-plugins/currency/tronStakePlugin.ts @@ -3,7 +3,6 @@ import { asDate, asMaybe, asObject, asString } from 'cleaners' import type { EdgeSpendInfo, EdgeTransaction } from 'edge-core-js' import { lstrings } from '../../../locales/strings' -import { getWalletTokenId } from '../../../util/CurrencyInfoHelpers' import { type ChangeQuote, type ChangeQuoteRequest, @@ -49,6 +48,7 @@ const policies: StakePolicy[] = [ { pluginId: 'tron', currencyCode: 'TRX', + tokenId: null, internalCurrencyCode: 'BANDWIDTH_V2', displayName: lstrings.stake_resource_bandwidth, cdnName: 'bandwidth' @@ -57,7 +57,8 @@ const policies: StakePolicy[] = [ stakeAssets: [ { pluginId: 'tron', - currencyCode: 'TRX' + currencyCode: 'TRX', + tokenId: null } ] }, @@ -72,6 +73,7 @@ const policies: StakePolicy[] = [ { pluginId: 'tron', currencyCode: 'TRX', + tokenId: null, internalCurrencyCode: 'ENERGY_V2', displayName: lstrings.stake_resource_energy, cdnName: 'energy' @@ -80,7 +82,8 @@ const policies: StakePolicy[] = [ stakeAssets: [ { pluginId: 'tron', - currencyCode: 'TRX' + currencyCode: 'TRX', + tokenId: null } ] }, @@ -94,6 +97,7 @@ const policies: StakePolicy[] = [ { pluginId: 'tron', currencyCode: 'TRX', + tokenId: null, internalCurrencyCode: 'BANDWIDTH', displayName: lstrings.stake_resource_bandwidth, cdnName: 'bandwidth' @@ -102,7 +106,8 @@ const policies: StakePolicy[] = [ stakeAssets: [ { pluginId: 'tron', - currencyCode: 'TRX' + currencyCode: 'TRX', + tokenId: null } ] }, @@ -116,6 +121,7 @@ const policies: StakePolicy[] = [ { pluginId: 'tron', currencyCode: 'TRX', + tokenId: null, internalCurrencyCode: 'ENERGY', displayName: lstrings.stake_resource_energy, cdnName: 'energy' @@ -124,7 +130,8 @@ const policies: StakePolicy[] = [ stakeAssets: [ { pluginId: 'tron', - currencyCode: 'TRX' + currencyCode: 'TRX', + tokenId: null } ] } @@ -238,6 +245,7 @@ export const makeTronStakePlugin = async ( allocations.push({ pluginId, currencyCode, + tokenId: null, allocationType: 'claim', nativeAmount: claimableAmount }) @@ -298,12 +306,14 @@ export const makeTronStakePlugin = async ( { allocationType: action, pluginId, + tokenId: null, currencyCode, nativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode, nativeAmount: edgeTransaction.networkFee } @@ -333,8 +343,7 @@ export const makeTronStakePlugin = async ( const rewardAsset = policy.rewardAssets[0].internalCurrencyCode ?? policy.rewardAssets[0].currencyCode - const tokenId = getWalletTokenId(wallet, currencyCode) - const balanceTrx = wallet.balanceMap.get(tokenId) ?? '0' + const balanceTrx = wallet.balanceMap.get(null) ?? '0' const canStake = gt(balanceTrx, '0') let canClaim = false const allocations: PositionAllocation[] = [] @@ -361,6 +370,7 @@ export const makeTronStakePlugin = async ( } allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType, nativeAmount, @@ -371,6 +381,7 @@ export const makeTronStakePlugin = async ( if (allocations.length === 0) { allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType: 'staked', nativeAmount: '0' @@ -434,12 +445,14 @@ const fetchChangeQuoteV1 = async ( { allocationType: isStake ? 'stake' : 'unstake', pluginId, + tokenId: null, currencyCode, nativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode, nativeAmount: edgeTransaction.networkFee } @@ -468,8 +481,7 @@ const fetchStakePositionV1 = async ( amount => amount.otherParams?.type === rewardAsset ) const nativeAmount = stakedAmount?.nativeAmount ?? '0' - const tokenId = getWalletTokenId(wallet, currencyCode) - const balanceTrx = wallet.balanceMap.get(tokenId) ?? '0' + const balanceTrx = wallet.balanceMap.get(null) ?? '0' const locktime = stakedAmount?.unlockDate != null ? new Date(stakedAmount.unlockDate) @@ -479,6 +491,7 @@ const fetchStakePositionV1 = async ( allocations: [ { pluginId, + tokenId: null, currencyCode, allocationType: 'staked', nativeAmount, diff --git a/src/plugins/stake-plugins/generic/pluginInfo/cardanoKilnPool.ts b/src/plugins/stake-plugins/generic/pluginInfo/cardanoKilnPool.ts index a8f11cbb908..acf39c49299 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/cardanoKilnPool.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/cardanoKilnPool.ts @@ -25,8 +25,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool1', @@ -48,8 +48,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool2', @@ -71,8 +71,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool3', @@ -94,8 +94,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool4', @@ -117,8 +117,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool6', @@ -140,8 +140,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool7', @@ -163,8 +163,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] }, { stakePolicyId: 'cardano_kiln_pool8', @@ -186,8 +186,8 @@ const kilnPolicyConfig: Array< }, hideUnstakeAndClaimAction: true, isLiquidStaking: true, - stakeAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }], - rewardAssets: [{ pluginId: 'cardano', currencyCode: 'ADA' }] + stakeAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }], + rewardAssets: [{ pluginId: 'cardano', tokenId: null, currencyCode: 'ADA' }] } ] diff --git a/src/plugins/stake-plugins/generic/pluginInfo/coreumNativeStaking.ts b/src/plugins/stake-plugins/generic/pluginInfo/coreumNativeStaking.ts index 828a39eb8ee..2dc11159235 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/coreumNativeStaking.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/coreumNativeStaking.ts @@ -39,8 +39,12 @@ const coreumPolicyConfig: Array< parentCurrencyCode: 'COREUM', hideUnstakeAction: true, adapterConfig, - stakeAssets: [{ pluginId: 'coreum', currencyCode: 'COREUM' }], - rewardAssets: [{ pluginId: 'coreum', currencyCode: 'COREUM' }] + stakeAssets: [ + { pluginId: 'coreum', tokenId: null, currencyCode: 'COREUM' } + ], + rewardAssets: [ + { pluginId: 'coreum', tokenId: null, currencyCode: 'COREUM' } + ] } }) diff --git a/src/plugins/stake-plugins/generic/pluginInfo/ethereumKilnPool.ts b/src/plugins/stake-plugins/generic/pluginInfo/ethereumKilnPool.ts index 1d458bfeec5..9e3bd675d16 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/ethereumKilnPool.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/ethereumKilnPool.ts @@ -28,8 +28,8 @@ const kilnPolicyConfig: Array< }, mustMaxUnstake: true, // TODO: This can be removed once engines have LP token balances hideUnstakeAndClaimAction: true, - stakeAssets: [{ pluginId: 'holesky', currencyCode: 'ETH' }], - rewardAssets: [{ pluginId: 'holesky', currencyCode: 'ETH' }] + stakeAssets: [{ pluginId: 'holesky', tokenId: null, currencyCode: 'ETH' }], + rewardAssets: [{ pluginId: 'holesky', tokenId: null, currencyCode: 'ETH' }] }, { stakePolicyId: 'ethereum_kiln', @@ -54,8 +54,8 @@ const kilnPolicyConfig: Array< }, mustMaxUnstake: true, // TODO: This can be removed once engines have LP token balances hideUnstakeAndClaimAction: true, - stakeAssets: [{ pluginId: 'ethereum', currencyCode: 'ETH' }], - rewardAssets: [{ pluginId: 'ethereum', currencyCode: 'ETH' }] + stakeAssets: [{ pluginId: 'ethereum', tokenId: null, currencyCode: 'ETH' }], + rewardAssets: [{ pluginId: 'ethereum', tokenId: null, currencyCode: 'ETH' }] } ] diff --git a/src/plugins/stake-plugins/generic/pluginInfo/filecoinCalibrationGlifpool.ts b/src/plugins/stake-plugins/generic/pluginInfo/filecoinCalibrationGlifpool.ts index b85382a0d4c..c322a30181d 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/filecoinCalibrationGlifpool.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/filecoinCalibrationGlifpool.ts @@ -26,10 +26,18 @@ const filecoinCalibrationPolicyConfig: Array< hideClaimAction: true, hideUnstakeAndClaimAction: true, stakeAssets: [ - { pluginId: 'filecoinfevmcalibration', currencyCode: 'tFIL' } + { + pluginId: 'filecoinfevmcalibration', + tokenId: null, + currencyCode: 'tFIL' + } ], rewardAssets: [ - { pluginId: 'filecoinfevmcalibration', currencyCode: 'tFIL' } + { + pluginId: 'filecoinfevmcalibration', + tokenId: null, + currencyCode: 'tFIL' + } ] } ] diff --git a/src/plugins/stake-plugins/generic/pluginInfo/filecoinGlifpool.ts b/src/plugins/stake-plugins/generic/pluginInfo/filecoinGlifpool.ts index dec78a27bf9..1af7994d511 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/filecoinGlifpool.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/filecoinGlifpool.ts @@ -25,8 +25,12 @@ const filecoinPolicyConfig: Array< disableMaxStake: true, hideClaimAction: true, hideUnstakeAndClaimAction: true, - stakeAssets: [{ pluginId: 'filecoinfevm', currencyCode: 'FIL' }], - rewardAssets: [{ pluginId: 'filecoinfevm', currencyCode: 'FIL' }] + stakeAssets: [ + { pluginId: 'filecoinfevm', tokenId: null, currencyCode: 'FIL' } + ], + rewardAssets: [ + { pluginId: 'filecoinfevm', tokenId: null, currencyCode: 'FIL' } + ] } ] diff --git a/src/plugins/stake-plugins/generic/pluginInfo/optimismTarotPool.ts b/src/plugins/stake-plugins/generic/pluginInfo/optimismTarotPool.ts index 399a8439d9c..da7a231ba0d 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/optimismTarotPool.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/optimismTarotPool.ts @@ -180,12 +180,28 @@ const makePolicyConfig = (adapterConfig: TarotPoolAdapterConfig) => { mustMaxUnstake: true, adapterConfig, stakeAssets: [ - { pluginId: 'optimism', currencyCode: adapterConfig.token0.symbol }, - { pluginId: 'optimism', currencyCode: adapterConfig.token1.symbol } + { + pluginId: 'optimism', + tokenId: adapterConfig.token0.tokenId, + currencyCode: adapterConfig.token0.symbol + }, + { + pluginId: 'optimism', + tokenId: adapterConfig.token1.tokenId, + currencyCode: adapterConfig.token1.symbol + } ], rewardAssets: [ - { pluginId: 'optimism', currencyCode: adapterConfig.token0.symbol }, - { pluginId: 'optimism', currencyCode: adapterConfig.token1.symbol } + { + pluginId: 'optimism', + tokenId: adapterConfig.token0.tokenId, + currencyCode: adapterConfig.token0.symbol + }, + { + pluginId: 'optimism', + tokenId: adapterConfig.token1.tokenId, + currencyCode: adapterConfig.token1.symbol + } ] } } diff --git a/src/plugins/stake-plugins/generic/pluginInfo/thorchainYield.ts b/src/plugins/stake-plugins/generic/pluginInfo/thorchainYield.ts index 43862d6cf8c..006e7aba3c8 100644 --- a/src/plugins/stake-plugins/generic/pluginInfo/thorchainYield.ts +++ b/src/plugins/stake-plugins/generic/pluginInfo/thorchainYield.ts @@ -26,8 +26,12 @@ const thorchainYieldPolicyConfig: Array< hideClaimAction: true, hideUnstakeAndClaimAction: true, - stakeAssets: [{ pluginId: 'thorchainrune', currencyCode: 'TCY' }], - rewardAssets: [{ pluginId: 'thorchainrune', currencyCode: 'RUNE' }] + stakeAssets: [ + { pluginId: 'thorchainrune', tokenId: 'tcy', currencyCode: 'TCY' } + ], + rewardAssets: [ + { pluginId: 'thorchainrune', tokenId: null, currencyCode: 'RUNE' } + ] } ] diff --git a/src/plugins/stake-plugins/generic/policyAdapters/CardanoKilnAdaptor.ts b/src/plugins/stake-plugins/generic/policyAdapters/CardanoKilnAdaptor.ts index c4c0059fa52..5f67d164924 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/CardanoKilnAdaptor.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/CardanoKilnAdaptor.ts @@ -2,8 +2,8 @@ import { div, eq, gt, lt, sub } from 'biggystring' import type { EdgeCurrencyWallet, EdgeTransaction } from 'edge-core-js' import { lstrings } from '../../../../locales/strings' +import { getExchangeDenom } from '../../../../selectors/DenominationSelectors' import { HumanFriendlyError } from '../../../../types/HumanFriendlyError' -import { getCurrencyCodeMultiplier } from '../../../../util/CurrencyInfoHelpers' import { infoServerData } from '../../../../util/network' import { snooze } from '../../../../util/utils' import type { @@ -77,12 +77,14 @@ export const makeCardanoKilnAdapter = ( { allocationType: 'claim', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount }, { allocationType: 'networkFee', pluginId: wallet.currencyInfo.pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: edgeTx.networkFee } @@ -111,10 +113,7 @@ export const makeCardanoKilnAdapter = ( if (eq(walletBalance, '0')) { throw new Error('Insufficient funds') } - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - wallet.currencyInfo.currencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, null) if (lt(walletBalance, MIN_STAKE_LOVELACE_AMOUNT)) { const balanceDisplayAmount = div( walletBalance, @@ -172,12 +171,14 @@ export const makeCardanoKilnAdapter = ( { allocationType: 'stake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: sub(walletBalance, edgeTx.networkFee) }, { allocationType: 'networkFee', pluginId: wallet.currencyInfo.pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: edgeTx.networkFee } @@ -223,12 +224,14 @@ export const makeCardanoKilnAdapter = ( { allocationType: 'unstake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: sub(walletBalance, edgeTx.networkFee) }, { allocationType: 'networkFee', pluginId: wallet.currencyInfo.pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: edgeTx.networkFee } @@ -276,6 +279,7 @@ export const makeCardanoKilnAdapter = ( allocations.push({ allocationType: 'staked', pluginId, + tokenId: null, currencyCode, nativeAmount: stakedAmount }) @@ -284,6 +288,7 @@ export const makeCardanoKilnAdapter = ( allocations.push({ allocationType: 'earned', pluginId, + tokenId: null, currencyCode, nativeAmount: rewardsAmount }) diff --git a/src/plugins/stake-plugins/generic/policyAdapters/CoreumStakeKitAdaptor.ts b/src/plugins/stake-plugins/generic/policyAdapters/CoreumStakeKitAdaptor.ts index eeeca61666e..822a9228bdf 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/CoreumStakeKitAdaptor.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/CoreumStakeKitAdaptor.ts @@ -71,6 +71,7 @@ export const makeStakeKitAdapter = ( allocations.push({ allocationType: 'networkFee', pluginId: policyConfig.parentPluginId, + tokenId: null, currencyCode: policyConfig.parentCurrencyCode, nativeAmount: networkFee }) @@ -218,6 +219,7 @@ export const makeStakeKitAdapter = ( { allocationType: 'claim', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount } @@ -302,6 +304,7 @@ export const makeStakeKitAdapter = ( { allocationType: 'stake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -385,6 +388,7 @@ export const makeStakeKitAdapter = ( { allocationType: 'unstake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -454,6 +458,7 @@ export const makeStakeKitAdapter = ( case 'rewards': { allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType: 'earned', nativeAmount, @@ -465,6 +470,7 @@ export const makeStakeKitAdapter = ( canUnstakeAndClaim = true allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType: 'staked', nativeAmount, @@ -475,6 +481,7 @@ export const makeStakeKitAdapter = ( case 'unstaking': { allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType: 'unstaked', nativeAmount, @@ -503,6 +510,7 @@ export const makeStakeKitAdapter = ( if (allocations.length === 0) { allocations.push({ pluginId, + tokenId: null, currencyCode, allocationType: 'staked', nativeAmount: '0' diff --git a/src/plugins/stake-plugins/generic/policyAdapters/EthereumKilnAdaptor.ts b/src/plugins/stake-plugins/generic/policyAdapters/EthereumKilnAdaptor.ts index 4a20e1342fb..74d64d1b17f 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/EthereumKilnAdaptor.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/EthereumKilnAdaptor.ts @@ -75,6 +75,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'networkFee', pluginId: policyConfig.parentPluginId, + tokenId: null, currencyCode: policyConfig.parentCurrencyCode, nativeAmount: networkFee.toString() }) @@ -154,6 +155,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'claim', pluginId, + tokenId: null, currencyCode, nativeAmount: claimableTotal }) @@ -207,6 +209,7 @@ export const makeEthereumKilnAdapter = ( { allocationType: 'stake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -265,6 +268,7 @@ export const makeEthereumKilnAdapter = ( { allocationType: 'unstake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -307,6 +311,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'staked', pluginId, + tokenId: null, currencyCode, nativeAmount: nativeStakedAmount }) @@ -314,6 +319,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'earned', pluginId, + tokenId: null, currencyCode, nativeAmount: position?.rewards ?? '0' }) @@ -330,6 +336,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'unstaked', pluginId, + tokenId: null, currencyCode, nativeAmount: operation.size, locktime: operationDate @@ -341,6 +348,7 @@ export const makeEthereumKilnAdapter = ( allocations.push({ allocationType: 'unstaked', pluginId, + tokenId: null, currencyCode, nativeAmount: claimableTotal }) diff --git a/src/plugins/stake-plugins/generic/policyAdapters/GlifInfinityPoolAdapter.ts b/src/plugins/stake-plugins/generic/policyAdapters/GlifInfinityPoolAdapter.ts index 2cda2c0d50a..7e9e7c1d2f7 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/GlifInfinityPoolAdapter.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/GlifInfinityPoolAdapter.ts @@ -91,6 +91,7 @@ export const makeGlifInfinityPoolAdapter = ( allocations.push({ allocationType: 'networkFee', pluginId: policyConfig.parentPluginId, + tokenId: null, currencyCode: policyConfig.parentCurrencyCode, nativeAmount: networkFee.toString() }) @@ -186,6 +187,7 @@ export const makeGlifInfinityPoolAdapter = ( { allocationType: 'stake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -281,6 +283,7 @@ export const makeGlifInfinityPoolAdapter = ( { allocationType: 'unstake', pluginId: requestAssetId.pluginId, + tokenId: requestAssetId.tokenId, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount } @@ -348,6 +351,7 @@ export const makeGlifInfinityPoolAdapter = ( const allocations: PositionAllocation[] = [ { pluginId: policyConfig.rewardAssets[0].pluginId, + tokenId: policyConfig.rewardAssets[0].tokenId, currencyCode: policyConfig.rewardAssets[0].currencyCode, allocationType: 'staked', nativeAmount: redemptionValue.toString(), diff --git a/src/plugins/stake-plugins/generic/policyAdapters/TarotPoolAdaptor.ts b/src/plugins/stake-plugins/generic/policyAdapters/TarotPoolAdaptor.ts index ec93ec353d8..cb36775cd9f 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/TarotPoolAdaptor.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/TarotPoolAdaptor.ts @@ -209,6 +209,7 @@ export const makeTarotPoolAdapter = ( allocations.push({ allocationType: 'networkFee', pluginId: policyConfig.parentPluginId, + tokenId: null, currencyCode: policyConfig.parentCurrencyCode, nativeAmount: networkFee.toString() }) @@ -565,12 +566,14 @@ export const makeTarotPoolAdapter = ( { allocationType: 'stake', pluginId: policyConfig.stakeAssets[0].pluginId, + tokenId: policyConfig.stakeAssets[0].tokenId, currencyCode: policyConfig.stakeAssets[0].currencyCode, nativeAmount: token0Amount.toString() }, { allocationType: 'stake', pluginId: policyConfig.stakeAssets[1].pluginId, + tokenId: policyConfig.stakeAssets[1].tokenId, currencyCode: policyConfig.stakeAssets[1].currencyCode, nativeAmount: token1Amount.toString() } @@ -662,12 +665,14 @@ export const makeTarotPoolAdapter = ( { allocationType: 'unstake', pluginId: policyConfig.stakeAssets[0].pluginId, + tokenId: policyConfig.stakeAssets[0].tokenId, currencyCode: policyConfig.stakeAssets[0].currencyCode, nativeAmount: bAmountAMin.div(leverage - 1).toString() }, { allocationType: 'unstake', pluginId: policyConfig.stakeAssets[1].pluginId, + tokenId: policyConfig.stakeAssets[1].tokenId, currencyCode: policyConfig.stakeAssets[1].currencyCode, nativeAmount: bAmountBMin.div(leverage - 1).toString() } @@ -713,6 +718,7 @@ export const makeTarotPoolAdapter = ( ): PositionAllocation { return { pluginId: token.pluginId, + tokenId: token.tokenId, currencyCode: token.currencyCode, allocationType: 'staked', nativeAmount, diff --git a/src/plugins/stake-plugins/generic/policyAdapters/ThorchainYieldAdaptor.ts b/src/plugins/stake-plugins/generic/policyAdapters/ThorchainYieldAdaptor.ts index 0643795bb8b..f75783c6939 100644 --- a/src/plugins/stake-plugins/generic/policyAdapters/ThorchainYieldAdaptor.ts +++ b/src/plugins/stake-plugins/generic/policyAdapters/ThorchainYieldAdaptor.ts @@ -147,12 +147,14 @@ export const makeThorchainYieldAdapter = ( { allocationType: 'stake', pluginId: requestAssetId.pluginId, + tokenId: null, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount }, { allocationType: 'networkFee', pluginId: 'thorchainrune', + tokenId: null, currencyCode: 'RUNE', nativeAmount: networkFee } @@ -226,12 +228,14 @@ export const makeThorchainYieldAdapter = ( { allocationType: 'unstake', pluginId: requestAssetId.pluginId, + tokenId: null, currencyCode: requestAssetId.currencyCode, nativeAmount: requestNativeAmount }, { allocationType: 'networkFee', pluginId: 'thorchainrune', + tokenId: null, currencyCode: 'RUNE', nativeAmount: networkFee } @@ -267,6 +271,7 @@ export const makeThorchainYieldAdapter = ( allocations: [ { pluginId: 'thorchainrune', + tokenId: 'tcy', currencyCode: 'TCY', allocationType: 'staked', nativeAmount: tcyStakedAmount diff --git a/src/plugins/stake-plugins/thorchainSavers/tcSaversPlugin.tsx b/src/plugins/stake-plugins/thorchainSavers/tcSaversPlugin.tsx index d46f76e7b91..a5f8eb2dc55 100644 --- a/src/plugins/stake-plugins/thorchainSavers/tcSaversPlugin.tsx +++ b/src/plugins/stake-plugins/thorchainSavers/tcSaversPlugin.tsx @@ -15,6 +15,7 @@ import { type EdgeCurrencyWallet, type EdgeMemo, type EdgeSpendInfo, + type EdgeTokenId, type EdgeTransaction, InsufficientFundsError } from 'edge-core-js' @@ -24,13 +25,9 @@ import { Linking } from 'react-native' import { ButtonsModal } from '../../../components/modals/ButtonsModal' import { Airship } from '../../../components/services/AirshipInstance' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { StringMap } from '../../../types/types' -import { asMaybeContractLocation } from '../../../util/cleaners' -import { - getCurrencyCodeMultiplier, - getTokenId, - getWalletTokenId -} from '../../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { getHistoricalCryptoRate } from '../../../util/exchangeRates' import { cleanMultiFetch, @@ -314,14 +311,16 @@ export const makeTcSaversPlugin = async ( if (gt(pool.savers_depth, '0')) { const edgeAsset = tcAssetToEdge(pool.asset) if (edgeAsset == null) return - const { pluginId, currencyCode } = edgeAsset + const { pluginId, currencyCode, tokenId } = edgeAsset const lowerCc = currencyCode.toLowerCase() policies.push({ ...policyDefault, stakePolicyId: `tcsavers/${pluginId}:${lowerCc}=${pluginId}:${lowerCc}`, - rewardAssets: [{ pluginId: 'thorchainrune', currencyCode: 'TCY' }], - stakeAssets: [{ pluginId, currencyCode }], + rewardAssets: [ + { pluginId: 'thorchainrune', tokenId: 'tcy', currencyCode: 'TCY' } + ], + stakeAssets: [{ pluginId, currencyCode, tokenId }], deprecated: true }) } @@ -389,14 +388,10 @@ const getStakePosition = async ( ): Promise => { const { stakePolicyId, wallet, account } = request const policy = getPolicyFromId(stakePolicyId) - const { currencyCode } = policy.stakeAssets[0] - const { primaryAddress } = await getPrimaryAddress( - account, - wallet, - currencyCode - ) + const { currencyCode, tokenId } = policy.stakeAssets[0] + const { primaryAddress } = await getPrimaryAddress(account, wallet, tokenId) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const [pool, saver] = await Promise.all([ fetchPool(opts, asset), fetchSaver(opts, asset, primaryAddress) @@ -419,6 +414,7 @@ const getStakePosition = async ( allocations: [ { pluginId: wallet.currencyInfo.pluginId, + tokenId, currencyCode, allocationType: 'staked', nativeAmount: '0' @@ -433,6 +429,7 @@ const getStakePosition = async ( const position = saverToPosition( wallet.currencyConfig, + tokenId, currencyCode, saver, pool @@ -441,6 +438,7 @@ const getStakePosition = async ( // TCY has to be the first earned position in order to render correctly in the StakeModifyScene since that scene only looks at the first one position.allocations.unshift({ pluginId: 'thorchainrune', + tokenId: 'tcy', currencyCode: 'TCY', allocationType: 'earned', nativeAmount: claimableTcy @@ -519,13 +517,14 @@ async function fetchSavers( function saverToPosition( currencyConfig: EdgeCurrencyConfig, + tokenId: EdgeTokenId, currencyCode: string, saver: Saver, pool: Pool ): StakePosition { const pluginId = currencyConfig.currencyInfo.pluginId - const multiplier = getCurrencyCodeMultiplier(currencyConfig, currencyCode) + const { multiplier } = getExchangeDenom(currencyConfig, tokenId) function thorToNative(amount: string): string { return toFixed( mul(div(amount, THOR_LIMIT_UNITS, DIVIDE_PRECISION), multiplier), @@ -551,12 +550,14 @@ function saverToPosition( allocations: [ { pluginId, + tokenId, currencyCode, allocationType: 'staked', nativeAmount: stakedAmount }, { pluginId, + tokenId, currencyCode, allocationType: 'earned', nativeAmount: earnedAmount @@ -619,14 +620,17 @@ const stakeRequest = async ( ): Promise => { const { ninerealmsClientId } = asInitOptions(opts.initOptions) - const { wallet, nativeAmount, currencyCode, stakePolicyId, account } = request - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - currencyCode - ) + const { + wallet, + nativeAmount, + currencyCode, + stakePolicyId, + account, + tokenId + } = request + const { multiplier } = getExchangeDenom(wallet.currencyConfig, tokenId) const { pluginId } = wallet.currencyInfo - const tokenId = getWalletTokenId(wallet, currencyCode) const isToken = tokenId != null const isEvm = EVM_PLUGINIDS[pluginId] @@ -651,9 +655,9 @@ const stakeRequest = async ( ) parentToTokenRate = parentRate / tokenRate } - const parentMultiplier = getCurrencyCodeMultiplier( + const { multiplier: parentMultiplier } = getExchangeDenom( wallet.currencyConfig, - parentCurrencyCode + null ) if (lt(walletBalance, nativeAmount)) { @@ -667,9 +671,9 @@ const stakeRequest = async ( await updateInboundAddresses(opts) const { primaryAddress, parentBalance, addressBalance } = - await getPrimaryAddress(account, wallet, currencyCode) + await getPrimaryAddress(account, wallet, tokenId) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const path = `/thorchain/quote/saver/deposit?asset=${asset}&address=${primaryAddress}&amount=${thorAmount}` const quoteDeposit = await cleanMultiFetch( @@ -938,18 +942,21 @@ const stakeRequest = async ( { allocationType: 'stake', pluginId, + tokenId, currencyCode, nativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: toFixed(fee, 0, 0) }, { allocationType: 'deductedFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(slippageNativeAmount, 0, 0) } @@ -969,6 +976,7 @@ const stakeRequest = async ( allocations.push({ allocationType: 'futureUnstakeFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(futureUnstakeFee, 0, 0) }) @@ -1041,13 +1049,19 @@ const stakeRequest = async ( const tcAssetToEdge = ( asset: string -): { pluginId: string; currencyCode: string } | undefined => { +): + | { pluginId: string; currencyCode: string; tokenId: EdgeTokenId } + | undefined => { const [chainCode, currency] = asset.split('.') - const [currencyCode] = currency.split('-') + const [currencyCode, contractAddress] = currency.split('-') const pluginId = tcChainCodePluginIdMap[chainCode] + const tokenId = + contractAddress == null + ? null + : contractAddress.toLowerCase().replace('0x', '') if (pluginId != null && currencyCode != null) - return { currencyCode, pluginId } + return { currencyCode, pluginId, tokenId } } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -1056,9 +1070,9 @@ const unstakeRequest = async ( request: ChangeQuoteRequest ): Promise => { const { allocations } = await getStakePosition(opts, request) - const { wallet, currencyCode, account } = request + const { wallet, account, tokenId } = request const { addressBalance, parentBalance, primaryAddress } = - await getPrimaryAddress(account, wallet, currencyCode) + await getPrimaryAddress(account, wallet, tokenId) return await unstakeRequestInner(opts, request, { addressBalance, allocations, @@ -1086,15 +1100,12 @@ const unstakeRequestInner = async ( wallet, nativeAmount: requestNativeAmount, currencyCode, + tokenId, account } = request - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - currencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, tokenId) const { pluginId } = wallet.currencyInfo - const tokenId = getTokenId(wallet.currencyConfig, currencyCode) ?? null const isToken = tokenId != null const isEvm = EVM_PLUGINIDS[pluginId] @@ -1162,7 +1173,7 @@ const unstakeRequestInner = async ( 0, 0 ) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const path = `/thorchain/quote/saver/withdraw?asset=${asset}&address=${primaryAddress}&amount=${totalUnstakeThorAmount}&withdraw_bps=${withdrawBps}` const quoteDeposit = await cleanMultiFetch( @@ -1194,7 +1205,7 @@ const unstakeRequestInner = async ( const { primaryAddress: utxoSourceAddress } = await getPrimaryAddress( account, wallet, - currencyCode + tokenId ) const forceChangeAddress = utxoSourceAddress @@ -1329,18 +1340,21 @@ const unstakeRequestInner = async ( { allocationType: 'unstake', pluginId, + tokenId, currencyCode, nativeAmount: totalUnstakeNativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: add(sendNativeAmount, toFixed(fee, 0, 0)) }, { allocationType: 'deductedFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(slippageNativeAmount, 0, 0) } @@ -1387,13 +1401,12 @@ const claimRequest = async ( opts: EdgeGuiPluginOptions, request: ChangeQuoteRequest ): Promise => { - const { wallet, account } = request + const { wallet, account, tokenId } = request const { currencyCode, pluginId } = wallet.currencyInfo const dustThreshold = CLAIMING_DUST_THRESHOLDS[currencyCode] if (dustThreshold == null) throw new Error('unknown dust threshold') const nativeAmount = add(dustThreshold, '1') // amount sent must exceed the dust threshold - const tokenId = getWalletTokenId(wallet, currencyCode) const isEvm = EVM_PLUGINIDS[pluginId] const walletBalance = wallet.balanceMap.get(tokenId) ?? '0' @@ -1407,10 +1420,10 @@ const claimRequest = async ( const { primaryAddress, addressBalance } = await getPrimaryAddress( account, wallet, - currencyCode + tokenId ) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const [chain] = asset.split('.') const poolAddress = inboundAddresses?.find(ia => ia.chain === chain)?.address if (poolAddress == null) { @@ -1606,12 +1619,14 @@ const claimRequest = async ( { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: add(toFixed(fee, 0, 0), nativeAmount) // we're adding the dust amount to the network fee since it cannot be unclaimed }, { allocationType: 'claim', pluginId: 'thorchainrune', + tokenId: 'tcy', currencyCode: 'TCY', nativeAmount: claimableTcy } @@ -1657,14 +1672,14 @@ const estimateUnstakeFee = async ( parentBalance: string ): Promise => { const { currencyCode, nativeAmount, wallet } = request - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( wallet.currencyConfig, - currencyCode + request.tokenId ) const parentCurrencyCode = wallet.currencyInfo.currencyCode - const parentMultiplier = getCurrencyCodeMultiplier( + const { multiplier: parentMultiplier } = getExchangeDenom( wallet.currencyConfig, - parentCurrencyCode + null ) const [pool, savers] = await Promise.all([ @@ -1685,6 +1700,7 @@ const estimateUnstakeFee = async ( primaryAddress = saver.asset_address stakePosition = saverToPosition( wallet.currencyConfig, + request.tokenId, currencyCode, saver, pool @@ -1831,13 +1847,12 @@ const updateInboundAddresses = async ( const getPrimaryAddress = async ( account: EdgeAccount, wallet: EdgeCurrencyWallet, - currencyCode: string + tokenId: EdgeTokenId ): Promise<{ primaryAddress: string addressBalance: string parentBalance: string }> => { - const tokenId = getWalletTokenId(wallet, currencyCode) const { publicAddress, nativeBalance } = await wallet.getReceiveAddress({ forceIndex: 0, tokenId @@ -1859,42 +1874,22 @@ const getPrimaryAddress = async ( const edgeToTcAsset = ( currencyConfig: EdgeCurrencyConfig, - currencyCode: string + tokenId: EdgeTokenId ): string => { const { pluginId } = currencyConfig.currencyInfo const mainnetCode = MAINNET_CODE_TRANSCRIPTION[pluginId] + const currencyCode = getCurrencyCode( + { + currencyConfig, + currencyInfo: currencyConfig.currencyInfo + } as unknown as EdgeCurrencyWallet, + tokenId + ) const asset = `${mainnetCode}.${currencyCode}` - if (currencyConfig.currencyInfo.currencyCode !== currencyCode) { - const { type } = policyCurrencyInfos[pluginId] - - if (type !== 'evm') { - throw new Error( - `Currency type ${type} does not support token savers and currencyCode ${currencyCode} mismatches wallet currency code ${currencyConfig.currencyInfo.currencyCode}` - ) - } - const tokenId = getTokenId(currencyConfig, currencyCode) - if (tokenId == null) { - throw new Error( - `getStakePositionInner: Cannot find tokenId for ${pluginId}:${currencyCode}` - ) - } - const edgeToken = currencyConfig.allTokens[tokenId] - if (edgeToken == null) { - throw new Error( - `getStakePositionInner: Cannot find edgeToken for ${pluginId}:${tokenId}` - ) - } - - const { contractAddress } = - asMaybeContractLocation(edgeToken.networkLocation) ?? {} - if (contractAddress == null) { - throw new Error( - `getStakePositionInner: No contractAddress for ${pluginId}:${tokenId}` - ) - } - - return `${asset}-${contractAddress.toLocaleUpperCase()}` + if (tokenId != null) { + const contractAddress = `0x${tokenId}`.toLocaleUpperCase() + return `${asset}-${contractAddress}` } return asset diff --git a/src/plugins/stake-plugins/thorchainSavers/tcSaversPluginSegwit.tsx b/src/plugins/stake-plugins/thorchainSavers/tcSaversPluginSegwit.tsx index a15b880c9b0..cc711e96081 100644 --- a/src/plugins/stake-plugins/thorchainSavers/tcSaversPluginSegwit.tsx +++ b/src/plugins/stake-plugins/thorchainSavers/tcSaversPluginSegwit.tsx @@ -15,6 +15,7 @@ import { type EdgeCurrencyWallet, type EdgeMemo, type EdgeSpendInfo, + type EdgeTokenId, type EdgeTransaction, InsufficientFundsError } from 'edge-core-js' @@ -24,13 +25,9 @@ import { Linking } from 'react-native' import { ButtonsModal } from '../../../components/modals/ButtonsModal' import { Airship } from '../../../components/services/AirshipInstance' import { lstrings } from '../../../locales/strings' +import { getExchangeDenom } from '../../../selectors/DenominationSelectors' import type { StringMap } from '../../../types/types' -import { asMaybeContractLocation } from '../../../util/cleaners' -import { - getCurrencyCodeMultiplier, - getTokenId, - getWalletTokenId -} from '../../../util/CurrencyInfoHelpers' +import { getCurrencyCode } from '../../../util/CurrencyInfoHelpers' import { getHistoricalCryptoRate } from '../../../util/exchangeRates' import { cleanMultiFetch, @@ -309,14 +306,16 @@ export const makeTcSaversPluginSegwit = async ( if (gt(pool.savers_depth, '0')) { const edgeAsset = tcAssetToEdge(pool.asset) if (edgeAsset == null) return - const { pluginId, currencyCode } = edgeAsset + const { pluginId, currencyCode, tokenId } = edgeAsset const lowerCc = currencyCode.toLowerCase() policies.push({ ...policyDefault, stakePolicyId: `tcsavers/${pluginId}:${lowerCc}=${pluginId}:${lowerCc}-bech32`, - rewardAssets: [{ pluginId: 'thorchainrune', currencyCode: 'TCY' }], - stakeAssets: [{ pluginId, currencyCode }], + rewardAssets: [ + { pluginId: 'thorchainrune', tokenId: 'tcy', currencyCode: 'TCY' } + ], + stakeAssets: [{ pluginId, tokenId, currencyCode }], deprecated: true }) } @@ -384,14 +383,10 @@ const getStakePosition = async ( ): Promise => { const { stakePolicyId, wallet, account } = request const policy = getPolicyFromId(stakePolicyId) - const { currencyCode } = policy.stakeAssets[0] - const { primaryAddress } = await getPrimaryAddress( - account, - wallet, - currencyCode - ) + const { currencyCode, tokenId } = policy.stakeAssets[0] + const { primaryAddress } = await getPrimaryAddress(account, wallet, tokenId) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const [pool, saver] = await Promise.all([ fetchPool(opts, asset), fetchSaver(opts, asset, primaryAddress) @@ -414,6 +409,7 @@ const getStakePosition = async ( allocations: [ { pluginId: wallet.currencyInfo.pluginId, + tokenId, currencyCode, allocationType: 'staked', nativeAmount: '0' @@ -428,6 +424,7 @@ const getStakePosition = async ( const position = saverToPosition( wallet.currencyConfig, + tokenId, currencyCode, saver, pool @@ -436,6 +433,7 @@ const getStakePosition = async ( // TCY has to be the first earned position in order to render correctly in the StakeModifyScene since that scene only looks at the first one position.allocations.unshift({ pluginId: 'thorchainrune', + tokenId: 'tcy', currencyCode: 'TCY', allocationType: 'earned', nativeAmount: claimableTcy @@ -514,13 +512,14 @@ async function fetchSavers( function saverToPosition( currencyConfig: EdgeCurrencyConfig, + tokenId: EdgeTokenId, currencyCode: string, saver: Saver, pool: Pool ): StakePosition { const pluginId = currencyConfig.currencyInfo.pluginId - const multiplier = getCurrencyCodeMultiplier(currencyConfig, currencyCode) + const { multiplier } = getExchangeDenom(currencyConfig, tokenId) function thorToNative(amount: string): string { return toFixed( mul(div(amount, THOR_LIMIT_UNITS, DIVIDE_PRECISION), multiplier), @@ -546,12 +545,14 @@ function saverToPosition( allocations: [ { pluginId, + tokenId, currencyCode, allocationType: 'staked', nativeAmount: stakedAmount }, { pluginId, + tokenId, currencyCode, allocationType: 'earned', nativeAmount: earnedAmount @@ -614,14 +615,17 @@ const stakeRequest = async ( ): Promise => { const { ninerealmsClientId } = asInitOptions(opts.initOptions) - const { wallet, nativeAmount, currencyCode, stakePolicyId, account } = request - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - currencyCode - ) + const { + wallet, + nativeAmount, + currencyCode, + stakePolicyId, + account, + tokenId + } = request + const { multiplier } = getExchangeDenom(wallet.currencyConfig, tokenId) const { pluginId } = wallet.currencyInfo - const tokenId = getWalletTokenId(wallet, currencyCode) const isToken = tokenId != null const isEvm = EVM_PLUGINIDS[pluginId] @@ -646,9 +650,9 @@ const stakeRequest = async ( ) parentToTokenRate = parentRate / tokenRate } - const parentMultiplier = getCurrencyCodeMultiplier( + const { multiplier: parentMultiplier } = getExchangeDenom( wallet.currencyConfig, - parentCurrencyCode + null ) if (lt(walletBalance, nativeAmount)) { @@ -662,9 +666,9 @@ const stakeRequest = async ( await updateInboundAddresses(opts) const { primaryAddress, parentBalance, addressBalance } = - await getPrimaryAddress(account, wallet, currencyCode) + await getPrimaryAddress(account, wallet, tokenId) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const path = `/thorchain/quote/saver/deposit?asset=${asset}&address=${primaryAddress}&amount=${thorAmount}` const quoteDeposit = await cleanMultiFetch( @@ -933,18 +937,21 @@ const stakeRequest = async ( { allocationType: 'stake', pluginId, + tokenId, currencyCode, nativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: toFixed(fee, 0, 0) }, { allocationType: 'deductedFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(slippageNativeAmount, 0, 0) } @@ -964,6 +971,7 @@ const stakeRequest = async ( allocations.push({ allocationType: 'futureUnstakeFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(futureUnstakeFee, 0, 0) }) @@ -1036,13 +1044,19 @@ const stakeRequest = async ( const tcAssetToEdge = ( asset: string -): { pluginId: string; currencyCode: string } | undefined => { +): + | { pluginId: string; currencyCode: string; tokenId: EdgeTokenId } + | undefined => { const [chainCode, currency] = asset.split('.') - const [currencyCode] = currency.split('-') + const [currencyCode, contractAddress] = currency.split('-') const pluginId = tcChainCodePluginIdMap[chainCode] + const tokenId = + contractAddress == null + ? null + : contractAddress.toLowerCase().replace('0x', '') if (pluginId != null && currencyCode != null) - return { currencyCode, pluginId } + return { currencyCode, pluginId, tokenId } } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -1051,9 +1065,9 @@ const unstakeRequest = async ( request: ChangeQuoteRequest ): Promise => { const { allocations } = await getStakePosition(opts, request) - const { wallet, currencyCode, account } = request + const { wallet, account, tokenId } = request const { addressBalance, parentBalance, primaryAddress } = - await getPrimaryAddress(account, wallet, currencyCode) + await getPrimaryAddress(account, wallet, tokenId) return await unstakeRequestInner(opts, request, { addressBalance, allocations, @@ -1081,15 +1095,12 @@ const unstakeRequestInner = async ( wallet, nativeAmount: requestNativeAmount, currencyCode, - account + account, + tokenId } = request - const multiplier = getCurrencyCodeMultiplier( - wallet.currencyConfig, - currencyCode - ) + const { multiplier } = getExchangeDenom(wallet.currencyConfig, tokenId) const { pluginId } = wallet.currencyInfo - const tokenId = getTokenId(wallet.currencyConfig, currencyCode) ?? null const isToken = tokenId != null const isEvm = EVM_PLUGINIDS[pluginId] @@ -1157,7 +1168,7 @@ const unstakeRequestInner = async ( 0, 0 ) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const path = `/thorchain/quote/saver/withdraw?asset=${asset}&address=${primaryAddress}&amount=${totalUnstakeThorAmount}&withdraw_bps=${withdrawBps}` const quoteDeposit = await cleanMultiFetch( @@ -1189,7 +1200,7 @@ const unstakeRequestInner = async ( const { primaryAddress: utxoSourceAddress } = await getPrimaryAddress( account, wallet, - currencyCode + tokenId ) const forceChangeAddress = utxoSourceAddress @@ -1325,17 +1336,20 @@ const unstakeRequestInner = async ( allocationType: 'unstake', pluginId, currencyCode, + tokenId, nativeAmount: totalUnstakeNativeAmount }, { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: add(sendNativeAmount, toFixed(fee, 0, 0)) }, { allocationType: 'deductedFee', pluginId, + tokenId, currencyCode, nativeAmount: toFixed(slippageNativeAmount, 0, 0) } @@ -1382,13 +1396,12 @@ const claimRequest = async ( opts: EdgeGuiPluginOptions, request: ChangeQuoteRequest ): Promise => { - const { wallet, account } = request + const { wallet, account, tokenId } = request const { currencyCode, pluginId } = wallet.currencyInfo const dustThreshold = CLAIMING_DUST_THRESHOLDS[currencyCode] if (dustThreshold == null) throw new Error('unknown dust threshold') const nativeAmount = add(dustThreshold, '1') // amount sent must exceed the dust threshold - const tokenId = getWalletTokenId(wallet, currencyCode) const isEvm = EVM_PLUGINIDS[pluginId] const walletBalance = wallet.balanceMap.get(tokenId) ?? '0' @@ -1402,10 +1415,10 @@ const claimRequest = async ( const { primaryAddress, addressBalance } = await getPrimaryAddress( account, wallet, - currencyCode + tokenId ) - const asset = edgeToTcAsset(wallet.currencyConfig, currencyCode) + const asset = edgeToTcAsset(wallet.currencyConfig, tokenId) const [chain] = asset.split('.') const poolAddress = inboundAddresses?.find(ia => ia.chain === chain)?.address if (poolAddress == null) { @@ -1601,12 +1614,14 @@ const claimRequest = async ( { allocationType: 'networkFee', pluginId, + tokenId: null, currencyCode: wallet.currencyInfo.currencyCode, nativeAmount: add(toFixed(fee, 0, 0), nativeAmount) // we're adding the dust amount to the network fee since it cannot be unclaimed }, { allocationType: 'claim', pluginId: 'thorchainrune', + tokenId: 'tcy', currencyCode: 'TCY', nativeAmount: claimableTcy } @@ -1652,14 +1667,14 @@ const estimateUnstakeFee = async ( parentBalance: string ): Promise => { const { currencyCode, nativeAmount, wallet } = request - const multiplier = getCurrencyCodeMultiplier( + const { multiplier } = getExchangeDenom( wallet.currencyConfig, - currencyCode + request.tokenId ) const parentCurrencyCode = wallet.currencyInfo.currencyCode - const parentMultiplier = getCurrencyCodeMultiplier( + const { multiplier: parentMultiplier } = getExchangeDenom( wallet.currencyConfig, - parentCurrencyCode + null ) const [pool, savers] = await Promise.all([ @@ -1680,6 +1695,7 @@ const estimateUnstakeFee = async ( primaryAddress = saver.asset_address stakePosition = saverToPosition( wallet.currencyConfig, + request.tokenId, currencyCode, saver, pool @@ -1826,13 +1842,12 @@ const updateInboundAddresses = async ( const getPrimaryAddress = async ( account: EdgeAccount, wallet: EdgeCurrencyWallet, - currencyCode: string + tokenId: EdgeTokenId ): Promise<{ primaryAddress: string addressBalance: string parentBalance: string }> => { - const tokenId = getWalletTokenId(wallet, currencyCode) const edgeAddresses = await wallet.getAddresses({ tokenId: null, forceIndex: 0 @@ -1862,42 +1877,22 @@ const getPrimaryAddress = async ( const edgeToTcAsset = ( currencyConfig: EdgeCurrencyConfig, - currencyCode: string + tokenId: EdgeTokenId ): string => { const { pluginId } = currencyConfig.currencyInfo const mainnetCode = MAINNET_CODE_TRANSCRIPTION[pluginId] + const currencyCode = getCurrencyCode( + { + currencyConfig, + currencyInfo: currencyConfig.currencyInfo + } as unknown as EdgeCurrencyWallet, + tokenId + ) const asset = `${mainnetCode}.${currencyCode}` - if (currencyConfig.currencyInfo.currencyCode !== currencyCode) { - const { type } = policyCurrencyInfos[pluginId] - - if (type !== 'evm') { - throw new Error( - `Currency type ${type} does not support token savers and currencyCode ${currencyCode} mismatches wallet currency code ${currencyConfig.currencyInfo.currencyCode}` - ) - } - const tokenId = getTokenId(currencyConfig, currencyCode) - if (tokenId == null) { - throw new Error( - `getStakePositionInner: Cannot find tokenId for ${pluginId}:${currencyCode}` - ) - } - const edgeToken = currencyConfig.allTokens[tokenId] - if (edgeToken == null) { - throw new Error( - `getStakePositionInner: Cannot find edgeToken for ${pluginId}:${tokenId}` - ) - } - - const { contractAddress } = - asMaybeContractLocation(edgeToken.networkLocation) ?? {} - if (contractAddress == null) { - throw new Error( - `getStakePositionInner: No contractAddress for ${pluginId}:${tokenId}` - ) - } - - return `${asset}-${contractAddress.toLocaleUpperCase()}` + if (tokenId != null) { + const contractAddress = `0x${tokenId}`.toLocaleUpperCase() + return `${asset}-${contractAddress}` } return asset diff --git a/src/plugins/stake-plugins/types.ts b/src/plugins/stake-plugins/types.ts index 44a15914bc1..c744f7ffb11 100644 --- a/src/plugins/stake-plugins/types.ts +++ b/src/plugins/stake-plugins/types.ts @@ -5,7 +5,8 @@ import type { EdgeAccount, EdgeCorePluginOptions, - EdgeCurrencyWallet + EdgeCurrencyWallet, + EdgeTokenId } from 'edge-core-js' // ----------------------------------------------------------------------------- @@ -57,6 +58,7 @@ export class StakePoolFullError extends Error { */ export interface StakeAssetInfo { pluginId: string + tokenId: EdgeTokenId currencyCode: string internalCurrencyCode?: string displayName?: string @@ -123,6 +125,7 @@ export interface StakePolicy { export interface ChangeQuoteRequest { action: 'stake' | 'unstake' | 'claim' | 'unstakeExact' stakePolicyId: string + tokenId: EdgeTokenId currencyCode: string nativeAmount: string wallet: EdgeCurrencyWallet @@ -138,6 +141,7 @@ export interface QuoteAllocation { | 'deductedFee' | 'futureUnstakeFee' pluginId: string + tokenId: EdgeTokenId currencyCode: string nativeAmount: string lockInputs?: boolean @@ -166,6 +170,7 @@ export interface StakePositionRequest { export interface PositionAllocation { // The of asset for this allocation pluginId: string + tokenId: EdgeTokenId currencyCode: string // The of the allocation allocationType: 'staked' | 'unstaked' | 'earned' @@ -197,6 +202,7 @@ export interface StakePolicyFilter { pluginId?: string wallet?: EdgeCurrencyWallet currencyCode?: string + tokenId?: EdgeTokenId } export const filterStakePolicies = ( @@ -206,7 +212,7 @@ export const filterStakePolicies = ( if (filter == null) return policies let out: StakePolicy[] = [...policies] - const { currencyCode, pluginId, wallet } = filter + const { currencyCode, pluginId, tokenId, wallet } = filter if (wallet != null) { out = out.filter(policy => @@ -229,6 +235,13 @@ export const filterStakePolicies = ( ) ) } + if (tokenId != null) { + out = out.filter(policy => + [...policy.rewardAssets, ...policy.stakeAssets].some( + asset => asset.tokenId === tokenId + ) + ) + } return out } diff --git a/src/plugins/stake-plugins/uniswapV2/policies/VelodromeV2StakePolicy.ts b/src/plugins/stake-plugins/uniswapV2/policies/VelodromeV2StakePolicy.ts index 4ba585afe85..cb4c4f1e75f 100644 --- a/src/plugins/stake-plugins/uniswapV2/policies/VelodromeV2StakePolicy.ts +++ b/src/plugins/stake-plugins/uniswapV2/policies/VelodromeV2StakePolicy.ts @@ -199,9 +199,10 @@ export const makeVelodromeV2StakePolicy = ( allocations.push( ...policyInfo.stakeAssets.map( - ({ pluginId, currencyCode }, index) => { + ({ pluginId, tokenId, currencyCode }) => { const tokenContractAddress = assetToContractAddress(policyInfo, { pluginId, + tokenId, currencyCode }) const tokenReserves = reservesMap[tokenContractAddress] @@ -212,6 +213,7 @@ export const makeVelodromeV2StakePolicy = ( return { allocationType: action, pluginId, + tokenId, currencyCode, nativeAmount } @@ -228,10 +230,11 @@ export const makeVelodromeV2StakePolicy = ( ).toString() allocations.push( ...policyInfo.rewardAssets.map( - ({ currencyCode, pluginId }) => { + ({ currencyCode, pluginId, tokenId }) => { return { allocationType: 'claim', pluginId, + tokenId, currencyCode, nativeAmount: rewardNativeAmount } @@ -829,6 +832,7 @@ export const makeVelodromeV2StakePolicy = ( allocations.push({ allocationType: 'networkFee', pluginId: policyInfo.parentPluginId, + tokenId: null, currencyCode: policyInfo.parentCurrencyCode, nativeAmount: networkFee }) @@ -940,6 +944,7 @@ export const makeVelodromeV2StakePolicy = ( return { pluginId: assetId.pluginId, + tokenId: assetId.tokenId, currencyCode: assetId.currencyCode, allocationType: 'staked', nativeAmount: add(stakedNativeAmount, nativeAmount), @@ -951,6 +956,7 @@ export const makeVelodromeV2StakePolicy = ( const earnedAllocations: PositionAllocation[] = [ { pluginId: policyInfo.rewardAssets[0].pluginId, + tokenId: policyInfo.rewardAssets[0].tokenId, currencyCode: policyInfo.rewardAssets[0].currencyCode, allocationType: 'earned', nativeAmount: rewardNativeAmount, diff --git a/src/plugins/stake-plugins/uniswapV2/policies/cemeteryPolicy.ts b/src/plugins/stake-plugins/uniswapV2/policies/cemeteryPolicy.ts index 197b99de3a7..c915cea30ac 100644 --- a/src/plugins/stake-plugins/uniswapV2/policies/cemeteryPolicy.ts +++ b/src/plugins/stake-plugins/uniswapV2/policies/cemeteryPolicy.ts @@ -198,10 +198,11 @@ export const makeCemeteryPolicy = ( allocations.push( ...policyInfo.stakeAssets.map( - ({ pluginId, currencyCode }, index) => { + ({ pluginId, currencyCode, tokenId }, index) => { const tokenContractAddress = assetToContractAddress(policyInfo, { pluginId, - currencyCode + currencyCode, + tokenId }) const tokenReserves = reservesMap[tokenContractAddress] const nativeAmount = div( @@ -211,6 +212,7 @@ export const makeCemeteryPolicy = ( return { allocationType: action, pluginId, + tokenId, currencyCode, nativeAmount } @@ -227,10 +229,11 @@ export const makeCemeteryPolicy = ( ).toString() allocations.push( ...policyInfo.rewardAssets.map( - ({ currencyCode, pluginId }) => { + ({ currencyCode, pluginId, tokenId }) => { return { allocationType: 'claim', pluginId, + tokenId, currencyCode, nativeAmount: rewardNativeAmount } @@ -791,6 +794,7 @@ export const makeCemeteryPolicy = ( allocations.push({ allocationType: 'networkFee', pluginId: policyInfo.parentPluginId, + tokenId: null, currencyCode: policyInfo.parentCurrencyCode, nativeAmount: networkFee }) @@ -892,6 +896,7 @@ export const makeCemeteryPolicy = ( return { pluginId: assetId.pluginId, + tokenId: assetId.tokenId, currencyCode: assetId.currencyCode, allocationType: 'staked', nativeAmount, @@ -903,6 +908,7 @@ export const makeCemeteryPolicy = ( const earnedAllocations: PositionAllocation[] = [ { pluginId: policyInfo.rewardAssets[0].pluginId, + tokenId: policyInfo.rewardAssets[0].tokenId, currencyCode: policyInfo.rewardAssets[0].currencyCode, allocationType: 'earned', nativeAmount: rewardNativeAmount, diff --git a/src/plugins/stake-plugins/uniswapV2/policies/masonryPolicy.ts b/src/plugins/stake-plugins/uniswapV2/policies/masonryPolicy.ts index e168c4d8f5d..9f8d988970a 100644 --- a/src/plugins/stake-plugins/uniswapV2/policies/masonryPolicy.ts +++ b/src/plugins/stake-plugins/uniswapV2/policies/masonryPolicy.ts @@ -170,7 +170,7 @@ export const makeMasonryPolicy = ( if (action === 'stake' || action === 'unstake') { allocations.push( ...policyInfo.stakeAssets.map( - ({ currencyCode, pluginId }) => { + ({ currencyCode, pluginId, tokenId }) => { if (currencyCode !== request.currencyCode) throw new Error( `Requested token '${request.currencyCode}' to ${action} not found in policy` @@ -179,6 +179,7 @@ export const makeMasonryPolicy = ( return { allocationType: action, pluginId, + tokenId, currencyCode, nativeAmount: request.nativeAmount } @@ -195,10 +196,11 @@ export const makeMasonryPolicy = ( ).toString() allocations.push( ...policyInfo.rewardAssets.map( - ({ currencyCode, pluginId }) => { + ({ currencyCode, pluginId, tokenId }) => { return { allocationType: 'claim', pluginId, + tokenId, currencyCode, nativeAmount: earnedAmount } @@ -416,6 +418,7 @@ export const makeMasonryPolicy = ( allocations.push({ allocationType: 'networkFee', pluginId: policyInfo.parentPluginId, + tokenId: null, currencyCode: policyInfo.parentCurrencyCode, nativeAmount: networkFee }) @@ -478,6 +481,7 @@ export const makeMasonryPolicy = ( const stakedAllocations: PositionAllocation[] = [ { pluginId: policyInfo.stakeAssets[0].pluginId, + tokenId: policyInfo.stakeAssets[0].tokenId, currencyCode: policyInfo.stakeAssets[0].currencyCode, allocationType: 'staked', nativeAmount: fromHex(stakedAmount._hex), @@ -489,6 +493,7 @@ export const makeMasonryPolicy = ( const earnedAllocations: PositionAllocation[] = [ { pluginId: policyInfo.rewardAssets[0].pluginId, + tokenId: policyInfo.rewardAssets[0].tokenId, currencyCode: policyInfo.rewardAssets[0].currencyCode, allocationType: 'earned', nativeAmount: fromHex(earnedAmount._hex), diff --git a/src/plugins/stake-plugins/uniswapV2/policyInfo/fantom.ts b/src/plugins/stake-plugins/uniswapV2/policyInfo/fantom.ts index bd90b93cc7a..0c5b39a0862 100644 --- a/src/plugins/stake-plugins/uniswapV2/policyInfo/fantom.ts +++ b/src/plugins/stake-plugins/uniswapV2/policyInfo/fantom.ts @@ -313,13 +313,15 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ stakeAssets: [ { pluginId: 'fantom', - currencyCode: 'TSHARE' + currencyCode: 'TSHARE', + tokenId: '4cdf39285d7ca8eb3f090fda0c069ba5f4145b37' } ], rewardAssets: [ { pluginId: 'fantom', - currencyCode: 'TOMB' + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' } ] }, @@ -338,10 +340,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('TOMB') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'TOMB' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_1', @@ -358,10 +374,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('USDC') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TOMB' }, - { pluginId: 'fantom', currencyCode: 'USDC' } + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + }, + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_2', @@ -378,10 +408,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('TOMB') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'ZOO' }, - { pluginId: 'fantom', currencyCode: 'TOMB' } + { + pluginId: 'fantom', + currencyCode: 'ZOO', + tokenId: '09e145a1d53c0045f41aeef25d8ff982ae74dd56' + }, + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_4', @@ -398,10 +442,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('TSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'BTC' }, - { pluginId: 'fantom', currencyCode: 'TSHARE' } + { + pluginId: 'fantom', + currencyCode: 'BTC', + tokenId: '321162cd933e2be498cd2267a90534a804051b11' + }, + { + pluginId: 'fantom', + currencyCode: 'TSHARE', + tokenId: '4cdf39285d7ca8eb3f090fda0c069ba5f4145b37' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_5', @@ -418,10 +476,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('ETH') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TSHARE' }, - { pluginId: 'fantom', currencyCode: 'ETH' } + { + pluginId: 'fantom', + currencyCode: 'TSHARE', + tokenId: '4cdf39285d7ca8eb3f090fda0c069ba5f4145b37' + }, + { + pluginId: 'fantom', + currencyCode: 'ETH', + tokenId: '74b23882a30290451a17c44f4f05243b6b58c76d' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_6', @@ -438,10 +510,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('TSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'TSHARE' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'TSHARE', + tokenId: '4cdf39285d7ca8eb3f090fda0c069ba5f4145b37' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_7', @@ -458,10 +544,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('FUSDT') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'FUSDT' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'FUSDT', + tokenId: '049d68029688eabf473097a2fc38ef61633a3c7a' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_8', @@ -478,10 +578,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('MIM') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'MIM' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'MIM', + tokenId: '82f0b8b456c1a451378467398982d4834b6829c1' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { @@ -499,10 +613,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('FTM') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'FTM' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_11', @@ -519,10 +647,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('DAI') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'DAI' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'DAI', + tokenId: '8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_12', @@ -539,10 +681,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('ETH') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'ETH' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'ETH', + tokenId: '74b23882a30290451a17c44f4f05243b6b58c76d' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_13', @@ -559,10 +715,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('FTM') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FUSDT' }, - { pluginId: 'fantom', currencyCode: 'FTM' } + { + pluginId: 'fantom', + currencyCode: 'FUSDT', + tokenId: '049d68029688eabf473097a2fc38ef61633a3c7a' + }, + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_14', @@ -579,10 +749,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('BTC') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'BTC' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'BTC', + tokenId: '321162cd933e2be498cd2267a90534a804051b11' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_15', @@ -599,10 +783,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('MIM') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'MIM' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'MIM', + tokenId: '82f0b8b456c1a451378467398982d4834b6829c1' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_16', @@ -619,10 +817,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('BNB') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'BNB' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'BNB', + tokenId: 'd67de0e0a0fd7b15dc8348bb9be742f3c5850454' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_17', @@ -639,10 +851,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('AVAX') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'AVAX' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'AVAX', + tokenId: '511d35c52a3c244e7b8bd92c0c297755fbd89212' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_18', @@ -659,10 +885,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LINK') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'LINK' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'LINK', + tokenId: 'b3654dc3d10ea7645f8319668e8f54d2574fbdc8' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_19', @@ -679,10 +919,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('FTM') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'CRV' }, - { pluginId: 'fantom', currencyCode: 'FTM' } + { + pluginId: 'fantom', + currencyCode: 'CRV', + tokenId: '1e4f97b9f9f913c46f1632781732927b9019c68b' + }, + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_20', @@ -699,10 +953,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('ETH') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'BTC' }, - { pluginId: 'fantom', currencyCode: 'ETH' } + { + pluginId: 'fantom', + currencyCode: 'BTC', + tokenId: '321162cd933e2be498cd2267a90534a804051b11' + }, + { + pluginId: 'fantom', + currencyCode: 'ETH', + tokenId: '74b23882a30290451a17c44f4f05243b6b58c76d' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_21', @@ -719,10 +987,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LIF3') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TOMB' }, - { pluginId: 'fantom', currencyCode: 'LIF3' } + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + }, + { + pluginId: 'fantom', + currencyCode: 'LIF3', + tokenId: 'bf60e7414ef09026733c1e7de72e393888c64da' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_22', @@ -739,10 +1021,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TSHARE' }, - { pluginId: 'fantom', currencyCode: 'LSHARE' } + { + pluginId: 'fantom', + currencyCode: 'TSHARE', + tokenId: '4cdf39285d7ca8eb3f090fda0c069ba5f4145b37' + }, + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_23', @@ -759,10 +1055,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LIF3') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'LIF3' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'LIF3', + tokenId: 'bf60e7414ef09026733c1e7de72e393888c64da' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_24', @@ -779,10 +1089,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'USDC' }, - { pluginId: 'fantom', currencyCode: 'LSHARE' } + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + }, + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_25', @@ -799,10 +1123,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LIF3') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'LIF3' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'LIF3', + tokenId: 'bf60e7414ef09026733c1e7de72e393888c64da' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_26', @@ -819,10 +1157,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('TOMB') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TBOND' }, - { pluginId: 'fantom', currencyCode: 'TOMB' } + { + pluginId: 'fantom', + currencyCode: 'TBOND', + tokenId: '24248cd1747348bdc971a5395f4b3cd7fee94ea0' + }, + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_27', @@ -839,10 +1191,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'FTM' }, - { pluginId: 'fantom', currencyCode: 'LSHARE' } + { + pluginId: 'fantom', + currencyCode: 'FTM', + tokenId: '21be370d5312f44cb42ce377bc9b8a0cef1a4c83' + }, + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_28', @@ -859,10 +1225,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'TOMB' }, - { pluginId: 'fantom', currencyCode: 'LSHARE' } + { + pluginId: 'fantom', + currencyCode: 'TOMB', + tokenId: '6c021ae822bea943b2e66552bde1d2696a53fbb7' + }, + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_29', @@ -879,10 +1259,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('LSHARE') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'LIF3' }, - { pluginId: 'fantom', currencyCode: 'LSHARE' } + { + pluginId: 'fantom', + currencyCode: 'LIF3', + tokenId: 'bf60e7414ef09026733c1e7de72e393888c64da' + }, + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_33', @@ -899,10 +1293,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('USDC') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'L3USD' }, - { pluginId: 'fantom', currencyCode: 'USDC' } + { + pluginId: 'fantom', + currencyCode: 'L3USD', + tokenId: '5f0456f728e2d59028b4f5b8ad8c604100724c6a' + }, + { + pluginId: 'fantom', + currencyCode: 'USDC', + tokenId: '04068da6c83afcfa0e13ba15a6696662335d5b75' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_34', @@ -919,10 +1327,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('FUSDT') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'L3USD' }, - { pluginId: 'fantom', currencyCode: 'FUSDT' } + { + pluginId: 'fantom', + currencyCode: 'L3USD', + tokenId: '5f0456f728e2d59028b4f5b8ad8c604100724c6a' + }, + { + pluginId: 'fantom', + currencyCode: 'FUSDT', + tokenId: '049d68029688eabf473097a2fc38ef61633a3c7a' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] }, { stakePolicyId: 'ftm_tombswap_cemetery_v2_35', @@ -939,10 +1361,24 @@ export const fantomPolicyInfo: StakePolicyInfo[] = [ tokenBContract: eco.makeContract('DAI') }), stakeAssets: [ - { pluginId: 'fantom', currencyCode: 'L3USD' }, - { pluginId: 'fantom', currencyCode: 'DAI' } + { + pluginId: 'fantom', + currencyCode: 'L3USD', + tokenId: '5f0456f728e2d59028b4f5b8ad8c604100724c6a' + }, + { + pluginId: 'fantom', + currencyCode: 'DAI', + tokenId: '8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e' + } ], - rewardAssets: [{ pluginId: 'fantom', currencyCode: 'LSHARE' }] + rewardAssets: [ + { + pluginId: 'fantom', + currencyCode: 'LSHARE', + tokenId: 'cbe0ca46399af916784cadf5bcc3aed2052d6c45' + } + ] } // TODO: After multi-hop swap support implemented OR if a direct swap route opens up for FTM->TREEB and FTM->FUSD, add those Cemetery V2 pools. ] diff --git a/src/plugins/stake-plugins/uniswapV2/policyInfo/optimism.ts b/src/plugins/stake-plugins/uniswapV2/policyInfo/optimism.ts index 836dd6474b0..95bf3d42909 100644 --- a/src/plugins/stake-plugins/uniswapV2/policyInfo/optimism.ts +++ b/src/plugins/stake-plugins/uniswapV2/policyInfo/optimism.ts @@ -12,7 +12,10 @@ import type { StakePolicyInfo } from '../stakePolicy' // Contract Info Map // ----------------------------------------------------------------------------- -export const optimismContractInfoMap = { +export const optimismContractInfoMap: Record< + string, + { abi: any; address: string } +> = { ROUTER_VELODROME_V2: { abi: VELODROME_V2_ROUTER, address: '0xa062aE8A9c5e11aaA026fc2670B0D65cCc8B2858' @@ -204,6 +207,13 @@ function generateVelodromeV2StakePolicyInfo( const isStablePool = poolType.startsWith('s') const lpTokenContract = eco.makeContract(poolContractKey) + const tokenIdA = optimismContractInfoMap[tokenA].address + .toLowerCase() + .replace('0x', '') + const tokenIdB = optimismContractInfoMap[tokenB].address + .toLowerCase() + .replace('0x', '') + return { stakePolicyId: `optimism_velodrome_${poolType}_${tokenA}_${tokenB}`, stakeProviderInfo: velodromeProviderInfo, @@ -222,9 +232,15 @@ function generateVelodromeV2StakePolicyInfo( tokenBContract: eco.makeContract(tokenB) }), stakeAssets: [ - { pluginId: 'optimism', currencyCode: tokenA }, - { pluginId: 'optimism', currencyCode: tokenB } + { pluginId: 'optimism', tokenId: tokenIdA, currencyCode: tokenA }, + { pluginId: 'optimism', tokenId: tokenIdB, currencyCode: tokenB } ], - rewardAssets: [{ pluginId: 'optimism', currencyCode: 'VELO' }] + rewardAssets: [ + { + pluginId: 'optimism', + tokenId: '9560e827af36c94d2ac33a39bce1fe78631088db', + currencyCode: 'VELO' + } + ] } } diff --git a/src/plugins/stake-plugins/uniswapV2/uniV2Plugin.ts b/src/plugins/stake-plugins/uniswapV2/uniV2Plugin.ts index 5bc8f1028e5..6d48aab60fd 100644 --- a/src/plugins/stake-plugins/uniswapV2/uniV2Plugin.ts +++ b/src/plugins/stake-plugins/uniswapV2/uniV2Plugin.ts @@ -25,7 +25,7 @@ export const makeUniV2StakePlugin = async ( const instance: StakePlugin = { getPolicies(filter?: StakePolicyFilter): StakePolicy[] { let out: StakePolicyInfo[] = [...pluginInfo.policyInfo] - const { currencyCode, pluginId } = filter ?? {} + const { currencyCode, pluginId, tokenId } = filter ?? {} if (pluginId != null) { out = out.filter(policy => @@ -54,6 +54,14 @@ export const makeUniV2StakePlugin = async ( }) } + if (tokenId != null) { + out = out.filter(policy => + [...policy.rewardAssets, ...policy.stakeAssets].some( + asset => asset.tokenId === tokenId + ) + ) + } + const policies = out.map(toStakePolicy(infoServerResponse)) return policies }, diff --git a/src/reducers/FioReducer.ts b/src/reducers/FioReducer.ts index 959ecf13c2f..b17c9251117 100644 --- a/src/reducers/FioReducer.ts +++ b/src/reducers/FioReducer.ts @@ -1,3 +1,4 @@ +import type { EdgeCurrencyWallet } from 'edge-core-js' import type { Reducer } from 'redux' import type { Action } from '../types/reduxActions' @@ -9,10 +10,12 @@ export type CcWalletMap = Record export interface FioState { connectedWalletsByFioAddress: Record + fioWallets: EdgeCurrencyWallet[] } const initialState: FioState = { - connectedWalletsByFioAddress: {} + connectedWalletsByFioAddress: {}, + fioWallets: [] } export const fio: Reducer = ( @@ -31,6 +34,13 @@ export const fio: Reducer = ( connectedWalletsByFioAddress } } + case 'UPDATE_FIO_WALLETS': { + const { fioWallets } = action.data + return { + ...state, + fioWallets + } + } default: return state } diff --git a/src/reducers/scenes/SettingsReducer.ts b/src/reducers/scenes/SettingsReducer.ts index 9bebd1b204d..3df018553ae 100644 --- a/src/reducers/scenes/SettingsReducer.ts +++ b/src/reducers/scenes/SettingsReducer.ts @@ -1,4 +1,4 @@ -import type { EdgeAccount } from 'edge-core-js' +import type { EdgeAccount, EdgeTokenId } from 'edge-core-js' import { asSyncedAccountSettings, @@ -39,7 +39,7 @@ export interface SettingsState export interface AccountInitPayload extends SettingsState { account: EdgeAccount - currencyCode: string + tokenId: EdgeTokenId pinLoginEnabled: boolean isTouchEnabled: boolean isTouchSupported: boolean diff --git a/src/reducers/scenes/WalletsReducer.ts b/src/reducers/scenes/WalletsReducer.ts deleted file mode 100644 index c30b65d61cf..00000000000 --- a/src/reducers/scenes/WalletsReducer.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type { EdgeCurrencyWallet } from 'edge-core-js' -import { combineReducers, type Reducer } from 'redux' - -import type { Action } from '../../types/reduxTypes' - -export interface WalletsState { - selectedWalletId: string - selectedCurrencyCode: string - fioWallets: EdgeCurrencyWallet[] -} - -const selectedWalletId = (state = '', action: Action): string => { - switch (action.type) { - case 'UI/WALLETS/SELECT_WALLET': { - return action.data.walletId - } - - case 'ACCOUNT_INIT_COMPLETE': { - if (action.data == null) throw new TypeError('Invalid action') - if (action.data.walletId === '') return state - return action.data.walletId - } - - default: - return state - } -} - -const selectedCurrencyCode = (state = '', action: Action): string => { - switch (action.type) { - case 'UI/WALLETS/SELECT_WALLET': { - return action.data.currencyCode - } - - case 'ACCOUNT_INIT_COMPLETE': { - if (action.data == null) throw new TypeError('Invalid action') - if (action.data.currencyCode === '') return state - return action.data.currencyCode - } - - default: - return state - } -} - -const fioWallets: Reducer = ( - state = [], - action -) => { - switch (action.type) { - case 'UPDATE_FIO_WALLETS': { - const { fioWallets } = action.data - return fioWallets - } - - default: - return state - } -} - -export const wallets = combineReducers({ - selectedWalletId, - selectedCurrencyCode, - fioWallets -}) diff --git a/src/reducers/uiReducer.ts b/src/reducers/uiReducer.ts index 1f62a1340a1..38d75555ac7 100644 --- a/src/reducers/uiReducer.ts +++ b/src/reducers/uiReducer.ts @@ -13,7 +13,6 @@ import { type FioAddressSceneState } from './scenes/FioAddressSceneReducer' import { settings, type SettingsState } from './scenes/SettingsReducer' -import { wallets, type WalletsState } from './scenes/WalletsReducer' export interface UiState { readonly exchangeInfo: ExchangeInfo @@ -23,7 +22,6 @@ export interface UiState { readonly settings: SettingsState readonly notificationHeight: number readonly subcategories: string[] - readonly wallets: WalletsState readonly countryCode: string } @@ -52,9 +50,7 @@ const uiInner = combineReducers({ default: return state } - }, - - wallets + } }) export const ui: Reducer = (state, action: Action) => { diff --git a/src/selectors/DenominationSelectors.ts b/src/selectors/DenominationSelectors.ts index 352a386faa6..53fa7dd6ab0 100644 --- a/src/selectors/DenominationSelectors.ts +++ b/src/selectors/DenominationSelectors.ts @@ -12,20 +12,6 @@ export const emptyEdgeDenomination: EdgeDenomination = Object.freeze({ symbol: '' }) -/** @deprecated Use `selectDisplayDenom` to look up by tokenId instead. */ -export const selectDisplayDenomByCurrencyCode = ( - state: RootState, - currencyConfig: EdgeCurrencyConfig, - currencyCode: string -): EdgeDenomination => { - const { pluginId } = currencyConfig.currencyInfo - const pluginSettings = state.ui.settings.denominationSettings[pluginId] - if (pluginSettings?.[currencyCode] != null) { - return pluginSettings[currencyCode] ?? emptyEdgeDenomination - } - return getExchangeDenomByCurrencyCode(currencyConfig, currencyCode) -} - export const selectDisplayDenom = ( state: RootState, currencyConfig: EdgeCurrencyConfig, @@ -48,29 +34,6 @@ export const selectDisplayDenom = ( return exchangeDenomination } -/** - * Finds the primary denomination for the given currencyCode. - * This would match "BTC" but not "sats". - * Pass either `account.currencyConfig[pluginId]` or `wallet.currencyConfig`, - * whichever you have. - * @deprecated Use `getExchangeDenom` to look up by tokenId instead. - */ -export const getExchangeDenomByCurrencyCode = ( - currencyConfig: EdgeCurrencyConfig, - currencyCode: string -): EdgeDenomination => { - const { allTokens, currencyInfo } = currencyConfig - - if (currencyInfo.currencyCode === currencyCode) - return currencyInfo.denominations[0] - for (const tokenId of Object.keys(allTokens)) { - const token = allTokens[tokenId] - if (token.currencyCode === currencyCode) return token.denominations[0] - } - - return emptyEdgeDenomination -} - /** * Looks up the denomination for a tokenId. * Pass either `account.currencyConfig[pluginId]` or `wallet.currencyConfig`, diff --git a/src/selectors/WalletSelectors.ts b/src/selectors/WalletSelectors.ts index 060d514ec99..bb74ba67d20 100644 --- a/src/selectors/WalletSelectors.ts +++ b/src/selectors/WalletSelectors.ts @@ -8,15 +8,8 @@ import type { import type { GuiExchangeRates } from '../actions/ExchangeRateActions' import type { RootState } from '../types/reduxTypes' -import { getWalletTokenId } from '../util/CurrencyInfoHelpers' import { convertNativeToExchange, zeroString } from '../util/utils' -export function getSelectedCurrencyWallet( - state: RootState -): EdgeCurrencyWallet { - return state.core.account.currencyWallets[state.ui.wallets.selectedWalletId] -} - export const getActiveWalletCurrencyInfos = ( currencyWallets: Record ): EdgeCurrencyInfo[] => { @@ -102,12 +95,11 @@ export const convertFiatCurrency = ( export const calculateFiatBalance = ( wallet: EdgeCurrencyWallet, + tokenId: EdgeTokenId, isoFiatCurrencyCode: string, exchangeDenomination: EdgeDenomination, exchangeRates: GuiExchangeRates ): string => { - const currencyCode = exchangeDenomination.name - const tokenId = getWalletTokenId(wallet, currencyCode) const nativeBalance = wallet.balanceMap.get(tokenId) ?? '0' if (zeroString(nativeBalance)) return '0' const nativeToExchangeRatio: string = exchangeDenomination.multiplier diff --git a/src/types/reduxActions.ts b/src/types/reduxActions.ts index f16e300a468..d96b778d82b 100644 --- a/src/types/reduxActions.ts +++ b/src/types/reduxActions.ts @@ -158,10 +158,6 @@ export type Action = data: { pinLoginEnabled: boolean } } | { type: 'UI/SETTINGS/UPDATE_SETTINGS'; data: { settings: SettingsState } } - | { - type: 'UI/WALLETS/SELECT_WALLET' - data: { currencyCode: string; walletId: string } - } | { type: 'UI/SET_COUNTRY_CODE'; data: { countryCode: string | undefined } } | { type: 'UI/SET_NOTIFICATION_HEIGHT' diff --git a/src/types/types.ts b/src/types/types.ts index 07fcdfb5749..22ca2eecc33 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -262,7 +262,7 @@ export interface CountryData { export const asMostRecentWallet = asObject({ id: asString, - currencyCode: asString + tokenId: asEdgeTokenId }) export type MostRecentWallet = ReturnType diff --git a/src/util/ActionProgramUtils.ts b/src/util/ActionProgramUtils.ts index 029dfa65e94..d64fc34e23a 100644 --- a/src/util/ActionProgramUtils.ts +++ b/src/util/ActionProgramUtils.ts @@ -20,7 +20,7 @@ import type { import { convertCurrency, getExchangeRate } from '../selectors/WalletSelectors' import { config } from '../theme/appConfig' import { getToken } from './CurrencyInfoHelpers' -import { enableTokenCurrencyCode } from './CurrencyWalletHelpers' +import { enableTokens } from './CurrencyWalletHelpers' import { convertNativeToExchange, DECIMAL_PRECISION, @@ -76,12 +76,7 @@ export const makeAaveCreateActionProgram = async ( // Swap and Deposit steps // - const depositToken = getToken(borrowEngineWallet, source.tokenId) - - // If no deposit token provided (i.e. buy from exchange provider), default to WBTC - const depositTokenCc = - depositToken == null ? 'WBTC' : depositToken.currencyCode - await enableTokenCurrencyCode(depositTokenCc, borrowEngineWallet) + await enableTokens([source.tokenId], borrowEngineWallet) const toTokenId = source.tokenId ?? @@ -179,7 +174,7 @@ export const makeAaveBorrowAction = async ( // If no borrow token specified (withdraw to bank), default to USDC for intermediate borrow step prior to withdrawing to bank const borrowTokenCc = borrowToken == null ? 'USDC' : borrowToken.currencyCode - await enableTokenCurrencyCode(borrowTokenCc, borrowEngineWallet) + await enableTokens([destination.tokenId], borrowEngineWallet) // TODO: ASSUMPTION: The only borrow destinations are: // 1. USDC @@ -235,12 +230,8 @@ export const makeAaveDepositAction = async ({ } // TODO: Handle buy from fiat onramp in a separate method - const depositToken = getToken(borrowEngineWallet, depositTokenId) - // If no deposit token provided (i.e. buy from exchange provider), default to WBTC - const depositTokenCc = - depositToken == null ? 'WBTC' : depositToken.currencyCode - await enableTokenCurrencyCode(depositTokenCc, borrowEngineWallet) + await enableTokens([depositTokenId], borrowEngineWallet) const allTokens = borrowEngineWallet.currencyConfig.allTokens const tokenId = depositTokenId ?? @@ -322,7 +313,7 @@ export const makeAaveCloseAction = async ({ // We must ensure the token is enabled to get the user's token balance and // calculate exchange rates - await enableTokenCurrencyCode(collateralCurrencyCode, wallet) + await enableTokens([collateralTokenId], wallet) if (debt != null) { const debtTokenId = debt.tokenId @@ -334,7 +325,7 @@ export const makeAaveCloseAction = async ({ // We must ensure the token is enabled to get the user's token balance // and calculate exchange rates - await enableTokenCurrencyCode(debtCurrencyCode, wallet) + await enableTokens([debtTokenId], wallet) // #region Swap Validation diff --git a/src/util/CryptoAmount.ts b/src/util/CryptoAmount.ts index 87361d9a3c5..ea435eb4212 100644 --- a/src/util/CryptoAmount.ts +++ b/src/util/CryptoAmount.ts @@ -8,7 +8,6 @@ import type { import type { GuiExchangeRates } from '../actions/ExchangeRateActions' import { getExchangeRate } from '../selectors/WalletSelectors' import { asBiggystring } from './cleaners' -import { getTokenId } from './CurrencyInfoHelpers' import { DECIMAL_PRECISION, mulToPrecision } from './utils' /** @@ -16,23 +15,9 @@ import { DECIMAL_PRECISION, mulToPrecision } from './utils' */ interface AssetBaseArgs { currencyConfig: EdgeCurrencyConfig + tokenId: EdgeTokenId } -/** - * Specifies that one of tokenId or currencyCode must be provided. To describe a - * mainnet/parent/chain currency, an explicit null must be provided to tokenId - * or currencyCode. - */ -type TokenOrCurrencyCodeArgs = - | { - tokenId: EdgeTokenId - currencyCode?: never - } - | { - tokenId?: never - currencyCode: string - } - // Specifies that one of exchangeAmount or nativeAmount must be provided. type ExchangeOrNativeAmountArgs = | { @@ -45,9 +30,7 @@ type ExchangeOrNativeAmountArgs = } // Combines both requirements. -type CryptoAmountConstructorArgs = AssetBaseArgs & - TokenOrCurrencyCodeArgs & - ExchangeOrNativeAmountArgs +type CryptoAmountConstructorArgs = AssetBaseArgs & ExchangeOrNativeAmountArgs /** * One-stop shop for any information pertaining to a crypto asset. @@ -77,29 +60,9 @@ export class CryptoAmount { * Must construct CryptoAmount with currencyConfig and one of either: tokenId or currencyCode */ public constructor(args: CryptoAmountConstructorArgs) { - const { - currencyCode, - currencyConfig, - exchangeAmount, - nativeAmount, - tokenId - } = args + const { currencyConfig, exchangeAmount, nativeAmount, tokenId } = args this.currencyConfig = currencyConfig - - // Populate tokenId, derived from currencyCode - if (currencyCode != null) { - // Ensure currencyCode is recognized, if given as a constructor argument. - const foundTokenId = getTokenId(currencyConfig, currencyCode) - if (foundTokenId === undefined) { - throw new Error( - `CryptoAmount: Could not find tokenId for currencyCode: ${currencyCode}, pluginId: ${currencyConfig.currencyInfo.pluginId}.` - ) - } else { - this.tokenId = foundTokenId - } - } else { - this.tokenId = tokenId - } + this.tokenId = tokenId // Populate nativeAmount if (exchangeAmount != null) { @@ -202,7 +165,7 @@ export class CryptoAmount { exchangeRates: GuiExchangeRates, isoFiatCode: string, precision?: number - ) { + ): string { return this.fiatValue(exchangeRates, isoFiatCode).toFixed(precision ?? 2) } diff --git a/src/util/CurrencyInfoHelpers.ts b/src/util/CurrencyInfoHelpers.ts index 4bb61aced51..24e8eb13d9b 100644 --- a/src/util/CurrencyInfoHelpers.ts +++ b/src/util/CurrencyInfoHelpers.ts @@ -93,57 +93,6 @@ export const getTokenId = ( return tokenId } -export const getTokenIdForced = ( - account: EdgeAccount, - pluginId: string, - currencyCode: string -): EdgeTokenId => { - const tokenId = getTokenId(account.currencyConfig[pluginId], currencyCode) - if (tokenId === undefined) - throw new Error( - `getTokenIdForced: tokenId not found for ${currencyCode} in ${pluginId}` - ) - return tokenId -} - -export function getCurrencyCodeMultiplier( - currencyConfig: EdgeCurrencyConfig, - currencyCode: string -): string { - const { currencyInfo, allTokens } = currencyConfig - for (const denomination of currencyInfo.denominations) { - if (denomination.name === currencyCode) { - return denomination.multiplier - } - } - - for (const token of Object.values(allTokens)) { - for (const denomination of token.denominations) { - if (denomination.name === currencyCode) { - return denomination.multiplier - } - } - } - - return '1' -} - -export const getWalletTokenId = ( - wallet: EdgeCurrencyWallet, - currencyCode: string -): EdgeTokenId => { - const { currencyConfig, currencyInfo } = wallet - if (currencyInfo.currencyCode === currencyCode) return null - const { allTokens } = currencyConfig ?? {} - const tokenId = Object.keys(allTokens).find( - edgeToken => allTokens[edgeToken].currencyCode === currencyCode - ) - if (tokenId == null) { - throw new Error(`Cannot find tokenId for currencyCode ${currencyCode}`) - } - return tokenId -} - /** * Get the currencyCode associated with a tokenId */ diff --git a/src/util/CurrencyWalletHelpers.ts b/src/util/CurrencyWalletHelpers.ts index f61ca892a90..d76adcbaf20 100644 --- a/src/util/CurrencyWalletHelpers.ts +++ b/src/util/CurrencyWalletHelpers.ts @@ -55,25 +55,6 @@ export const getAvailableBalance = ( return balance } -/** @deprecated - Use `enableTokens()` instead */ -export const enableTokenCurrencyCode = async ( - currencyCode: string, - wallet: EdgeCurrencyWallet -) => { - const allTokens = wallet.currencyConfig.allTokens - const newTokenId = Object.keys(allTokens).find( - tokenId => - allTokens[tokenId].currencyCode.toUpperCase() === - currencyCode.toUpperCase() - ) - if (newTokenId == null) - throw Error( - `Could not find token ${currencyCode} to add to ${wallet.currencyInfo.currencyCode} wallet` - ) - - await enableTokens([newTokenId], wallet) -} - /** * Enables tokens in a wallet, if not already enabled. * - If some tokens are not yet enabled, shows a full screen spinner while they diff --git a/src/util/stakeUtils.ts b/src/util/stakeUtils.ts index 5e4e9f0fe00..bfad81934d2 100644 --- a/src/util/stakeUtils.ts +++ b/src/util/stakeUtils.ts @@ -21,7 +21,6 @@ import type { import type { StakePositionMap } from '../reducers/StakingReducer' import type { EdgeAsset } from '../types/types' import { getCurrencyIconUris } from './CdnUris' -import { getTokenId } from './CurrencyInfoHelpers' import { enableTokens } from './CurrencyWalletHelpers' import { getUkCompliantString } from './ukComplianceUtils' @@ -129,20 +128,7 @@ export const getPolicyIconUris = ( for (const stakeAsset of assetInfos) { const pluginId = stakeAsset.pluginId - const currencyCode = stakeAsset.currencyCode - - const currencyConfig = currencyConfigs[pluginId] - - if (currencyCode === currencyConfig.currencyInfo.currencyCode) { - edgeAssets.push({ pluginId, tokenId: null }) - continue - } - const tokenId = Object.keys(currencyConfig.allTokens).find( - tokenId => - currencyConfig.allTokens[tokenId].currencyCode === currencyCode - ) - if (tokenId == null) continue - + const tokenId = stakeAsset.tokenId edgeAssets.push({ pluginId, tokenId }) } return edgeAssets @@ -223,7 +209,6 @@ export const getFioStakingBalances = ( } export const enableStakeTokens = async ( - account: EdgeAccount, wallet: EdgeCurrencyWallet, stakePolicy: StakePolicy ) => { @@ -232,14 +217,7 @@ export const enableStakeTokens = async ( ...stakePolicy.stakeAssets, ...stakePolicy.rewardAssets ]) { - const pluginId = wallet.currencyInfo.pluginId - const tokenId = getTokenId( - account.currencyConfig[pluginId], - stakeAssetInfo.currencyCode - ) - if (tokenId != null) { - requiredTokenIds.push(tokenId) - } + requiredTokenIds.push(stakeAssetInfo.tokenId) } await enableTokens(requiredTokenIds, wallet) @@ -283,14 +261,14 @@ export const getPoliciesFromPlugins = ( stakePlugins: StakePlugin[], stakePositionMap: StakePositionMap, wallet: EdgeCurrencyWallet, - currencyCode: string + tokenId: EdgeTokenId ): StakePolicy[] => { return stakePlugins.flatMap(stakePlugin => stakePlugin .getPolicies({ wallet, pluginId: wallet.currencyInfo.pluginId, - currencyCode + tokenId }) .filter( stakePolicy => @@ -298,13 +276,13 @@ export const getPoliciesFromPlugins = ( stakePolicy.stakeAssets.some( asset => asset.pluginId === wallet.currencyInfo.pluginId && - asset.currencyCode === currencyCode + asset.tokenId === tokenId )) || (stakePolicy.deprecated && stakePositionMap[stakePolicy.stakePolicyId]?.allocations.some( allocation => allocation.pluginId === wallet.currencyInfo.pluginId && - allocation.currencyCode === currencyCode && + allocation.tokenId === tokenId && gt(allocation.nativeAmount, '0') )) ) diff --git a/src/util/utils.ts b/src/util/utils.ts index 873e9609556..ef2d80ac633 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -33,7 +33,7 @@ import { lstrings } from '../locales/strings' import { convertCurrency, getExchangeRate } from '../selectors/WalletSelectors' import type { RootState } from '../types/reduxTypes' import type { GuiFiatType } from '../types/types' -import { getCurrencyCode, getTokenId } from './CurrencyInfoHelpers' +import { getCurrencyCode } from './CurrencyInfoHelpers' import { base58 } from './encoding' export const DECIMAL_PRECISION = 18 @@ -375,13 +375,13 @@ export const getTotalFiatAmountFromExchangeRates = ( // Find the currency or token info: let info: EdgeCurrencyInfo | EdgeToken = wallet.currencyInfo - if (currencyCode !== wallet.currencyInfo.currencyCode) { - const tokenId = getTokenId(wallet.currencyConfig, currencyCode) - if (tokenId == null) { - log.push(`LogTot: No tokenId for ${currencyCode}`) + if (tokenId != null) { + const token = wallet.currencyConfig.allTokens[tokenId] + if (token == null) { + log.push(`LogTot: No token for ${tokenId}`) continue } - info = wallet.currencyConfig.allTokens[tokenId] + info = token } const { denominations: [denomination] diff --git a/yarn.lock b/yarn.lock index be9d7de4418..7a8184290da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9436,10 +9436,10 @@ ed25519@0.0.4: bindings "^1.2.1" nan "^2.0.9" -edge-core-js@^2.35.0: - version "2.35.0" - resolved "https://registry.yarnpkg.com/edge-core-js/-/edge-core-js-2.35.0.tgz#ef8efadd2281f9c551d2bd6f8f9fed11eb3e5e95" - integrity sha512-CmTrE1Qf4VpLlqLtXoxrEX1tFqDqmPsicw7J9AkL8RGzAMkSf3k13LMGLLBMCnGYK3WLvTRTAeVsKI4y+qcHYA== +edge-core-js@^2.37.0: + version "2.37.0" + resolved "https://registry.yarnpkg.com/edge-core-js/-/edge-core-js-2.37.0.tgz#1f215676acacbb694b78208145faf476c5ae3139" + integrity sha512-DwR9VJXmB8WgXuMaF8/iqsbGgE7XCNBre/L1dhrHe0eKHwqAPlU/tYXESxXygDOumlQN0x4qbDfzOUxs8NtpqQ== dependencies: aes-js "^3.1.0" base-x "^4.0.0"