From 90723695d123d3705b2b2a25d3b5a738ff8d5a78 Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Fri, 13 Sep 2024 13:43:24 +0100 Subject: [PATCH 1/4] refactor(wallet-mobile): moved explorers to network manager (#3630) --- .../Claim/useCases/ShowSuccessScreen.tsx | 3 +- .../MediaDetailsScreen/MediaDetailsScreen.tsx | 12 ++- .../PortfolioTokenInfo/Overview/Overview.tsx | 3 +- .../ShowSubmittedTxScreen.tsx | 3 +- .../ListOrders/CompletedOrders.tsx | 3 +- .../ListOrders/OpenOrders.tsx | 3 +- .../useCases/TxDetails/TxDetails.tsx | 3 +- .../network-manager/network-manager.ts | 4 +- .../TransferSummary/TransferSummary.tsx | 7 +- .../MediaDetailsScreen.json | 88 +++++++++---------- .../TransferSummary/TransferSummary.json | 32 +++---- packages/types/src/network/manager.ts | 3 + 12 files changed, 80 insertions(+), 84 deletions(-) diff --git a/apps/wallet-mobile/src/features/Claim/useCases/ShowSuccessScreen.tsx b/apps/wallet-mobile/src/features/Claim/useCases/ShowSuccessScreen.tsx index f81d57fffa..7ef0c2a26d 100644 --- a/apps/wallet-mobile/src/features/Claim/useCases/ShowSuccessScreen.tsx +++ b/apps/wallet-mobile/src/features/Claim/useCases/ShowSuccessScreen.tsx @@ -1,5 +1,4 @@ import {useClaim} from '@yoroi/claim' -import {useExplorers} from '@yoroi/explorers' import {sortTokenAmountsByInfo} from '@yoroi/portfolio' import {useTheme} from '@yoroi/theme' import {App, Claim, Portfolio} from '@yoroi/types' @@ -93,7 +92,7 @@ const TxHash = ({txHash}: {txHash: string}) => { const strings = useStrings() const {wallet} = useSelectedWallet() const {styles, colors} = useStyles() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers return ( <> diff --git a/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx b/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx index 6b85a59b49..1d55928e22 100644 --- a/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx @@ -1,9 +1,8 @@ import {RouteProp, useRoute} from '@react-navigation/native' import {isString} from '@yoroi/common' -import {useExplorers} from '@yoroi/explorers' import {usePortfolioTokenDiscovery, usePortfolioTokenTraits} from '@yoroi/portfolio' import {useTheme} from '@yoroi/theme' -import {Chain, Network, Portfolio} from '@yoroi/types' +import {Explorers, Network, Portfolio} from '@yoroi/types' import React, {ReactNode, useState} from 'react' import {defineMessages, useIntl} from 'react-intl' import { @@ -98,7 +97,7 @@ type DetailsProps = { networkManager: Network.Manager } const Details = ({activeTab, info, networkManager}: DetailsProps) => { - const {tokenManager, network} = networkManager + const {tokenManager, network, explorers} = networkManager const {tokenDiscovery} = usePortfolioTokenDiscovery( { @@ -127,7 +126,7 @@ const Details = ({activeTab, info, networkManager}: DetailsProps) => { return ( - + @@ -174,12 +173,11 @@ const MetadataRow = ({title, copyText, children}: {title: string; children: Reac type NftOverviewProps = { info: Portfolio.Token.Info traits: Portfolio.Token.Traits | undefined - network: Chain.SupportedNetworks + explorers: Record } -const NftOverview = ({info, network, traits}: NftOverviewProps) => { +const NftOverview = ({info, explorers, traits}: NftOverviewProps) => { const styles = useStyles() const strings = useStrings() - const explorers = useExplorers(network) const [policyId] = info.id.split('.') diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokenDetails/PortfolioTokenInfo/Overview/Overview.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokenDetails/PortfolioTokenInfo/Overview/Overview.tsx index 39e6d889a3..c723c384c3 100644 --- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokenDetails/PortfolioTokenInfo/Overview/Overview.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokenDetails/PortfolioTokenInfo/Overview/Overview.tsx @@ -1,4 +1,3 @@ -import {useExplorers} from '@yoroi/explorers' import {infoExtractName, isPrimaryToken} from '@yoroi/portfolio' import {useTheme} from '@yoroi/theme' import React, {useState} from 'react' @@ -19,7 +18,7 @@ export const Overview = () => { const { wallet: {balances, networkManager}, } = useSelectedWallet() - const explorers = useExplorers(networkManager.network) + const explorers = networkManager.explorers const tokenInfo = balances.records.get(tokenId) const tokenSymbol = tokenInfo ? infoExtractName(tokenInfo.info, {mode: 'currency'}) : '' const [policyId] = tokenInfo?.info.id.split('.') ?? [] diff --git a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.tsx b/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.tsx index 1ccadf117d..58a2491fef 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.tsx @@ -1,5 +1,4 @@ import {createTypeGuardFromSchema, isString} from '@yoroi/common' -import {useExplorers} from '@yoroi/explorers' import {useTheme} from '@yoroi/theme' import React from 'react' import {Linking, StyleSheet, View} from 'react-native' @@ -20,7 +19,7 @@ export const ShowSubmittedTxScreen = () => { const strings = useStrings() const styles = useStyles() const {wallet} = useSelectedWallet() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const walletNavigate = useWalletNavigation() const unsafeParams = useUnsafeParams() diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/CompletedOrders.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/CompletedOrders.tsx index 28d22464c5..766216e465 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/CompletedOrders.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/CompletedOrders.tsx @@ -1,5 +1,4 @@ import {useFocusEffect} from '@react-navigation/native' -import {useExplorers} from '@yoroi/explorers' import {usePortfolioTokenInfo} from '@yoroi/portfolio' import {getPoolUrlByProvider} from '@yoroi/swap' import {useTheme} from '@yoroi/theme' @@ -166,7 +165,7 @@ export const ExpandableOrder = ({order}: {order: MappedRawOrder}) => { const [hiddenInfoOpenId, setHiddenInfoOpenId] = React.useState(null) const {wallet} = useSelectedWallet() const intl = useIntl() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const metadata = order.metadata const id = order.id const expanded = id === hiddenInfoOpenId diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/OpenOrders.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/OpenOrders.tsx index 62036dc116..dd636cb7e7 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/OpenOrders.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/OpenOrders.tsx @@ -2,7 +2,6 @@ import {useNavigation} from '@react-navigation/core' import {NavigationState, useFocusEffect} from '@react-navigation/native' import {FlashList} from '@shopify/flash-list' import {isString} from '@yoroi/common' -import {useExplorers} from '@yoroi/explorers' import {useSwap, useSwapOrdersByStatusOpen} from '@yoroi/swap' import {useTheme} from '@yoroi/theme' import {Buffer} from 'buffer' @@ -62,7 +61,7 @@ export const OpenOrders = () => { const {numberLocale} = useLanguage() const tokenIds = React.useMemo(() => _.uniq(orders?.flatMap((o) => [o.from.tokenId, o.to.tokenId])), [orders]) const transactionsInfos = useTransactionInfos({wallet}) - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const {tokenInfos} = usePortfolioTokenInfos({wallet, tokenIds}, {suspense: true}) const normalizedOrders = React.useMemo(() => { diff --git a/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx b/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx index 01da68bd76..8e646f099e 100644 --- a/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx +++ b/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import {useRoute} from '@react-navigation/native' import {isNonNullable} from '@yoroi/common' -import {useExplorers} from '@yoroi/explorers' import {useTheme} from '@yoroi/theme' import {Chain} from '@yoroi/types' import {BigNumber} from 'bignumber.js' @@ -48,7 +47,7 @@ export const TxDetails = () => { const { selected: {network}, } = useWalletManager() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const internalAddressIndex = fromPairs(wallet.internalAddresses.map((addr, i) => [addr, i])) const externalAddressIndex = fromPairs(wallet.externalAddresses.map((addr, i) => [addr, i])) const [expandedInItemId, setExpandedInItemId] = useState(null) diff --git a/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts b/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts index 38d9a3efc0..0467b5a669 100644 --- a/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts +++ b/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts @@ -1,5 +1,6 @@ import {CardanoApi} from '@yoroi/api' import {mountAsyncStorage, mountMMKVStorage, observableStorageMaker} from '@yoroi/common' +import {explorerManager} from '@yoroi/explorers' import {createPrimaryTokenInfo} from '@yoroi/portfolio' import {Chain, Network} from '@yoroi/types' import {freeze} from 'immer' @@ -148,9 +149,10 @@ export function buildNetworkManagers({ ...config, tokenManager, rootStorage, - // NOTE: we can't use the new rootStorage cuz all modules are async now 🥹 + // NOTE: it can't use the new rootStorage cuz all modules are async now 🥹 legacyRootStorage, api, + explorers: explorerManager[network as Chain.SupportedNetworks], } networkManagers[network as Chain.SupportedNetworks] = networkManager diff --git a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx index ab0091864c..7e58aea50c 100644 --- a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx +++ b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx @@ -1,6 +1,5 @@ -import {useExplorers} from '@yoroi/explorers' import {useTheme} from '@yoroi/theme' -import React from 'react' +import * as React from 'react' import {defineMessages, useIntl} from 'react-intl' import {Linking, StyleSheet, TouchableOpacity, View, ViewProps} from 'react-native' @@ -81,7 +80,7 @@ const Withdrawals = ({ withdrawals: NonNullable }) => { const strings = useStrings() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const addresses = Entries.toAddresses(withdrawals) if (addresses.length < 1) return null @@ -113,7 +112,7 @@ const Deregistrations = ({ deregistrations: NonNullable }) => { const strings = useStrings() - const explorers = useExplorers(wallet.networkManager.network) + const explorers = wallet.networkManager.explorers const refundAmounts = Entries.toAmounts(deregistrations) const primaryAmount = Amounts.getAmount(refundAmounts, wallet.portfolioPrimaryTokenInfo.id) diff --git a/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json b/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json index 0e426177dc..4e09725f7a 100644 --- a/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json +++ b/apps/wallet-mobile/translations/messages/src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!NFT Details", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 356, + "line": 354, "column": 9, - "index": 9887 + "index": 9844 }, "end": { - "line": 359, + "line": 357, "column": 3, - "index": 9958 + "index": 9915 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Overview", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 360, + "line": 358, "column": 12, - "index": 9972 + "index": 9929 }, "end": { - "line": 363, + "line": 361, "column": 3, - "index": 10043 + "index": 10000 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Metadata", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 364, + "line": 362, "column": 12, - "index": 10057 + "index": 10014 }, "end": { - "line": 367, + "line": 365, "column": 3, - "index": 10128 + "index": 10085 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!NFT Name", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 368, + "line": 366, "column": 11, - "index": 10141 + "index": 10098 }, "end": { - "line": 371, + "line": 369, "column": 3, - "index": 10211 + "index": 10168 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Created", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 372, + "line": 370, "column": 13, - "index": 10226 + "index": 10183 }, "end": { - "line": 375, + "line": 373, "column": 3, - "index": 10297 + "index": 10254 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Description", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 376, + "line": 374, "column": 15, - "index": 10314 + "index": 10271 }, "end": { - "line": 379, + "line": 377, "column": 3, - "index": 10391 + "index": 10348 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Author", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 380, + "line": 378, "column": 10, - "index": 10403 + "index": 10360 }, "end": { - "line": 383, + "line": 381, "column": 3, - "index": 10470 + "index": 10427 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Fingerprint", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 384, + "line": 382, "column": 15, - "index": 10487 + "index": 10444 }, "end": { - "line": 387, + "line": 385, "column": 3, - "index": 10564 + "index": 10521 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!Policy id", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 388, + "line": 386, "column": 12, - "index": 10578 + "index": 10535 }, "end": { - "line": 391, + "line": 389, "column": 3, - "index": 10650 + "index": 10607 } }, { @@ -139,14 +139,14 @@ "defaultMessage": "!!!Details on", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 392, + "line": 390, "column": 16, - "index": 10668 + "index": 10625 }, "end": { - "line": 395, + "line": 393, "column": 3, - "index": 10745 + "index": 10702 } }, { @@ -154,14 +154,14 @@ "defaultMessage": "!!!Copy metadata", "file": "src/features/Portfolio/common/MediaDetailsScreen/MediaDetailsScreen.tsx", "start": { - "line": 396, + "line": 394, "column": 16, - "index": 10763 + "index": 10720 }, "end": { - "line": 399, + "line": 397, "column": 3, - "index": 10843 + "index": 10800 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json index da4e31cab6..c41f70c8d1 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!From", "file": "src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx", "start": { - "line": 182, + "line": 181, "column": 13, - "index": 5838 + "index": 5773 }, "end": { - "line": 185, + "line": 184, "column": 3, - "index": 5951 + "index": 5886 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Recovered balance", "file": "src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx", "start": { - "line": 186, + "line": 185, "column": 16, - "index": 5969 + "index": 5904 }, "end": { - "line": 189, + "line": 188, "column": 3, - "index": 6098 + "index": 6033 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Final balance", "file": "src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx", "start": { - "line": 190, + "line": 189, "column": 21, - "index": 6121 + "index": 6056 }, "end": { - "line": 193, + "line": 192, "column": 3, - "index": 6251 + "index": 6186 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!This transaction will unregister one or more staking keys, giving you back your {refundAmount} from your deposit", "file": "src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx", "start": { - "line": 194, + "line": 193, "column": 25, - "index": 6278 + "index": 6213 }, "end": { - "line": 199, + "line": 198, "column": 3, - "index": 6513 + "index": 6448 } } ] \ No newline at end of file diff --git a/packages/types/src/network/manager.ts b/packages/types/src/network/manager.ts index 1013bf59a6..2bba8225ab 100644 --- a/packages/types/src/network/manager.ts +++ b/packages/types/src/network/manager.ts @@ -1,6 +1,8 @@ import {ApiProtocolParams} from '../api/cardano' import {AppObservableStorage} from '../app/observable-storage' import {ChainSupportedNetworks} from '../chain/network' +import {ExplorersExplorer} from '../explorers/explorer' +import {ExplorersManager} from '../explorers/manager' import {PortfolioTokenInfo} from '../portfolio/info' import {PortfolioManagerToken} from '../portfolio/manager' @@ -25,6 +27,7 @@ export type NetworkManager = { rootStorage: AppObservableStorage legacyRootStorage: AppObservableStorage api: NetworkApi + explorers: Record } & NetworkConfig export type NetworkEraConfig = { From 58f4bf7a8e207e1bfc0aa95df684ea7a332b94af Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:49:35 +0100 Subject: [PATCH 2/4] refactor(wallet-mobile): token info drop stage 2 (#3631) --- .../ReviewTransaction/ReviewTransaction.tsx | 6 ++-- .../ConfirmVotingTx/ConfirmVotingTx.tsx | 4 +-- .../ConfirmTx/Summary/BalanceAfter.tsx | 7 ++-- .../Send/useCases/ConfirmTx/Summary/Fees.tsx | 4 +-- .../ConfirmTx/Summary/PrimaryTotal.tsx | 4 +-- .../ConfirmTx/Summary/BalanceAfter.tsx | 7 ++-- .../ConfirmTx/Summary/Fees.tsx | 4 +-- .../ConfirmTx/Summary/PrimaryTotal.tsx | 4 +-- .../ManageCollateralScreen.tsx | 2 +- .../useCases/ConfirmTx/ConfirmTxScreen.tsx | 4 +-- .../ListOrders/helpers.ts | 5 +-- .../useCases/TxDetails/TxDetails.tsx | 4 +-- .../src/legacy/Dashboard/UserSummary.tsx | 6 ++-- .../TransferSummary/TransferSummary.tsx | 10 +++--- .../DelegationConfirmation.tsx | 9 ++++-- .../src/yoroi-wallets/cardano/MultiToken.ts | 17 +++++----- .../yoroi-wallets/cardano/cardano-wallet.ts | 18 ++++------- .../cardano/constants/mainnet/constants.ts | 2 -- .../cardano/constants/sanchonet/constants.ts | 2 -- .../cardano/constants/testnet/constants.ts | 2 -- .../cardano/getMinAmounts.test.ts | 26 +++++++-------- .../yoroi-wallets/cardano/getMinAmounts.ts | 28 +++++++++------- .../processTransactions.test.ts | 10 +++--- .../processTransactions.ts | 29 +++++++---------- .../cardano/transformers/to-lib-token.test.ts | 22 +++++++++++++ .../cardano/transformers/to-lib-token.ts | 9 ++++++ .../src/yoroi-wallets/cardano/types.ts | 3 -- .../src/yoroi-wallets/cardano/utils.test.ts | 12 +++---- .../src/yoroi-wallets/cardano/utils.ts | 31 +++++++++++------- .../src/yoroi-wallets/mocks/transaction.ts | 8 ----- .../src/yoroi-wallets/mocks/wallet.ts | 19 +---------- .../src/yoroi-wallets/types/tokens.ts | 10 ++---- .../src/yoroi-wallets/utils/format.test.ts | 22 ++++++------- .../src/yoroi-wallets/utils/format.ts | 21 +++++++----- .../src/legacy/Dashboard/UserSummary.json | 16 +++++----- .../TransferSummary/TransferSummary.json | 16 +++++----- .../DelegationConfirmation.json | 32 +++++++++---------- .../src/yoroi-wallets/utils/format.json | 24 +++++++------- 38 files changed, 230 insertions(+), 229 deletions(-) create mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.test.ts create mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.ts diff --git a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx b/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx index cc9d0ce780..ffe65478bd 100644 --- a/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx +++ b/apps/wallet-mobile/src/features/Discover/useCases/ReviewTransaction/ReviewTransaction.tsx @@ -225,7 +225,7 @@ const useFormattedTransaction = (cbor: string) => { const receiveUTxO = getUtxoByTxIdAndIndex(input.transaction_id, input.index) const address = receiveUTxO?.receiver const coin = receiveUTxO?.amount != null ? asQuantity(receiveUTxO.amount) : null - const coinText = coin != null ? formatAdaWithText(coin, wallet.primaryToken) : null + const coinText = coin != null ? formatAdaWithText(coin, wallet.portfolioPrimaryTokenInfo) : null const primaryAssets = coinText != null ? [coinText] : [] const multiAssets = receiveUTxO?.assets @@ -249,7 +249,7 @@ const useFormattedTransaction = (cbor: string) => { const formattedOutputs = outputs.map((output) => { const address = output.address const coin = asQuantity(output.amount.coin) - const coinText = formatAdaWithText(coin, wallet.primaryToken) + const coinText = formatAdaWithText(coin, wallet.portfolioPrimaryTokenInfo) const primaryAssets = coinText != null ? [coinText] : [] const multiAssets = output.amount.multiasset ? Object.entries(output.amount.multiasset).map(([policyId, assets]) => { @@ -266,7 +266,7 @@ const useFormattedTransaction = (cbor: string) => { return {assets, address, ownAddress: address != null && isOwnedAddress(address)} }) - const formattedFee = formatAdaWithText(asQuantity(data?.body?.fee ?? '0'), wallet.primaryToken) + const formattedFee = formatAdaWithText(asQuantity(data?.body?.fee ?? '0'), wallet.portfolioPrimaryTokenInfo) return {inputs: formattedInputs, outputs: formattedOutputs, fee: formattedFee} } diff --git a/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmVotingTx/ConfirmVotingTx.tsx b/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmVotingTx/ConfirmVotingTx.tsx index 4fca57c45c..a53d186c7b 100644 --- a/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmVotingTx/ConfirmVotingTx.tsx +++ b/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmVotingTx/ConfirmVotingTx.tsx @@ -102,8 +102,8 @@ export const ConfirmVotingTx = () => { - {`${strings.balanceAfterTx}: ${formatTokenWithSymbol(primaryAmountAfter.quantity, wallet.primaryToken)}`} + {`${strings.balanceAfterTx}: ${formatTokenWithSymbol( + primaryAmountAfter.quantity, + wallet.portfolioPrimaryTokenInfo, + )}`} ) } diff --git a/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/Fees.tsx b/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/Fees.tsx index 9871a3b8f4..05ad1a135f 100644 --- a/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/Fees.tsx +++ b/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/Fees.tsx @@ -11,11 +11,11 @@ import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelec export const Fees = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => { const strings = useStrings() const {wallet} = useSelectedWallet() - const feeAmount = Amounts.getAmount(yoroiUnsignedTx.fee, wallet.primaryToken.identifier) + const feeAmount = Amounts.getAmount(yoroiUnsignedTx.fee, wallet.portfolioPrimaryTokenInfo.id) return ( - {`${strings.fees}: ${formatTokenWithSymbol(feeAmount.quantity, wallet.primaryToken)}`} + {`${strings.fees}: ${formatTokenWithSymbol(feeAmount.quantity, wallet.portfolioPrimaryTokenInfo)}`} ) } diff --git a/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/PrimaryTotal.tsx b/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/PrimaryTotal.tsx index decf7f6db7..6d58948e20 100644 --- a/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/PrimaryTotal.tsx +++ b/apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/PrimaryTotal.tsx @@ -14,14 +14,14 @@ export const PrimaryTotal = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedT const strings = useStrings() const styles = useStyles() const {wallet} = useSelectedWallet() - const primaryAmount = Amounts.getAmountFromEntries(yoroiUnsignedTx.entries, wallet.primaryToken.identifier) + const primaryAmount = Amounts.getAmountFromEntries(yoroiUnsignedTx.entries, wallet.portfolioPrimaryTokenInfo.id) return ( <> {strings.total} - {formatTokenWithSymbol(primaryAmount.quantity, wallet.primaryToken)} + {formatTokenWithSymbol(primaryAmount.quantity, wallet.portfolioPrimaryTokenInfo)} ) diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx index d5986974c0..44a25cc607 100644 --- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx +++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/BalanceAfter.tsx @@ -15,11 +15,14 @@ export const BalanceAfter = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedT const balances = useBalances(wallet) const balancesAfter = Amounts.diff(balances, yoroiUnsignedTx.fee) - const primaryAmountAfter = Amounts.getAmount(balancesAfter, wallet.primaryToken.identifier) + const primaryAmountAfter = Amounts.getAmount(balancesAfter, wallet.portfolioPrimaryTokenInfo.id) return ( - {`${strings.balanceAfterTx}: ${formatTokenWithSymbol(primaryAmountAfter.quantity, wallet.primaryToken)}`} + {`${strings.balanceAfterTx}: ${formatTokenWithSymbol( + primaryAmountAfter.quantity, + wallet.portfolioPrimaryTokenInfo, + )}`} ) } diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx index 9871a3b8f4..05ad1a135f 100644 --- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx +++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/Fees.tsx @@ -11,11 +11,11 @@ import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelec export const Fees = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedTx}) => { const strings = useStrings() const {wallet} = useSelectedWallet() - const feeAmount = Amounts.getAmount(yoroiUnsignedTx.fee, wallet.primaryToken.identifier) + const feeAmount = Amounts.getAmount(yoroiUnsignedTx.fee, wallet.portfolioPrimaryTokenInfo.id) return ( - {`${strings.fees}: ${formatTokenWithSymbol(feeAmount.quantity, wallet.primaryToken)}`} + {`${strings.fees}: ${formatTokenWithSymbol(feeAmount.quantity, wallet.portfolioPrimaryTokenInfo)}`} ) } diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx index 0367b1bbea..a34bfdebf5 100644 --- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx +++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ConfirmTx/Summary/PrimaryTotal.tsx @@ -16,7 +16,7 @@ export const PrimaryTotal = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedT const {wallet} = useSelectedWallet() const primaryAmount = Amounts.getAmount( Amounts.getAmountsFromEntries(yoroiUnsignedTx.entries), - wallet.primaryToken.identifier, + wallet.portfolioPrimaryTokenInfo.id, ) return ( @@ -24,7 +24,7 @@ export const PrimaryTotal = ({yoroiUnsignedTx}: {yoroiUnsignedTx: YoroiUnsignedT {strings.total} - {formatTokenWithSymbol(primaryAmount.quantity, wallet.primaryToken)} + {formatTokenWithSymbol(primaryAmount.quantity, wallet.portfolioPrimaryTokenInfo)} ) diff --git a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx index 175f4ff312..ac5ef186cd 100644 --- a/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx +++ b/apps/wallet-mobile/src/features/Settings/ManageCollateral/ManageCollateralScreen.tsx @@ -105,7 +105,7 @@ export const ManageCollateralScreen = () => { return } - const primaryTokenBalance = new BigNumber(Amounts.getAmount(balances, wallet.primaryToken.identifier).quantity) + const primaryTokenBalance = new BigNumber(Amounts.getAmount(balances, wallet.portfolioPrimaryTokenInfo.id).quantity) const lockedBalance = Quantities.isZero(lockedAmount) ? new BigNumber(0) : new BigNumber(lockedAmount) if (primaryTokenBalance.minus(lockedBalance).isLessThan(collateralConfig.minLovelace)) { diff --git a/apps/wallet-mobile/src/features/Staking/Governance/useCases/ConfirmTx/ConfirmTxScreen.tsx b/apps/wallet-mobile/src/features/Staking/Governance/useCases/ConfirmTx/ConfirmTxScreen.tsx index 2d8f9261e2..8c1c1d2b1e 100644 --- a/apps/wallet-mobile/src/features/Staking/Governance/useCases/ConfirmTx/ConfirmTxScreen.tsx +++ b/apps/wallet-mobile/src/features/Staking/Governance/useCases/ConfirmTx/ConfirmTxScreen.tsx @@ -67,8 +67,8 @@ export const ConfirmTxScreen = () => { const operation = operations[params.vote.kind] const fee = params.unsignedTx.fee - const feeAmount = Amounts.getAmount(fee, wallet.primaryToken.identifier) - const feeText = formatTokenWithText(feeAmount.quantity, wallet.primaryToken) + const feeAmount = Amounts.getAmount(fee, wallet.portfolioPrimaryTokenInfo.id) + const feeText = formatTokenWithText(feeAmount.quantity, wallet.portfolioPrimaryTokenInfo) const onSuccess = (txID: string) => { if (params.vote.kind === 'delegate') { diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/helpers.ts b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/helpers.ts index 50cce23eee..34f13d3a17 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/helpers.ts +++ b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/ListOrders/helpers.ts @@ -27,8 +27,5 @@ export const getCancellationOrderFee = async ( if (!cbor) throw new Error(`Failed to get CBOR from REST API for address ${options.bech32Address}`) const tx = await CardanoMobile.Transaction.fromBytes(Buffer.from(cbor, 'hex')) const feeNumber = await tx.body().then((b) => b.fee()) - return Quantities.denominated( - (await feeNumber.toStr()) as BalanceQuantity, - wallet.primaryToken.metadata.numberOfDecimals, - ) + return Quantities.denominated((await feeNumber.toStr()) as BalanceQuantity, wallet.portfolioPrimaryTokenInfo.decimals) } diff --git a/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx b/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx index 8e646f099e..8d9b197861 100644 --- a/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx +++ b/apps/wallet-mobile/src/features/Transactions/useCases/TxDetails/TxDetails.tsx @@ -226,14 +226,14 @@ const AdaAmount = ({amount}: {amount: BigNumber}) => { return {privacyPlaceholder} } - return {formatTokenWithSymbol(asQuantity(amount), wallet.primaryToken)} + return {formatTokenWithSymbol(asQuantity(amount), wallet.portfolioPrimaryTokenInfo)} } const Fee = ({amount}: {amount: BigNumber}) => { const strings = useStrings() const {wallet} = useSelectedWallet() - const text = `${strings.txDetailsFee} ${formatTokenWithSymbol(asQuantity(amount), wallet.primaryToken)}` + const text = `${strings.txDetailsFee} ${formatTokenWithSymbol(asQuantity(amount), wallet.portfolioPrimaryTokenInfo)}` return {text} } diff --git a/apps/wallet-mobile/src/legacy/Dashboard/UserSummary.tsx b/apps/wallet-mobile/src/legacy/Dashboard/UserSummary.tsx index 667df6d3ed..9c281f805b 100644 --- a/apps/wallet-mobile/src/legacy/Dashboard/UserSummary.tsx +++ b/apps/wallet-mobile/src/legacy/Dashboard/UserSummary.tsx @@ -50,7 +50,7 @@ export const UserSummary = ({totalAdaSum, totalRewards, totalDelegated, onWithdr {!isPrivacyActive ? totalAdaSum != null - ? formatAdaWithText(asQuantity(totalAdaSum), wallet.primaryToken) + ? formatAdaWithText(asQuantity(totalAdaSum), wallet.portfolioPrimaryTokenInfo) : '-' : '**.******'} @@ -77,7 +77,7 @@ export const UserSummary = ({totalAdaSum, totalRewards, totalDelegated, onWithdr {!isPrivacyActive ? totalRewards != null - ? formatAdaWithText(asQuantity(totalRewards), wallet.primaryToken) + ? formatAdaWithText(asQuantity(totalRewards), wallet.portfolioPrimaryTokenInfo) : '-' : '**.******'} @@ -104,7 +104,7 @@ export const UserSummary = ({totalAdaSum, totalRewards, totalDelegated, onWithdr {!isPrivacyActive ? totalDelegated != null - ? formatAdaWithText(asQuantity(totalDelegated), wallet.primaryToken) + ? formatAdaWithText(asQuantity(totalDelegated), wallet.portfolioPrimaryTokenInfo) : '-' : '**.******'} diff --git a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx index 7e58aea50c..2522527a97 100644 --- a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx +++ b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.tsx @@ -15,7 +15,7 @@ export const TransferSummary = ({wallet, unsignedTx}: {wallet: YoroiWallet; unsi const styles = useStyles() const {deregistrations, withdrawals, refundAmount, feeAmount, totalAmount} = withdrawalInfo( unsignedTx, - wallet.primaryToken.identifier, + wallet.portfolioPrimaryTokenInfo.id, ) return ( @@ -26,7 +26,7 @@ export const TransferSummary = ({wallet, unsignedTx}: {wallet: YoroiWallet; unsi {strings.balanceLabel} - {formatTokenWithText(refundAmount.quantity, wallet.primaryToken)} + {formatTokenWithText(refundAmount.quantity, wallet.portfolioPrimaryTokenInfo)} @@ -34,7 +34,7 @@ export const TransferSummary = ({wallet, unsignedTx}: {wallet: YoroiWallet; unsi {strings.fees} - {formatTokenWithText(feeAmount.quantity, wallet.primaryToken)} + {formatTokenWithText(feeAmount.quantity, wallet.portfolioPrimaryTokenInfo)} @@ -42,7 +42,7 @@ export const TransferSummary = ({wallet, unsignedTx}: {wallet: YoroiWallet; unsi {strings.finalBalanceLabel} - {formatTokenWithText(totalAmount.quantity, wallet.primaryToken)} + {formatTokenWithText(totalAmount.quantity, wallet.portfolioPrimaryTokenInfo)} @@ -141,7 +141,7 @@ const Deregistrations = ({ {strings.unregisterExplanation({ - refundAmount: formatTokenWithText(primaryAmount.quantity, wallet.primaryToken), + refundAmount: formatTokenWithText(primaryAmount.quantity, wallet.portfolioPrimaryTokenInfo), })} diff --git a/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx b/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx index 0ac74cfa02..6b59fac6ea 100644 --- a/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx +++ b/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx @@ -59,7 +59,10 @@ export const DelegationConfirmation = () => { resetToTxHistory() } - const fee = formatTokenAmount(yoroiUnsignedTx.fee[wallet.primaryToken.identifier], wallet.primaryToken) + const fee = formatTokenAmount( + yoroiUnsignedTx.fee[wallet.portfolioPrimaryTokenInfo.id], + wallet.portfolioPrimaryTokenInfo, + ) return ( @@ -88,7 +91,7 @@ export const DelegationConfirmation = () => { undefined} editable={false} - value={formatTokenAmount(stakingAmount.quantity, wallet.primaryToken)} + value={formatTokenAmount(stakingAmount.quantity, wallet.portfolioPrimaryTokenInfo)} label={strings.amount} /> @@ -102,7 +105,7 @@ export const DelegationConfirmation = () => { {strings.rewardsExplanation} - {formatTokenWithText(reward, wallet.primaryToken)} + {formatTokenWithText(reward, wallet.portfolioPrimaryTokenInfo)} {meta.isHW && } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/MultiToken.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/MultiToken.ts index 740596113e..b53ee6b7b6 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/MultiToken.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/MultiToken.ts @@ -1,9 +1,7 @@ -// taken from Yoroi Frontend's MultiToken class import {TokenEntry} from '@emurgo/yoroi-lib' +import {Portfolio} from '@yoroi/types' import {BigNumber} from 'bignumber.js' -import {DefaultAsset} from '../types' - export type TokenLookupKey = { identifier: string } @@ -162,20 +160,21 @@ export class MultiToken { /** * Utility functions */ -export const getDefaultNetworkTokenEntry = (defaultAsset: DefaultAsset): DefaultTokenEntry => { +export const getDefaultNetworkTokenEntry = (primaryTokenInfo: Portfolio.Token.Info): DefaultTokenEntry => { return { - defaultIdentifier: defaultAsset.identifier, + defaultIdentifier: primaryTokenInfo.id, } } -export const strToDefaultMultiAsset = (amount: string, defaultAsset: DefaultAsset) => { - const defaultTokenEntry = getDefaultNetworkTokenEntry(defaultAsset) +export const strToDefaultMultiAsset = (amount: string, primaryTokenInfo: Portfolio.Token.Info) => { return new MultiToken( [ { - identifier: defaultTokenEntry.defaultIdentifier, + identifier: primaryTokenInfo.id, amount: new BigNumber(amount), }, ], - defaultTokenEntry, + { + defaultIdentifier: primaryTokenInfo.id, + }, ) } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts index 49ca98b309..2e5aa30a39 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts @@ -25,7 +25,6 @@ import {makeWalletEncryptedStorage, WalletEncryptedStorage} from '../../kernel/s import {isEmptyString} from '../../kernel/utils' import type { AccountStateResponse, - DefaultAsset, FundInfoResponse, PoolInfoRequest, RawUtxo, @@ -58,6 +57,7 @@ import {keyManager} from './key-manager/key-manager' import {processTxHistoryData} from './processTransactions' import {yoroiSignedTx} from './signedTx' import {TransactionManager} from './transactionManager' +import {toLibToken} from './transformers/to-lib-token' import { CardanoTypes, isYoroiWallet, @@ -118,10 +118,6 @@ export const makeCardanoWallet = ( static readonly implementation: Wallet.Implementation = implementation static readonly makeKeys = keyManager(implementation) - // legacy - readonly primaryToken: DefaultAsset = PRIMARY_TOKEN - // readonly primaryTokenInfo: Balance.TokenInfo = PRIMARY_TOKEN_INFO - // =================== create =================== // static readonly build = async ({ id, @@ -408,7 +404,7 @@ export const makeCardanoWallet = ( networkId: this.networkManager.chainId, }, ], - defaults: this.primaryToken, + defaults: toLibToken(this.portfolioPrimaryTokenInfo), } const {coinsPerUtxoByte, keyDeposit, linearFee, poolDeposit} = this.protocolParams @@ -421,7 +417,7 @@ export const makeCardanoWallet = ( poolId || null, // empty pool means deregistration changeAddr, delegatedAmountMT, - this.primaryToken, + toLibToken(this.portfolioPrimaryTokenInfo), {}, { keyDeposit, @@ -629,7 +625,7 @@ export const makeCardanoWallet = ( poolDeposit, networkId: this.networkManager.chainId, }, - this.primaryToken, + toLibToken(this.portfolioPrimaryTokenInfo), {}, votingCertificates, ) @@ -791,7 +787,7 @@ export const makeCardanoWallet = ( const changeAddr = this.getAddressedChangeAddress(addressMode) const addressedUtxos = await this.getAddressedUtxos() - const recipients = await toRecipients(entries, this.primaryToken) + const recipients = await toRecipients(entries, this.portfolioPrimaryTokenInfo) const containsDatum = recipients.some((recipient) => recipient.datum) @@ -819,7 +815,7 @@ export const makeCardanoWallet = ( poolDeposit, networkId: this.networkManager.chainId, }, - this.primaryToken, + toLibToken(this.portfolioPrimaryTokenInfo), {metadata}, ) @@ -1141,7 +1137,7 @@ export const makeCardanoWallet = ( : [...this.internalAddresses, ...this.externalAddresses], this.confirmationCounts[tx.id] || 0, memos[tx.id] ?? null, - this.primaryToken, + this.portfolioPrimaryTokenInfo, ) }) } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts index 181aaafcc8..daf47cfd6c 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts @@ -65,10 +65,8 @@ export const NETWORK_CONFIG = { export const PRIMARY_TOKEN: DefaultAsset = { identifier: '.', - networkId: CHAIN_NETWORK_ID, isDefault: true, metadata: { - type: 'Cardano', policyId: '', assetName: '', numberOfDecimals: 6, diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts index c24b7435f6..a123e5610e 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts @@ -66,10 +66,8 @@ export const NETWORK_CONFIG = { export const PRIMARY_TOKEN: DefaultAsset = { identifier: '.', - networkId: CHAIN_NETWORK_ID, isDefault: true, metadata: { - type: 'Cardano', policyId: '', assetName: '', numberOfDecimals: 6, diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts index b55d40e360..4ada898504 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts @@ -64,10 +64,8 @@ export const NETWORK_CONFIG = { export const PRIMARY_TOKEN: DefaultAsset = { identifier: '.', - networkId: CHAIN_NETWORK_ID, isDefault: true, metadata: { - type: 'Cardano', policyId: '', assetName: '', numberOfDecimals: 6, diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts index e670e23818..69b43afc11 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts @@ -8,12 +8,12 @@ describe('withMinAmounts()', () => { const address = 'addr_test1qrrdv3uxj8shu27ea9djvnn3rl4w3lvh3cyck6yc36mvf6ctlqxj9g0azvpycncr9u600p6t556qhc3psk06uzzw6saq4kvdpq' const amounts: Balance.Amounts = { - [walletMocks.wallet.primaryToken.identifier]: '123', + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '123', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(await withMinAmounts(address, amounts, walletMocks.wallet.primaryToken)).toEqual({ + expect(await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual({ '.': '1301620', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', @@ -24,24 +24,24 @@ describe('withMinAmounts()', () => { const address = 'addr_test1qrrdv3uxj8shu27ea9djvnn3rl4w3lvh3cyck6yc36mvf6ctlqxj9g0azvpycncr9u600p6t556qhc3psk06uzzw6saq4kvdpq' const amounts: Balance.Amounts = { - [walletMocks.wallet.primaryToken.identifier]: '1234432556466', + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '1234432556466', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(await withMinAmounts(address, amounts, walletMocks.wallet.primaryToken)).toEqual(amounts) + expect(await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual(amounts) }) }) describe('withPrimaryToken()', () => { it('should return the input amounts', () => { const amounts: Balance.Amounts = { - [walletMocks.wallet.primaryToken.identifier]: '123', + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '123', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(withPrimaryToken(amounts, walletMocks.wallet.primaryToken)).toEqual(amounts) + expect(withPrimaryToken(amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual(amounts) }) it('should return the input amounts plus primary token as 0', () => { @@ -50,8 +50,8 @@ describe('withPrimaryToken()', () => { '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(withPrimaryToken(amounts, walletMocks.wallet.primaryToken)).toEqual({ - [walletMocks.wallet.primaryToken.identifier]: '0', + expect(withPrimaryToken(amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual({ + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '0', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', }) @@ -61,28 +61,28 @@ describe('withPrimaryToken()', () => { describe('getMinAmounts()', () => { it('should return the min amount', async () => { const amounts: Balance.Amounts = { - [walletMocks.wallet.primaryToken.identifier]: '123', + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '123', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } const address = 'addr_test1qrrdv3uxj8shu27ea9djvnn3rl4w3lvh3cyck6yc36mvf6ctlqxj9g0azvpycncr9u600p6t556qhc3psk06uzzw6saq4kvdpq' - expect(await getMinAmounts(address, amounts, walletMocks.wallet.primaryToken)).toEqual({ - [walletMocks.wallet.primaryToken.identifier]: '1301620', + expect(await getMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual({ + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '1301620', }) }) it('should throw an error', async () => { const amounts: Balance.Amounts = { - [walletMocks.wallet.primaryToken.identifier]: '123', + [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '123', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } const address = 'really-bad-address' - const primaryToken = walletMocks.wallet.primaryToken + const primaryToken = walletMocks.wallet.portfolioPrimaryTokenInfo await expect(getMinAmounts(address, amounts, primaryToken)).rejects.toEqual( new Error('getMinAmounts::Error not a valid address'), diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts index 7eefd603cc..2c63606617 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts @@ -1,9 +1,9 @@ import {BigNum} from '@emurgo/cross-csl-core' import {normalizeToAddress} from '@emurgo/yoroi-lib/dist/internals/utils/addresses' -import {Balance} from '@yoroi/types' +import {Balance, Portfolio} from '@yoroi/types' import BigNumber from 'bignumber.js' -import {Address, Token} from '../types' +import {Address} from '../types' import {Amounts, asQuantity, Quantities} from '../utils' import {CardanoMobile} from '../wallets' import {cardanoValueFromMultiToken} from './cardanoValueFromMultiToken' @@ -13,10 +13,10 @@ import {MultiToken} from './MultiToken' export const withMinAmounts = async ( address: Address, amounts: Balance.Amounts, - primaryToken: Token, + primaryTokenInfo: Portfolio.Token.Info, ): Promise => { - const amountsWithPrimaryToken = withPrimaryToken(amounts, primaryToken) - const minAmounts = await getMinAmounts(address, amountsWithPrimaryToken, primaryToken) + const amountsWithPrimaryToken = withPrimaryToken(amounts, primaryTokenInfo) + const minAmounts = await getMinAmounts(address, amountsWithPrimaryToken, primaryTokenInfo) return Amounts.map(amountsWithPrimaryToken, (amount) => ({ ...amount, @@ -24,16 +24,20 @@ export const withMinAmounts = async ( })) } -export const getMinAmounts = async (address: Address, amounts: Balance.Amounts, primaryToken: Token) => { +export const getMinAmounts = async ( + address: Address, + amounts: Balance.Amounts, + primaryTokenInfo: Portfolio.Token.Info, +) => { const multiToken = new MultiToken( [ - {identifier: primaryToken.identifier, amount: new BigNumber('0')}, + {identifier: primaryTokenInfo.id, amount: new BigNumber('0')}, ...Amounts.toArray(amounts).map(({tokenId, quantity}) => ({ identifier: tokenId, amount: new BigNumber(quantity), })), ], - {defaultIdentifier: primaryToken.identifier}, + {defaultIdentifier: primaryTokenInfo.id}, ) const [value, coinsPerUtxoByte] = await Promise.all([ @@ -57,15 +61,15 @@ export const getMinAmounts = async (address: Address, amounts: Balance.Amounts, .then(asQuantity) return { - [primaryToken.identifier]: minAda, + [primaryTokenInfo.id]: minAda, } as Balance.Amounts } -export const withPrimaryToken = (amounts: Balance.Amounts, primaryToken: Token): Balance.Amounts => { - if (Amounts.includes(amounts, primaryToken.identifier)) return amounts +export const withPrimaryToken = (amounts: Balance.Amounts, primaryTokenInfo: Portfolio.Token.Info): Balance.Amounts => { + if (Amounts.includes(amounts, primaryTokenInfo.id)) return amounts return { ...amounts, - [primaryToken.identifier]: Quantities.zero, + [primaryTokenInfo.id]: Quantities.zero, } } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.test.ts index 4b7e9dc53d..37a25ae551 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.test.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.test.ts @@ -1,5 +1,5 @@ +import {primaryTokenInfoMainnet} from '../../../features/WalletManager/network-manager/network-manager' import {RawTransaction, TRANSACTION_DIRECTION} from '../../types/other' -import {PRIMARY_TOKEN} from '../constants/testnet/constants' import {MultiToken} from '../MultiToken' import {toCachedTx} from '../transactionManager' import {processTxHistoryData} from './processTransactions' @@ -276,7 +276,7 @@ describe('processTxHistoryData', () => { myAddresses, 100, // confirmations 'fake memo', - PRIMARY_TOKEN, + primaryTokenInfoMainnet, ) const delta = MultiToken.fromArray(tx.delta) @@ -292,7 +292,7 @@ describe('processTxHistoryData', () => { myAddresses, 100, // confirmations 'fake memo', - PRIMARY_TOKEN, + primaryTokenInfoMainnet, ) const delta = MultiToken.fromArray(tx.delta) @@ -308,7 +308,7 @@ describe('processTxHistoryData', () => { myAddresses, 100, // confirmations 'fake memo', - PRIMARY_TOKEN, + primaryTokenInfoMainnet, ) const delta = MultiToken.fromArray(tx.delta) @@ -329,7 +329,7 @@ describe('processTxHistoryData', () => { myAddresses, 100, // confirmations 'fake memo', - PRIMARY_TOKEN, + primaryTokenInfoMainnet, ) const delta = MultiToken.fromArray(tx.delta) diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.ts index 8ebb6a2a86..e56dc9e559 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/processTransactions/processTransactions.ts @@ -1,13 +1,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import {isArray, isString} from '@yoroi/common' +import {Portfolio} from '@yoroi/types' import assert from 'assert' import {BigNumber} from 'bignumber.js' import { BaseAsset, CERTIFICATE_KIND, - DefaultAsset, - NetworkId, Token, Transaction, TRANSACTION_DIRECTION, @@ -41,7 +40,7 @@ export const getTransactionAssurance = ( return 'HIGH' } -const getTxTokens = (tx: Transaction, networkId: NetworkId): Record => { +const getTxTokens = (tx: Transaction): Record => { const tokens: Record = {} const rawTokens: Array = [] tx.inputs.forEach((i) => rawTokens.push(...i.assets)) @@ -49,14 +48,11 @@ const getTxTokens = (tx: Transaction, networkId: NetworkId): Record { if (tokens[t.assetId] == null) { tokens[t.assetId] = { - networkId, isDefault: false, identifier: t.assetId, metadata: { policyId: t.policyId, assetName: t.name, - // no metadata for now - type: 'Cardano', numberOfDecimals: 0, ticker: null, longName: null, @@ -74,11 +70,11 @@ const _sum = ( amount: string assets: Array }>, - defaultAsset: DefaultAsset, + primaryTokenInfo: Portfolio.Token.Info, ): MultiToken => a.reduce( (acc: MultiToken, x) => acc.joinAddMutable(multiTokenFromRemote(x)), - new MultiToken([], getDefaultNetworkTokenEntry(defaultAsset)), + new MultiToken([], getDefaultNetworkTokenEntry(primaryTokenInfo)), ) const _multiPartyWarningCache: Record = {} @@ -87,7 +83,7 @@ export const processTxHistoryData = ( ownAddresses: Array, confirmations: number, memo: string | null, - defaultAsset: DefaultAsset, + primaryTokenInfo: Portfolio.Token.Info, ): TransactionInfo => { const metadata = tx.metadata?.reduce( (metadatas: TransactionInfo['metadata'], metadata) => { @@ -104,7 +100,7 @@ export const processTxHistoryData = ( {}, ) - const _strToDefaultMultiAsset = (amount: string) => strToDefaultMultiAsset(amount, defaultAsset) + const _strToDefaultMultiAsset = (amount: string) => strToDefaultMultiAsset(amount, primaryTokenInfo) // collateral const collateral = tx.collateralInputs || [] const isNonNativeScriptExecution = Number(tx.scriptSize) > 0 || collateral.length > 0 @@ -161,13 +157,13 @@ export const processTxHistoryData = ( const ownInputs = unifiedInputs.filter(({address}) => ownAddresses.includes(address)) const ownOutputs = unifiedOutputs.filter(({address}) => ownAddresses.includes(address)) - const totalIn = _sum(unifiedInputs, defaultAsset) + const totalIn = _sum(unifiedInputs, primaryTokenInfo) - const totalOut = _sum(unifiedOutputs, defaultAsset) + const totalOut = _sum(unifiedOutputs, primaryTokenInfo) - const ownIn = _sum(ownInputs, defaultAsset).joinAddMutable(ownImplicitInput) + const ownIn = _sum(ownInputs, primaryTokenInfo).joinAddMutable(ownImplicitInput) - const ownOut = _sum(ownOutputs, defaultAsset).joinAddMutable(ownImplicitOutput) + const ownOut = _sum(ownOutputs, primaryTokenInfo).joinAddMutable(ownImplicitOutput) const hasOnlyOwnInputs = ownInputs.length === unifiedInputs.length const hasOnlyOwnOutputs = ownOutputs.length === unifiedOutputs.length @@ -214,7 +210,7 @@ export const processTxHistoryData = ( // balance = sum(delta) // recall: if the tx has withdrawals or refunds to this wallet, they are // included in own utxo outputs - const delta = _sum(ownUtxoOutputs, defaultAsset).joinSubtractMutable(_sum(ownUtxoInputs, defaultAsset)) + const delta = _sum(ownUtxoOutputs, primaryTokenInfo).joinSubtractMutable(_sum(ownUtxoInputs, primaryTokenInfo)) let amount let fee @@ -246,12 +242,11 @@ export const processTxHistoryData = ( } const assurance = getTransactionAssurance(tx.status, confirmations) - const tokens = getTxTokens(tx, defaultAsset.networkId) + const tokens = getTxTokens(tx) const _remoteAssetAsTokenEntry = (asset: BaseAsset) => ({ identifier: asset.assetId, amount: new BigNumber(asset.amount), - networkId: defaultAsset.networkId, }) return { diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.test.ts new file mode 100644 index 0000000000..7ba57998da --- /dev/null +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.test.ts @@ -0,0 +1,22 @@ +import {tokenInfoMocks} from '@yoroi/portfolio' + +import {toLibToken} from './to-lib-token' + +describe('toLibToken', () => { + it('should convert secondary token info to lib token', () => { + const tokenInfo = tokenInfoMocks.ftNoTicker + const libToken = toLibToken(tokenInfo) + expect(libToken).toEqual({ + identifier: tokenInfo.id, + isDefault: false, + }) + }) + it('should convert primary token info to lib token', () => { + const tokenInfo = tokenInfoMocks.primaryETH + const libToken = toLibToken(tokenInfo) + expect(libToken).toEqual({ + identifier: tokenInfo.id, + isDefault: true, + }) + }) +}) diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.ts new file mode 100644 index 0000000000..fa5c18db05 --- /dev/null +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/transformers/to-lib-token.ts @@ -0,0 +1,9 @@ +import {isPrimaryToken} from '@yoroi/portfolio' +import {Portfolio} from '@yoroi/types' + +export function toLibToken(tokenInfo: Portfolio.Token.Info) { + return { + identifier: tokenInfo.id, + isDefault: isPrimaryToken(tokenInfo), + } +} diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts index 5dd4cc4f41..f9db386c31 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/types.ts @@ -33,7 +33,6 @@ import type { TxStatusResponse, WalletState, } from '../types/other' -import {DefaultAsset} from '../types/tokens' import type {Addresses} from './account-manager/account-manager' export type WalletEvent = @@ -62,7 +61,6 @@ export type Pagination = { export interface YoroiWallet { id: string publicKeyHex: string - primaryToken: Readonly readonly portfolioPrimaryTokenInfo: Readonly // --------------------------------------------------------------------------------------- @@ -190,7 +188,6 @@ export const isYoroiWallet = (wallet: unknown): wallet is YoroiWallet => { const yoroiWalletKeys: Array = [ 'id', 'publicKeyHex', - 'primaryToken', // Portfolio 'balance$', diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.test.ts index 704641434e..838639674c 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.test.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.test.ts @@ -1,34 +1,32 @@ import {SendToken} from '@emurgo/yoroi-lib' import {Balance} from '@yoroi/types' +import {primaryTokenInfoMainnet} from '../../features/WalletManager/network-manager/network-manager' import {Token} from '../types' -import {PRIMARY_TOKEN} from './constants/mainnet/constants' import {toSendToken, toSendTokenList} from './utils' describe('toSendTokenList', () => { - const asSendToken = toSendToken(PRIMARY_TOKEN) + const asSendToken = toSendToken(primaryTokenInfoMainnet) it('converts amounts to send token list for tx (lib)', async () => { const amounts: Balance.Amounts = { - [PRIMARY_TOKEN.identifier]: '123', + [primaryTokenInfoMainnet.id]: '123', [secondaryToken.identifier]: '456', } - const primaryAsToken = asSendToken({tokenId: PRIMARY_TOKEN.identifier, quantity: '123'}) + const primaryAsToken = asSendToken({tokenId: primaryTokenInfoMainnet.id, quantity: '123'}) const secondaryAsToken = asSendToken({tokenId: secondaryToken.identifier, quantity: '456'}) const sendTokenList: Array = [primaryAsToken, secondaryAsToken] - expect(toSendTokenList(amounts, PRIMARY_TOKEN)).toEqual(sendTokenList) + expect(toSendTokenList(amounts, primaryTokenInfoMainnet)).toEqual(sendTokenList) }) }) const secondaryToken: Token = { identifier: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', - networkId: 1, isDefault: false, metadata: { - type: 'Cardano', policyId: '2', assetName: '2', ticker: '2', diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts index ca300bb212..8d1790b663 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts @@ -1,12 +1,12 @@ /* eslint-disable no-empty */ import {SendToken} from '@emurgo/yoroi-lib' -import {Balance, Wallet} from '@yoroi/types' +import {Balance, Portfolio, Wallet} from '@yoroi/types' import {BigNumber} from 'bignumber.js' import {Buffer} from 'buffer' import {YoroiEntry} from '../types' import {BaseAsset, RawUtxo} from '../types/other' -import {DefaultAsset, Token} from '../types/tokens' +import {DefaultAsset} from '../types/tokens' import {Amounts} from '../utils' import {CardanoMobile} from '../wallets' import {toAssetNameHex, toPolicyId} from './api/utils' @@ -124,17 +124,17 @@ export const getCardanoBaseConfig = ( }, ] -export const toSendTokenList = (amounts: Balance.Amounts, primaryToken: Token): Array => { - return Amounts.toArray(amounts).map(toSendToken(primaryToken)) +export const toSendTokenList = (amounts: Balance.Amounts, primaryTokenInfo: Portfolio.Token.Info): Array => { + return Amounts.toArray(amounts).map(toSendToken(primaryTokenInfo)) } -export const toRecipients = async (entries: YoroiEntry[], primaryToken: DefaultAsset) => { +export const toRecipients = async (entries: YoroiEntry[], primaryTokenInfo: Portfolio.Token.Info) => { return Promise.all( entries.map(async (entry) => { - const amounts = await withMinAmounts(entry.address, entry.amounts, primaryToken) + const amounts = await withMinAmounts(entry.address, entry.amounts, primaryTokenInfo) return { receiver: entry.address, - tokens: toSendTokenList(amounts, primaryToken), + tokens: toSendTokenList(amounts, primaryTokenInfo), datum: entry.datum, } }), @@ -142,10 +142,19 @@ export const toRecipients = async (entries: YoroiEntry[], primaryToken: DefaultA } export const toSendToken = - (primaryToken: Token) => - (amount: Balance.Amount): SendToken => { - const {tokenId, quantity} = amount - const isPrimary = tokenId === primaryToken.identifier + (primaryTokenInfo: Portfolio.Token.Info) => + (amount: Balance.Amount | Portfolio.Token.Amount): SendToken => { + let tokenId = '' + let quantity = '' + if ('info' in amount) { + tokenId = amount.info.id + quantity = amount.quantity.toString() + } else { + tokenId = amount.tokenId + quantity = amount.quantity + } + + const isPrimary = tokenId === primaryTokenInfo.id return { token: { diff --git a/apps/wallet-mobile/src/yoroi-wallets/mocks/transaction.ts b/apps/wallet-mobile/src/yoroi-wallets/mocks/transaction.ts index 6313b3488b..c12d01b921 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/mocks/transaction.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/mocks/transaction.ts @@ -77,13 +77,11 @@ export const mockTransactionInfos: Record = { assurance: 'HIGH', tokens: { '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7': { - networkId: 1, isDefault: false, identifier: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', metadata: { policyId: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', assetName: '', - type: 'Cardano', numberOfDecimals: 0, ticker: null, longName: null, @@ -171,13 +169,11 @@ export const mockTransactionInfos: Record = { assurance: 'HIGH', tokens: { '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7': { - networkId: 1, isDefault: false, identifier: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', metadata: { policyId: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', assetName: '', - type: 'Cardano', numberOfDecimals: 0, ticker: null, longName: null, @@ -265,13 +261,11 @@ export const mockTransactionInfos: Record = { assurance: 'HIGH', tokens: { '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7': { - networkId: 1, isDefault: false, identifier: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', metadata: { policyId: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', assetName: '', - type: 'Cardano', numberOfDecimals: 0, ticker: null, longName: null, @@ -362,13 +356,11 @@ export const mockTransactionInfo = (transaction?: Partial): Tra assurance: 'HIGH', tokens: { '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7': { - networkId: 1, isDefault: false, identifier: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', metadata: { policyId: '6b8d07d69639e9413dd637a1a815a7323c69c86abbafb66dbfdb1aa7', assetName: '', - type: 'Cardano', numberOfDecimals: 0, ticker: null, longName: null, diff --git a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts index 926b53d0aa..5735c5ed9f 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts @@ -12,7 +12,7 @@ import {Observable} from 'rxjs' import {buildPortfolioTokenManagers} from '../../features/Portfolio/common/helpers/build-token-managers' import {buildNetworkManagers} from '../../features/WalletManager/network-manager/network-manager' import {toTokenInfo, utf8ToHex} from '../cardano/api/utils' -import {CHIMERIC_ACCOUNT, PRIMARY_TOKEN, STAKING_KEY_INDEX} from '../cardano/constants/testnet/constants' +import {CHIMERIC_ACCOUNT, STAKING_KEY_INDEX} from '../cardano/constants/testnet/constants' import {CardanoTypes, YoroiWallet} from '../cardano/types' import { RemotePoolMetaSuccess, @@ -70,7 +70,6 @@ const wallet: YoroiWallet = { hasOnlyPrimary: false, id: 'wallet-id', api: AppApi.mockAppApi, - primaryToken: PRIMARY_TOKEN, rewardAddressHex: 'reward-address-hex', publicKeyHex: 'publicKeyHex', utxos, @@ -582,11 +581,9 @@ const balances: Balance.Amounts = { const tokenInfos: Record = { '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': toTokenInfo({ - networkId: 300, identifier: '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950', isDefault: false, metadata: { - type: 'Cardano', policyId: '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d', assetName: '7444524950', ticker: '', @@ -596,11 +593,9 @@ const tokenInfos: Record = { }, }), '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': toTokenInfo({ - networkId: 300, identifier: '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e', isDefault: false, metadata: { - type: 'Cardano', policyId: '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6', assetName: '4d494e', ticker: '', @@ -610,11 +605,9 @@ const tokenInfos: Record = { }, }), '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65f.74484f444c52': toTokenInfo({ - networkId: 300, identifier: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65f.74484f444c52', isDefault: false, metadata: { - type: 'Cardano', policyId: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65f', assetName: '74484f444c52', ticker: '', @@ -624,11 +617,9 @@ const tokenInfos: Record = { }, }), '1ca1fc0c880d25850cb00303788dfb51bdf2f902f6dce47d1ad09d5b.44': toTokenInfo({ - networkId: 300, identifier: '1ca1fc0c880d25850cb00303788dfb51bdf2f902f6dce47d1ad09d5b.44', isDefault: false, metadata: { - type: 'Cardano', policyId: '1ca1fc0c880d25850cb00303788dfb51bdf2f902f6dce47d1ad09d5b', assetName: '44', ticker: '', @@ -638,11 +629,9 @@ const tokenInfos: Record = { }, }), '08d91ec4e6c743a92de97d2fde5ca0d81493555c535894a3097061f7.c8b0': toTokenInfo({ - networkId: 300, identifier: '08d91ec4e6c743a92de97d2fde5ca0d81493555c535894a3097061f7.c8b0', isDefault: false, metadata: { - type: 'Cardano', policyId: '08d91ec4e6c743a92de97d2fde5ca0d81493555c535894a3097061f7', assetName: 'c8b0', ticker: '', @@ -677,11 +666,9 @@ const tokenInfos: Record = { }, '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c53': { ...toTokenInfo({ - networkId: 300, identifier: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c53', isDefault: false, metadata: { - type: 'Cardano', policyId: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e', assetName: '74484f444c53', ticker: '8DEC', @@ -695,11 +682,9 @@ const tokenInfos: Record = { icon: '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', }, '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c54': toTokenInfo({ - networkId: 300, identifier: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c54', isDefault: false, metadata: { - type: 'Cardano', policyId: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e', assetName: '74484f444c53', ticker: '12DEC', @@ -709,11 +694,9 @@ const tokenInfos: Record = { }, }), '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c55': toTokenInfo({ - networkId: 300, identifier: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e.74484f444c55', isDefault: false, metadata: { - type: 'Cardano', policyId: '1d129dc9c03f95a863489883914f05a52e13135994a32f0cbeacc65e', assetName: '74484f444c53', ticker: '20DEC', diff --git a/apps/wallet-mobile/src/yoroi-wallets/types/tokens.ts b/apps/wallet-mobile/src/yoroi-wallets/types/tokens.ts index f9f454d7db..cf3846fb1f 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/types/tokens.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/types/tokens.ts @@ -1,5 +1,3 @@ -import {NetworkId} from './other' - export type TokenCommonMetadata = { numberOfDecimals: number ticker: null | string @@ -8,22 +6,19 @@ export type TokenCommonMetadata = { } export type TokenMetadata = TokenCommonMetadata & { - type: 'Cardano' policyId: string // empty string for ADA assetName: string // empty string for ADA } export type Token = { - networkId: NetworkId isDefault: boolean identifier: string metadata: TokenMetadata } export type DefaultAssetMetadata = TokenCommonMetadata & { - type: 'Cardano' - policyId: string // empty string for ADA - assetName: string // empty string for ADA + policyId: string + assetName: string ticker: string } @@ -32,7 +27,6 @@ export type DefaultAsset = Token & { } export type LegacyToken = { - networkId: NetworkId isDefault: boolean identifier: string metadata: TokenMetadata diff --git a/apps/wallet-mobile/src/yoroi-wallets/utils/format.test.ts b/apps/wallet-mobile/src/yoroi-wallets/utils/format.test.ts index 4264d2bb8b..e37d9b13b9 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/utils/format.test.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/utils/format.test.ts @@ -1,12 +1,10 @@ -import {PRIMARY_TOKEN} from '../cardano/constants/mainnet/constants' +import {primaryTokenInfoMainnet} from '../../features/WalletManager/network-manager/network-manager' import {asQuantity} from '.' import {formatTokenAmount, formatTokenFractional, formatTokenInteger} from './format' -const defaultCardanoAsset = PRIMARY_TOKEN - describe('formatAda', () => { it('formats zero', () => { - expect(formatTokenAmount(asQuantity(0), defaultCardanoAsset)).toEqual('0.000000') + expect(formatTokenAmount(asQuantity(0), primaryTokenInfoMainnet)).toEqual('0.000000') }) it('formats positive', () => { @@ -19,7 +17,7 @@ describe('formatAda', () => { ['9999999000000', '9,999,999.000000'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenAmount(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenAmount(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) it('formats negative', () => { @@ -32,14 +30,14 @@ describe('formatAda', () => { ['-9999999000000', '-9,999,999.000000'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenAmount(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenAmount(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) }) describe('formatAdaFractional', () => { it('formats zero', () => { - expect(formatTokenFractional(asQuantity(0), defaultCardanoAsset)).toEqual('.000000') + expect(formatTokenFractional(asQuantity(0), primaryTokenInfoMainnet)).toEqual('.000000') }) it('formats positive', () => { @@ -52,7 +50,7 @@ describe('formatAdaFractional', () => { ['9999999000000', '.000000'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenFractional(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenFractional(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) it('formats negative', () => { @@ -65,14 +63,14 @@ describe('formatAdaFractional', () => { ['-9999999000000', '.000000'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenFractional(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenFractional(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) }) describe('formatAdaInteger', () => { it('formats zero', () => { - expect(formatTokenInteger(asQuantity(0), defaultCardanoAsset)).toEqual('0') + expect(formatTokenInteger(asQuantity(0), primaryTokenInfoMainnet)).toEqual('0') }) it('formats positive', () => { @@ -86,7 +84,7 @@ describe('formatAdaInteger', () => { ['9999999000000', '9,999,999'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenInteger(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenInteger(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) it('formats negative', () => { @@ -100,7 +98,7 @@ describe('formatAdaInteger', () => { ['-9999999000000', '-9,999,999'], ] tests.forEach(([ada, formatted]) => { - expect(formatTokenInteger(asQuantity(ada), defaultCardanoAsset)).toEqual(formatted) + expect(formatTokenInteger(asQuantity(ada), primaryTokenInfoMainnet)).toEqual(formatted) }) }) }) diff --git a/apps/wallet-mobile/src/yoroi-wallets/utils/format.ts b/apps/wallet-mobile/src/yoroi-wallets/utils/format.ts index eaf1ed60a5..8d4e245823 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/utils/format.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/utils/format.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import AssetFingerprint from '@emurgo/cip14-js' +import {isTokenInfo as isPortfolioTokenInfo} from '@yoroi/portfolio' import {Balance, Portfolio} from '@yoroi/types' import {BigNumber} from 'bignumber.js' import type {FormatDateOptions, IntlShape} from 'react-intl' @@ -92,7 +93,13 @@ const getTokenV2Fingerprint = (token: Balance.TokenInfo | DefaultAsset): string }) } -export const formatTokenWithSymbol = (quantity: Balance.Quantity, token: Balance.TokenInfo | DefaultAsset): string => { +export const formatTokenWithSymbol = ( + quantity: Balance.Quantity, + token: Balance.TokenInfo | DefaultAsset | Portfolio.Token.Info, +): string => { + if (isPortfolioTokenInfo(token)) { + return `${formatTokenAmount(quantity, token)} ${token.ticker || token.fingerprint}` + } const denomination = getSymbol(token) ?? getTokenV2Fingerprint(token) return `${formatTokenAmount(quantity, token)} ${denomination}` } @@ -161,16 +168,14 @@ export const truncateWithEllipsis = (s: string, n: number) => { // TODO(multi-asset): consider removing these -const formatAda = (quantity: Balance.Quantity, defaultAsset: DefaultAsset) => { - const defaultAssetMeta = defaultAsset.metadata - const normalizationFactor = Math.pow(10, defaultAssetMeta.numberOfDecimals) +const formatAda = (quantity: Balance.Quantity, primaryTokenInfo: Portfolio.Token.Info) => { + const normalizationFactor = Math.pow(10, primaryTokenInfo.decimals) const num = new BigNumber(quantity).dividedBy(normalizationFactor) - return num.toFormat(6) + return num.toFormat(primaryTokenInfo.decimals) } -export const formatAdaWithText = (quantity: Balance.Quantity, defaultAsset: DefaultAsset) => { - const defaultAssetMeta = defaultAsset.metadata - return `${formatAda(quantity, defaultAsset)} ${defaultAssetMeta.ticker}` +export const formatAdaWithText = (quantity: Balance.Quantity, primaryTokenInfo: Portfolio.Token.Info) => { + return `${formatAda(quantity, primaryTokenInfo)} ${primaryTokenInfo.ticker}` } export const formatTime = (timestamp: string, intl: IntlShape) => { diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/UserSummary.json b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/UserSummary.json index d0cd1b0a1e..ca0a80b0ba 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/UserSummary.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/UserSummary.json @@ -6,12 +6,12 @@ "start": { "line": 177, "column": 9, - "index": 5112 + "index": 5151 }, "end": { "line": 180, "column": 3, - "index": 5214 + "index": 5253 } }, { @@ -21,12 +21,12 @@ "start": { "line": 181, "column": 16, - "index": 5232 + "index": 5271 }, "end": { "line": 184, "column": 3, - "index": 5342 + "index": 5381 } }, { @@ -36,12 +36,12 @@ "start": { "line": 185, "column": 18, - "index": 5362 + "index": 5401 }, "end": { "line": 188, "column": 3, - "index": 5476 + "index": 5515 } }, { @@ -51,12 +51,12 @@ "start": { "line": 189, "column": 23, - "index": 5501 + "index": 5540 }, "end": { "line": 192, "column": 3, - "index": 5613 + "index": 5652 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json index c41f70c8d1..e59bca4476 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/TransferSummary/TransferSummary.json @@ -6,12 +6,12 @@ "start": { "line": 181, "column": 13, - "index": 5773 + "index": 5830 }, "end": { "line": 184, "column": 3, - "index": 5886 + "index": 5943 } }, { @@ -21,12 +21,12 @@ "start": { "line": 185, "column": 16, - "index": 5904 + "index": 5961 }, "end": { "line": 188, "column": 3, - "index": 6033 + "index": 6090 } }, { @@ -36,12 +36,12 @@ "start": { "line": 189, "column": 21, - "index": 6056 + "index": 6113 }, "end": { "line": 192, "column": 3, - "index": 6186 + "index": 6243 } }, { @@ -51,12 +51,12 @@ "start": { "line": 193, "column": 25, - "index": 6213 + "index": 6270 }, "end": { "line": 198, "column": 3, - "index": 6448 + "index": 6505 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json b/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json index 0ab336ea48..dfce23b8b3 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Delegate", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 194, + "line": 197, "column": 23, - "index": 6300 + "index": 6357 }, "end": { - "line": 197, + "line": 200, "column": 3, - "index": 6414 + "index": 6471 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!of fees", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 198, + "line": 201, "column": 10, - "index": 6426 + "index": 6483 }, "end": { - "line": 201, + "line": 204, "column": 3, - "index": 6526 + "index": 6583 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Current approximation of rewards that you will receive per epoch:", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 202, + "line": 205, "column": 22, - "index": 6550 + "index": 6607 }, "end": { - "line": 205, + "line": 208, "column": 3, - "index": 6720 + "index": 6777 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Unknown pool", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 206, + "line": 209, "column": 15, - "index": 6737 + "index": 6794 }, "end": { - "line": 209, + "line": 212, "column": 3, - "index": 6856 + "index": 6913 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/yoroi-wallets/utils/format.json b/apps/wallet-mobile/translations/messages/src/yoroi-wallets/utils/format.json index 94db0a6297..778a15c87c 100644 --- a/apps/wallet-mobile/translations/messages/src/yoroi-wallets/utils/format.json +++ b/apps/wallet-mobile/translations/messages/src/yoroi-wallets/utils/format.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Today", "file": "src/yoroi-wallets/utils/format.ts", "start": { - "line": 237, + "line": 242, "column": 9, - "index": 7555 + "index": 7729 }, "end": { - "line": 240, + "line": 245, "column": 3, - "index": 7622 + "index": 7796 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Yesterday", "file": "src/yoroi-wallets/utils/format.ts", "start": { - "line": 241, + "line": 246, "column": 13, - "index": 7637 + "index": 7811 }, "end": { - "line": 244, + "line": 249, "column": 3, - "index": 7712 + "index": 7886 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!![Unknown asset name]", "file": "src/yoroi-wallets/utils/format.ts", "start": { - "line": 245, + "line": 250, "column": 20, - "index": 7734 + "index": 7908 }, "end": { - "line": 248, + "line": 253, "column": 3, - "index": 7827 + "index": 8001 } } ] \ No newline at end of file From 4edb93572e728ed6439e96bbda310c995458f07f Mon Sep 17 00:00:00 2001 From: jorbuedo Date: Mon, 16 Sep 2024 12:34:16 +0200 Subject: [PATCH 3/4] feature(wallet-mobile): update how portfolio token list does privacy (#3632) --- .../src/components/Icon/Change.tsx | 17 ++++++++ .../src/components/Icon/Icon.stories.tsx | 2 + .../src/components/Icon/index.ts | 2 + .../TokenBalanceItem.tsx | 5 ++- .../TotalTokensValue/TokenValueBalance.tsx | 42 ++++++++----------- .../TokenValuePairedBalance.tsx | 9 +++- .../TotalTokensValueContent.tsx | 37 ++++++++++------ 7 files changed, 74 insertions(+), 40 deletions(-) create mode 100644 apps/wallet-mobile/src/components/Icon/Change.tsx diff --git a/apps/wallet-mobile/src/components/Icon/Change.tsx b/apps/wallet-mobile/src/components/Icon/Change.tsx new file mode 100644 index 0000000000..8148badfb6 --- /dev/null +++ b/apps/wallet-mobile/src/components/Icon/Change.tsx @@ -0,0 +1,17 @@ +import * as React from 'react' +import Svg, {Path} from 'react-native-svg' + +type Props = { + color?: string +} + +export const Change = ({color = 'black'}: Props) => { + return ( + + + + ) +} diff --git a/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx b/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx index 5ec61fb260..6e504dc369 100644 --- a/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx +++ b/apps/wallet-mobile/src/components/Icon/Icon.stories.tsx @@ -115,6 +115,8 @@ storiesOf('Icon', module).add('Gallery', () => { } title="Plus Circle" /> + } title="Change" /> + } title="Check Filled" /> } title="Check Outlined" /> diff --git a/apps/wallet-mobile/src/components/Icon/index.ts b/apps/wallet-mobile/src/components/Icon/index.ts index 65dd2254bf..37bb92c860 100644 --- a/apps/wallet-mobile/src/components/Icon/index.ts +++ b/apps/wallet-mobile/src/components/Icon/index.ts @@ -14,6 +14,7 @@ import {Burger} from './Burger' import {Cardano} from './Cardano' import {Catalyst} from './Catalyst' import {Categories} from './Categories' +import {Change} from './Change' import {Check} from './Check' import {Checkbox} from './Checkbox' import {CheckFilled} from './CheckFilled' @@ -154,6 +155,7 @@ export const Icon = { Cardano, Catalyst, Categories, + Change, Check, Checkbox, CheckFilled, diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/TokenBalanceItem.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/TokenBalanceItem.tsx index ea6214c7b1..6fce3be405 100644 --- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/TokenBalanceItem.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/PortfolioWalletTokenList/TokenBalanceItem.tsx @@ -7,6 +7,7 @@ import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' import {Spacer} from '../../../../../components' import {PairedBalance} from '../../../../../components/PairedBalance/PairedBalance' import {useCurrencyPairing} from '../../../../Settings/Currency' +import {usePrivacyMode} from '../../../../Settings/PrivacyMode/PrivacyMode' import {formatPriceChange, priceChange} from '../../../common/helpers/priceChange' import {useNavigateTo} from '../../../common/hooks/useNavigateTo' import {PnlTag} from '../../../common/PnlTag/PnlTag' @@ -19,10 +20,12 @@ type Props = { export const TokenBalanceItem = ({amount}: Props) => { const {styles} = useStyles() const navigationTo = useNavigateTo() + const {isPrivacyActive, privacyPlaceholder} = usePrivacyMode() + const {info} = amount const name = infoExtractName(info) const symbol = infoExtractName(info, {mode: 'currency'}) - const balanceFormatted = amountBreakdown(amount).bn.toFormat(2) + const balanceFormatted = isPrivacyActive ? privacyPlaceholder : amountBreakdown(amount).bn.toFormat(2) const ptActivity = useCurrencyPairing().ptActivity diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValueBalance.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValueBalance.tsx index 999dd155a9..1e885f3801 100644 --- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValueBalance.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValueBalance.tsx @@ -5,6 +5,7 @@ import * as React from 'react' import {StyleSheet, Text, View} from 'react-native' import {useCurrencyPairing} from '../../../../Settings/Currency' +import {usePrivacyMode} from '../../../../Settings/PrivacyMode/PrivacyMode' import {SkeletonPrimaryToken} from './SkeletonPrimaryToken' type Props = { @@ -14,30 +15,26 @@ type Props = { rate?: number } export const TokenValueBalance = ({amount, isFetching, isPrimaryTokenActive, rate}: Props) => { - const {currency} = useCurrencyPairing() + const {currency, config} = useCurrencyPairing() + const {isPrivacyActive, privacyPlaceholder} = usePrivacyMode() const {styles} = useStyles() const name = infoExtractName(amount.info) - const renderBalance = () => { - if (isFetching || rate === undefined) return - if (!isPrimaryTokenActive) - return {amountBreakdown(amount).bn.times(rate).toFormat(2)} - - return {amountBreakdown(amount).bn.toFormat(2)} - } - - const firstSymbol = isPrimaryTokenActive ? name : currency - const secondSymbol = isPrimaryTokenActive ? currency : name - return ( - {renderBalance()} - - - {firstSymbol} - - /{secondSymbol} - + {isFetching || rate === undefined ? ( + + ) : ( + + {isPrivacyActive + ? privacyPlaceholder + : isPrimaryTokenActive + ? amountBreakdown(amount).bn.toFormat(2) + : amountBreakdown(amount).bn.times(rate).toFormat(config.decimals)} + + )} + + {isPrimaryTokenActive ? name : currency} ) } @@ -55,16 +52,11 @@ const useStyles = () => { ...atoms.font_semibold, color: color.text_gray_medium, }, - firstSymbol: { + symbol: { ...atoms.body_1_lg_medium, ...atoms.font_semibold, color: color.text_gray_medium, }, - secondSymbol: { - ...atoms.body_1_lg_medium, - ...atoms.font_semibold, - color: color.text_gray_low, - }, }) return {styles} as const diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValuePairedBalance.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValuePairedBalance.tsx index f0ef35ac46..a32669d6c6 100644 --- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValuePairedBalance.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TokenValuePairedBalance.tsx @@ -5,6 +5,7 @@ import * as React from 'react' import {StyleSheet, Text} from 'react-native' import {PairedBalance} from '../../../../../components/PairedBalance/PairedBalance' +import {usePrivacyMode} from '../../../../Settings/PrivacyMode/PrivacyMode' import {SkeletonPairedToken} from './SkeletonPairedToken' type Props = { @@ -14,11 +15,17 @@ type Props = { } export const TokenValuePairedBalance = ({amount, isFetching, isPrimaryTokenActive}: Props) => { const {styles} = useStyles() + const {isPrivacyActive, privacyPlaceholder} = usePrivacyMode() + const name = infoExtractName(amount.info) if (isFetching) return if (isPrimaryTokenActive) return - return {`${amountBreakdown(amount).bn.toFormat(2)} ${name}`} + return ( + {`${ + isPrivacyActive ? privacyPlaceholder : amountBreakdown(amount).bn.toFormat(2) + } ${name}`} + ) } const useStyles = () => { diff --git a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TotalTokensValueContent.tsx b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TotalTokensValueContent.tsx index 9fb79e300d..596c39adf0 100644 --- a/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TotalTokensValueContent.tsx +++ b/apps/wallet-mobile/src/features/Portfolio/useCases/PortfolioTokensList/TotalTokensValue/TotalTokensValueContent.tsx @@ -3,8 +3,9 @@ import {Portfolio} from '@yoroi/types' import * as React from 'react' import {StyleSheet, Text, TouchableOpacity, View} from 'react-native' -import {Spacer} from '../../../../../components' +import {Icon, Spacer} from '../../../../../components' import {useCurrencyPairing} from '../../../../Settings/Currency' +import {usePrivacyMode} from '../../../../Settings/PrivacyMode/PrivacyMode' import {formatPriceChange, priceChange} from '../../../common/helpers/priceChange' import {PnlTag} from '../../../common/PnlTag/PnlTag' import {usePortfolio} from '../../../common/PortfolioProvider' @@ -18,7 +19,7 @@ type Props = { } export const TotalTokensValueContent = ({amount, headerCard}: Props) => { - const {styles} = useStyles() + const {styles, color} = useStyles() const { currency, config, @@ -26,6 +27,7 @@ export const TotalTokensValueContent = ({amount, headerCard}: Props) => { isLoading, } = useCurrencyPairing() const {isPrimaryTokenActive, setIsPrimaryTokenActive} = usePortfolio() + const {togglePrivacyMode} = usePrivacyMode() const {changePercent, changeValue, variantPnl} = priceChange(open, close) @@ -36,14 +38,20 @@ export const TotalTokensValueContent = ({amount, headerCard}: Props) => { - setIsPrimaryTokenActive(!isPrimaryTokenActive)}> - - + + togglePrivacyMode()}> + + + + setIsPrimaryTokenActive(!isPrimaryTokenActive)}> + + + @@ -75,7 +83,7 @@ export const TotalTokensValueContent = ({amount, headerCard}: Props) => { } const useStyles = () => { - const {atoms} = useTheme() + const {atoms, color} = useTheme() const styles = StyleSheet.create({ rowBetween: { ...atoms.flex_row, @@ -85,11 +93,14 @@ const useStyles = () => { balanceBox: { ...atoms.flex_row, ...atoms.gap_2xs, - ...atoms.align_center, + ...atoms.align_end, }, balanceContainer: { ...atoms.gap_2xs, }, + button: { + ...atoms.p_sm, + }, varyContainer: { ...atoms.flex_row, ...atoms.gap_xs, @@ -97,5 +108,5 @@ const useStyles = () => { }, }) - return {styles} as const + return {styles, color} as const } From 04fb19cbbc5b6e788f0061ce5fed5a7f51cf0245 Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:25:41 +0100 Subject: [PATCH 4/4] refactor(wallet-mobile): network legacy drop stage - 3 (#3633) --- .../common/InsufficientFundsModal.tsx | 2 +- .../features/RegisterCatalyst/common/hooks.ts | 2 +- .../SaveReadOnlyWalletScreen.tsx | 6 +- .../ConnectNanoXScreen.stories.tsx | 12 +- .../adapters/cardano}/cardano-config.ts | 16 +- .../adapters/cardano}/catalyst-config.ts | 0 .../WalletManager/common/derivation-config.ts | 18 ++ .../network-manager/helpers/epoch-progress.ts | 2 +- .../helpers/get-wallet-factory.ts | 19 +- .../network-manager/network-manager.ts | 19 +- .../src/legacy/Dashboard/Dashboard.tsx | 50 ++--- .../DelegationConfirmation.tsx | 27 +-- .../Staking/StakingCenter/StakingCenter.tsx | 7 +- .../account-manager/account-manager.ts | 9 +- .../cardano/assetUtils/assetUtils.ts | 5 +- .../bip44Validators/bip44Validators.ts | 7 +- .../yoroi-wallets/cardano/cardano-wallet.ts | 47 ++--- .../cardano/cip30/cip30-ledger.ts | 2 +- .../src/yoroi-wallets/cardano/cip95/cip95.ts | 2 +- .../cardano/common/signatureUtils.ts | 12 +- .../yoroi-wallets/cardano/constants/common.ts | 27 --- .../cardano/constants/mainnet/constants.ts | 77 ------- .../cardano/constants/sanchonet/constants.ts | 78 ------- .../cardano/constants/testnet/constants.ts | 76 ------- .../derivation-path-manager.ts | 2 +- .../cardano/getMinAmounts.test.ts | 15 +- .../yoroi-wallets/cardano/getMinAmounts.ts | 9 +- .../cardano/getTime/getTime.test.ts | 28 --- .../yoroi-wallets/cardano/getTime/getTime.ts | 24 --- .../yoroi-wallets/cardano/getTime/index.ts | 1 - .../src/yoroi-wallets/cardano/hw/hw.ts | 5 +- .../cardano/key-manager/key-manager.ts | 5 +- .../cardano/mnemonic/mnemonic.ts | 5 +- .../src/yoroi-wallets/cardano/networks.ts | 128 ------------ .../src/yoroi-wallets/cardano/numbers.ts | 30 --- .../src/yoroi-wallets/cardano/utils.ts | 34 +-- .../src/yoroi-wallets/hooks/index.ts | 2 +- .../src/yoroi-wallets/mocks/wallet.ts | 6 +- .../src/yoroi-wallets/utils/timeUtils.ts | 193 ++---------------- .../SaveReadOnlyWalletScreen.json | 40 ++-- .../src/legacy/Dashboard/Dashboard.json | 8 +- .../DelegationConfirmation.json | 32 +-- .../Staking/StakingCenter/StakingCenter.json | 16 +- .../cardano/api/cardano-api-maker.mocks.ts | 2 +- .../api/src/cardano/api/cardano-api-maker.ts | 2 +- packages/types/src/api/cardano.ts | 11 - packages/types/src/chain/cardano.ts | 13 ++ packages/types/src/index.ts | 7 +- packages/types/src/network/manager.ts | 24 ++- 49 files changed, 245 insertions(+), 919 deletions(-) rename apps/wallet-mobile/src/{yoroi-wallets/cardano/constants => features/WalletManager/common/adapters/cardano}/cardano-config.ts (86%) rename apps/wallet-mobile/src/{yoroi-wallets/cardano/constants => features/WalletManager/common/adapters/cardano}/catalyst-config.ts (100%) create mode 100644 apps/wallet-mobile/src/features/WalletManager/common/derivation-config.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/constants/common.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.test.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/index.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/networks.ts delete mode 100644 apps/wallet-mobile/src/yoroi-wallets/cardano/numbers.ts diff --git a/apps/wallet-mobile/src/features/RegisterCatalyst/common/InsufficientFundsModal.tsx b/apps/wallet-mobile/src/features/RegisterCatalyst/common/InsufficientFundsModal.tsx index b528ef493b..7b205aba8c 100644 --- a/apps/wallet-mobile/src/features/RegisterCatalyst/common/InsufficientFundsModal.tsx +++ b/apps/wallet-mobile/src/features/RegisterCatalyst/common/InsufficientFundsModal.tsx @@ -7,8 +7,8 @@ import {Platform, StyleSheet, Text, View} from 'react-native' import {Button, useModal} from '../../../components' import {Space} from '../../../components/Space/Space' import globalMessages, {confirmationMessages} from '../../../kernel/i18n/global-messages' -import {catalystConfig} from '../../../yoroi-wallets/cardano/constants/catalyst-config' import {usePortfolioPrimaryBalance} from '../../Portfolio/common/hooks/usePortfolioPrimaryBalance' +import {catalystConfig} from '../../WalletManager/common/adapters/cardano/catalyst-config' import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' const formatter = amountFormatter({template: `{{value}} {{ticker}}`, dropTraillingZeros: true}) diff --git a/apps/wallet-mobile/src/features/RegisterCatalyst/common/hooks.ts b/apps/wallet-mobile/src/features/RegisterCatalyst/common/hooks.ts index bb92df80f5..f512f82ed3 100644 --- a/apps/wallet-mobile/src/features/RegisterCatalyst/common/hooks.ts +++ b/apps/wallet-mobile/src/features/RegisterCatalyst/common/hooks.ts @@ -6,10 +6,10 @@ import {useQuery, UseQueryOptions} from 'react-query' import {time} from '../../../kernel/constants' import {throwLoggedError} from '../../../kernel/logger/helpers/throw-logged-error' import {queryInfo} from '../../../kernel/query-client' -import {catalystConfig} from '../../../yoroi-wallets/cardano/constants/catalyst-config' import {YoroiWallet} from '../../../yoroi-wallets/cardano/types' import {isShelley} from '../../../yoroi-wallets/cardano/utils' import {usePortfolioPrimaryBalance} from '../../Portfolio/common/hooks/usePortfolioPrimaryBalance' +import {catalystConfig} from '../../WalletManager/common/adapters/cardano/catalyst-config' import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' export const useCanVote = (wallet: YoroiWallet) => { diff --git a/apps/wallet-mobile/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx b/apps/wallet-mobile/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx index e656392ec6..d29f585b6b 100644 --- a/apps/wallet-mobile/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx +++ b/apps/wallet-mobile/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx @@ -15,8 +15,8 @@ import {logger} from '../../../../kernel/logger/logger' import {useMetrics} from '../../../../kernel/metrics/metricsManager' import {SetupWalletRouteNavigation} from '../../../../kernel/navigation' import {isEmptyString} from '../../../../kernel/utils' -import {NUMBERS} from '../../../../yoroi-wallets/cardano/numbers' import {usePlate} from '../../../../yoroi-wallets/hooks' +import {derivationConfig} from '../../../WalletManager/common/derivation-config' import {useCreateWalletXPub} from '../../../WalletManager/common/hooks/useCreateWalletXPub' import {useSelectedNetwork} from '../../../WalletManager/common/hooks/useSelectedNetwork' import {parseWalletMeta} from '../../../WalletManager/common/validators/wallet-meta' @@ -35,9 +35,7 @@ export const SaveReadOnlyWalletScreen = () => { const {publicKeyHex, path, walletImplementation, accountVisual, walletIdChanged} = useSetupWallet() const normalizedPath = path.map((i) => { - if (i >= NUMBERS.HARD_DERIVATION_START) { - return i - NUMBERS.HARD_DERIVATION_START - } + if (i >= derivationConfig.hardStart) return i - derivationConfig.hardStart return i }) diff --git a/apps/wallet-mobile/src/features/SetupWallet/useCases/RestoreHwWallet/ConnectNanoXScreen.stories.tsx b/apps/wallet-mobile/src/features/SetupWallet/useCases/RestoreHwWallet/ConnectNanoXScreen.stories.tsx index 7905f77d97..a07b32418e 100644 --- a/apps/wallet-mobile/src/features/SetupWallet/useCases/RestoreHwWallet/ConnectNanoXScreen.stories.tsx +++ b/apps/wallet-mobile/src/features/SetupWallet/useCases/RestoreHwWallet/ConnectNanoXScreen.stories.tsx @@ -1,8 +1,8 @@ import {NavigationRouteContext} from '@react-navigation/native' import {storiesOf} from '@storybook/react-native' -import React from 'react' +import * as React from 'react' -import {NETWORK_ID, WALLET_IMPLEMENTATION_ID} from '../../../../yoroi-wallets/cardano/constants/testnet/constants' +import {networkConfigs} from '../../../WalletManager/network-manager/network-manager' import {ConnectNanoXScreen} from './ConnectNanoXScreen' const devices = [ @@ -18,8 +18,8 @@ const bleRoute = { name: 'name', params: { useUSB: false, - networkId: NETWORK_ID, - walletImplementationId: WALLET_IMPLEMENTATION_ID, + networkId: networkConfigs['mainnet'].chainId, + walletImplementationId: 'cardano-bip44', }, } @@ -28,8 +28,8 @@ const usbRoute = { name: 'name', params: { useUSB: true, - networkId: NETWORK_ID, - walletImplementationId: WALLET_IMPLEMENTATION_ID, + networkId: networkConfigs['mainnet'].chainId, + walletImplementationId: 'cardano-bip44', }, } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/cardano-config.ts b/apps/wallet-mobile/src/features/WalletManager/common/adapters/cardano/cardano-config.ts similarity index 86% rename from apps/wallet-mobile/src/yoroi-wallets/cardano/constants/cardano-config.ts rename to apps/wallet-mobile/src/features/WalletManager/common/adapters/cardano/cardano-config.ts index b5fa54b2aa..a1a115ada2 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/cardano-config.ts +++ b/apps/wallet-mobile/src/features/WalletManager/common/adapters/cardano/cardano-config.ts @@ -8,19 +8,9 @@ export const cardanoConfig = freeze( params: { minUtxoValue: 1_000_000n, }, - derivation: { - gapLimit: 20, - hardStart: 2_147_483_648, - keyLevel: { - root: 0, - purpose: 1, - coinType: 2, - account: 3, - role: 4, - index: 5, - }, - }, implementations: { + // after shelley + // https://cips.cardano.org/cip/CIP-1852 'cardano-cip1852': { features: { staking: { @@ -52,6 +42,8 @@ export const cardanoConfig = freeze( }, }, }, + // byron + // https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki 'cardano-bip44': { features: { staking: false, diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/catalyst-config.ts b/apps/wallet-mobile/src/features/WalletManager/common/adapters/cardano/catalyst-config.ts similarity index 100% rename from apps/wallet-mobile/src/yoroi-wallets/cardano/constants/catalyst-config.ts rename to apps/wallet-mobile/src/features/WalletManager/common/adapters/cardano/catalyst-config.ts diff --git a/apps/wallet-mobile/src/features/WalletManager/common/derivation-config.ts b/apps/wallet-mobile/src/features/WalletManager/common/derivation-config.ts new file mode 100644 index 0000000000..05738cef68 --- /dev/null +++ b/apps/wallet-mobile/src/features/WalletManager/common/derivation-config.ts @@ -0,0 +1,18 @@ +import {freeze} from 'immer' + +// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +export const derivationConfig = freeze( + { + gapLimit: 20, + hardStart: 2_147_483_648, + keyLevel: { + root: 0, + purpose: 1, + coinType: 2, + account: 3, + role: 4, + index: 5, + }, + } as const, + true, +) diff --git a/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/epoch-progress.ts b/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/epoch-progress.ts index d7da3769e5..d412bce685 100644 --- a/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/epoch-progress.ts +++ b/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/epoch-progress.ts @@ -2,7 +2,7 @@ import {Network} from '@yoroi/types' import {freeze} from 'immer' export function epochProgress(epochInfo: Network.EpochInfo) { - return (date: Date) => { + return (date: Date): Readonly => { const epochStart = epochInfo.start const epochEnd = epochInfo.end diff --git a/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/get-wallet-factory.ts b/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/get-wallet-factory.ts index a577281281..bee0c71573 100644 --- a/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/get-wallet-factory.ts +++ b/apps/wallet-mobile/src/features/WalletManager/network-manager/helpers/get-wallet-factory.ts @@ -3,20 +3,17 @@ import {freeze} from 'immer' import {throwLoggedError} from '../../../../kernel/logger/helpers/throw-logged-error' import {makeCardanoWallet} from '../../../../yoroi-wallets/cardano/cardano-wallet' -import * as MAINNET from '../../../../yoroi-wallets/cardano/constants/mainnet/constants' -import * as SANCHONET from '../../../../yoroi-wallets/cardano/constants/sanchonet/constants' -import * as TESTNET from '../../../../yoroi-wallets/cardano/constants/testnet/constants' import {networkManagers} from '../../common/constants' import {WalletFactory} from '../../common/types' -const ShelleyWalletMainnet = makeCardanoWallet(networkManagers[Chain.Network.Mainnet], 'cardano-cip1852', MAINNET) -const ShelleyWalletTestnet = makeCardanoWallet(networkManagers[Chain.Network.Preprod], 'cardano-cip1852', TESTNET) -const ShelleySanchonetWallet = makeCardanoWallet(networkManagers[Chain.Network.Sancho], 'cardano-cip1852', SANCHONET) -const ShelleyPreviewWallet = makeCardanoWallet(networkManagers[Chain.Network.Preview], 'cardano-cip1852', SANCHONET) -const ByronWallet = makeCardanoWallet(networkManagers[Chain.Network.Mainnet], 'cardano-bip44', MAINNET) -const ByronWalletTestnet = makeCardanoWallet(networkManagers[Chain.Network.Preprod], 'cardano-bip44', TESTNET) -const ByronSanchonetWallet = makeCardanoWallet(networkManagers[Chain.Network.Sancho], 'cardano-bip44', SANCHONET) -const ByronPreviewWallet = makeCardanoWallet(networkManagers[Chain.Network.Preview], 'cardano-bip44', SANCHONET) +const ShelleyWalletMainnet = makeCardanoWallet(networkManagers[Chain.Network.Mainnet], 'cardano-cip1852') +const ShelleyWalletTestnet = makeCardanoWallet(networkManagers[Chain.Network.Preprod], 'cardano-cip1852') +const ShelleySanchonetWallet = makeCardanoWallet(networkManagers[Chain.Network.Sancho], 'cardano-cip1852') +const ShelleyPreviewWallet = makeCardanoWallet(networkManagers[Chain.Network.Preview], 'cardano-cip1852') +const ByronWallet = makeCardanoWallet(networkManagers[Chain.Network.Mainnet], 'cardano-bip44') +const ByronWalletTestnet = makeCardanoWallet(networkManagers[Chain.Network.Preprod], 'cardano-bip44') +const ByronSanchonetWallet = makeCardanoWallet(networkManagers[Chain.Network.Sancho], 'cardano-bip44') +const ByronPreviewWallet = makeCardanoWallet(networkManagers[Chain.Network.Preview], 'cardano-bip44') /** * Retrieves the wallet factory based on the network and implementation ID diff --git a/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts b/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts index 0467b5a669..bf9c9c4f04 100644 --- a/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts +++ b/apps/wallet-mobile/src/features/WalletManager/network-manager/network-manager.ts @@ -7,6 +7,8 @@ import {freeze} from 'immer' import {logger} from '../../../kernel/logger/logger' import {NetworkTokenManagers} from '../common/types' +import {dateToEpochInfo} from './helpers/date-to-epoch-info' +import {epochProgress} from './helpers/epoch-progress' export const primaryTokenInfoMainnet = createPrimaryTokenInfo({ decimals: 6, @@ -65,7 +67,7 @@ export const shelleyPreprodEraConfig: Readonly = freeze( true, ) -export const protocolParamsPlaceholder = freeze({ +export const protocolParamsPlaceholder: Chain.Cardano.ProtocolParams = freeze({ linearFee: { constant: '155381', coefficient: '44', @@ -129,7 +131,6 @@ export function buildNetworkManagers({ }: { tokenManagers: NetworkTokenManagers }): Readonly> { - // TODO: receive and attach the explorers here as well const managers = Object.entries(networkConfigs).reduce>( (networkManagers, [network, config]) => { const tokenManager = tokenManagers[network as Chain.SupportedNetworks] @@ -140,11 +141,20 @@ export function buildNetworkManagers({ const api = { protocolParams: () => getProtocolParams().catch((error) => { - logger.error(`networkManager: ${network} protocolParams has failed`, {error}) - return protocolParamsPlaceholder + logger.error(`networkManager: ${network} protocolParams has failed, using hardcoded`, {error}) + return Promise.resolve(protocolParamsPlaceholder) }), } + const info = dateToEpochInfo(config.eras) + const epoch = { + info, + progress: (date: Date) => { + const currentInfo = info(date) + return epochProgress(currentInfo)(date) + }, + } + const networkManager: Network.Manager = { ...config, tokenManager, @@ -153,6 +163,7 @@ export function buildNetworkManagers({ legacyRootStorage, api, explorers: explorerManager[network as Chain.SupportedNetworks], + epoch, } networkManagers[network as Chain.SupportedNetworks] = networkManager diff --git a/apps/wallet-mobile/src/legacy/Dashboard/Dashboard.tsx b/apps/wallet-mobile/src/legacy/Dashboard/Dashboard.tsx index eb381d860e..c67b49e1ed 100644 --- a/apps/wallet-mobile/src/legacy/Dashboard/Dashboard.tsx +++ b/apps/wallet-mobile/src/legacy/Dashboard/Dashboard.tsx @@ -12,24 +12,17 @@ import {Banner, Button, useModal} from '../../components' import {Space} from '../../components/Space/Space' import { useGovernanceStrings, + useIsGovernanceFeatureEnabled, useIsParticipatingInGovernance, WithdrawWarningModal, } from '../../features/Staking/Governance' -import {useIsGovernanceFeatureEnabled} from '../../features/Staking/Governance' +import {useSelectedNetwork} from '../../features/WalletManager/common/hooks/useSelectedNetwork' import {useSelectedWallet} from '../../features/WalletManager/common/hooks/useSelectedWallet' import globalMessages from '../../kernel/i18n/global-messages' import {DashboardRoutes, useWalletNavigation} from '../../kernel/navigation' import {isEmptyString} from '../../kernel/utils' -import {getCardanoNetworkConfigById} from '../../yoroi-wallets/cardano/networks' -import {getCardanoBaseConfig} from '../../yoroi-wallets/cardano/utils' import {useBalances, useIsOnline, useSync} from '../../yoroi-wallets/hooks' import {Amounts} from '../../yoroi-wallets/utils' -import { - genCurrentEpochLength, - genCurrentSlotLength, - genTimeToSlot, - genToRelativeSlotNumber, -} from '../../yoroi-wallets/utils/timeUtils' import {PoolTransitionNotice} from '../Staking/PoolTransition/PoolTransitionNotice' import {usePoolTransition} from '../Staking/PoolTransition/usePoolTransition' import {EpochProgress} from './EpochProgress' @@ -204,27 +197,12 @@ const useCurrentTime = () => { const EpochInfo = () => { const currentTime = useCurrentTime() - const {wallet} = useSelectedWallet() - // TODO: revisit drop in favor of epochUtils - const config = getCardanoBaseConfig(getCardanoNetworkConfigById(wallet.isMainnet ? 1 : 300)) - - const toRelativeSlotNumberFn = genToRelativeSlotNumber(config) - const timeToSlotFn = genTimeToSlot(config) - - const currentAbsoluteSlot = timeToSlotFn({ - time: currentTime, - }) - - const currentRelativeTime = toRelativeSlotNumberFn( - timeToSlotFn({ - time: Date.now(), - }).slot, - ) - const epochLength = genCurrentEpochLength(config)() - const slotLength = genCurrentSlotLength(config)() - - const secondsLeftInEpoch = (epochLength - currentRelativeTime.slot) * slotLength - const timeLeftInEpoch = new Date(1000 * secondsLeftInEpoch - currentAbsoluteSlot.msIntoSlot) + const {networkManager} = useSelectedNetwork() + const {epoch} = networkManager.epoch.info(new Date(currentTime)) + const { + timeRemaining: {days, hours, minutes, seconds}, + progress, + } = networkManager.epoch.progress(new Date(currentTime)) const leftPadDate = (num: number) => { if (num < 10) return `0${num}` @@ -233,13 +211,13 @@ const EpochInfo = () => { return ( ) diff --git a/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx b/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx index 6b59fac6ea..eaa1803c13 100644 --- a/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx +++ b/apps/wallet-mobile/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx @@ -1,5 +1,4 @@ import {useTheme} from '@yoroi/theme' -import {Balance} from '@yoroi/types' import React, {useEffect, useState} from 'react' import {defineMessages, useIntl} from 'react-intl' import {Platform, ScrollView, StyleSheet, View} from 'react-native' @@ -12,10 +11,8 @@ import {useSelectedWallet} from '../../../features/WalletManager/common/hooks/us import {debugWalletInfo, features} from '../../../kernel/features' import globalMessages, {txLabels} from '../../../kernel/i18n/global-messages' import {StakingCenterRoutes, useParams, useWalletNavigation} from '../../../kernel/navigation' -import {NETWORKS} from '../../../yoroi-wallets/cardano/networks' -import {NUMBERS} from '../../../yoroi-wallets/cardano/numbers' -import {Amounts, Entries, Quantities} from '../../../yoroi-wallets/utils' -import {formatTokenAmount, formatTokenWithText} from '../../../yoroi-wallets/utils/format' +import {Amounts, Entries} from '../../../yoroi-wallets/utils' +import {formatTokenAmount} from '../../../yoroi-wallets/utils/format' import {useStakePoolInfoAndHistory} from '../../Dashboard/StakePoolInfo' import {Instructions as HWInstructions} from '../../HW' @@ -45,8 +42,6 @@ export const DelegationConfirmation = () => { Entries.toAmounts(yoroiUnsignedTx.staking.delegations), wallet.portfolioPrimaryTokenInfo.id, ) - const reward = approximateReward(stakingAmount.quantity) - const [password, setPassword] = useState('') const [useUSB, setUseUSB] = useState(false) @@ -104,8 +99,6 @@ export const DelegationConfirmation = () => { {strings.rewardsExplanation} - - {formatTokenWithText(reward, wallet.portfolioPrimaryTokenInfo)} {meta.isHW && } @@ -166,10 +159,6 @@ const useStyles = () => { color: color.gray_900, ...atoms.body_2_md_regular, }, - rewards: { - ...atoms.body_1_lg_medium, - color: color.primary_600, - }, fees: { textAlign: 'right', color: color.gray_900, @@ -211,15 +200,3 @@ const messages = defineMessages({ defaultMessage: '!!!Unknown pool', }, }) - -/** - * returns approximate rewards per epoch in lovelaces - * TODO: based on https://staking.cardano.org/en/calculator/ - * needs to be update per-network - */ -const approximateReward = (stakedQuantity: Balance.Quantity): Balance.Quantity => { - return Quantities.quotient( - Quantities.product([stakedQuantity, `${NETWORKS.HASKELL_SHELLEY.PER_EPOCH_PERCENTAGE_REWARD}`]), - NUMBERS.EPOCH_REWARD_DENOMINATOR.toString() as Balance.Quantity, - ) -} diff --git a/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx b/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx index 27835ebf49..e3a0374e79 100644 --- a/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx +++ b/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx @@ -15,7 +15,6 @@ import globalMessages from '../../../kernel/i18n/global-messages' import {logger} from '../../../kernel/logger/logger' import {useMetrics} from '../../../kernel/metrics/metricsManager' import {StakingCenterRouteNavigation} from '../../../kernel/navigation' -import {NETWORKS} from '../../../yoroi-wallets/cardano/networks' import {NotEnoughMoneyToSendError} from '../../../yoroi-wallets/cardano/types' import {useStakingTx} from '../../Dashboard/StakePoolInfos' import {PoolDetailScreen} from '../PoolDetails' @@ -138,13 +137,9 @@ const noPoolDataDialog = defineMessages({ }, }) -/** - * Prepares WebView's target staking URI - * @param {*} poolList : Array of delegated pool hash - */ const prepareStakingURL = (locale: string, plate: string): string => { // source=mobile is constant and already included - let finalURL = NETWORKS.HASKELL_SHELLEY.POOL_EXPLORER + let finalURL = 'https://adapools.yoroiwallet.com/?source=mobile' const lang = locale.slice(0, 2) finalURL += `&lang=${lang}` diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/account-manager/account-manager.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/account-manager/account-manager.ts index 968bb1fa02..13aa0b0e6e 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/account-manager/account-manager.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/account-manager/account-manager.ts @@ -4,13 +4,14 @@ import assert from 'assert' import _ from 'lodash' import {defaultMemoize} from 'reselect' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../../features/WalletManager/common/derivation-config' import {logger} from '../../../kernel/logger/logger' import {CardanoMobile} from '../../wallets' import * as legacyApi from '../api/api' -import {cardanoConfig} from '../constants/cardano-config' import {CardanoTypes} from '../types' -// NOTE: needs refactor, client is reponsible to know when to save +// NOTE: needs full refactor export class AddressGenerator { accountPubKeyHex: string role: number @@ -331,7 +332,7 @@ export const accountManagerMaker = async ({ : new AddressChain( new AddressGenerator(accountPubKeyHex, config.derivations.base.roles.internal, implementation, chainId), addressesPerRequest, - cardanoConfig.derivation.gapLimit, + derivationConfig.gapLimit, ) const externalChain = @@ -340,7 +341,7 @@ export const accountManagerMaker = async ({ : new AddressChain( new AddressGenerator(accountPubKeyHex, config.derivations.base.roles.external, implementation, chainId), addressesPerRequest, - cardanoConfig.derivation.gapLimit, + derivationConfig.gapLimit, ) await internalChain.initialize() diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/assetUtils/assetUtils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/assetUtils/assetUtils.ts index 9fda5c6ebd..9483387161 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/assetUtils/assetUtils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/assetUtils/assetUtils.ts @@ -4,7 +4,6 @@ import BigNumber from 'bignumber.js' import {logger} from '../../../kernel/logger/logger' import {RawUtxo} from '../../types/other' -import {COINS_PER_UTXO_BYTE} from '../constants/common' import {cardanoValueFromRemoteFormat} from '../utils' import {wrappedCsl} from '../wrappedCsl' @@ -14,11 +13,11 @@ const addressPlaceholder = export async function calcLockedDeposit({ rawUtxos, address = addressPlaceholder, - coinsPerUtxoByteStr = COINS_PER_UTXO_BYTE, + coinsPerUtxoByteStr, }: { rawUtxos: RawUtxo[] address?: string - coinsPerUtxoByteStr?: string + coinsPerUtxoByteStr: string }) { const cslLocal = wrappedCsl() const csl = cslLocal.csl diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/bip44Validators/bip44Validators.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/bip44Validators/bip44Validators.ts index 1c84a1ec12..b86768a4d1 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/bip44Validators/bip44Validators.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/bip44Validators/bip44Validators.ts @@ -1,7 +1,7 @@ import assert from 'assert' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' import {CardanoMobile} from '../../wallets' -import {NUMBERS} from '../numbers' const isString = (s: unknown) => typeof s === 'string' || s instanceof String @@ -24,8 +24,9 @@ export const isCIP1852AccountPath = (path: Array): boolean => { // note: allows non-zero accounts return ( path.length === 3 && - (path[0] === NUMBERS.WALLET_TYPE_PURPOSE.CIP1852 || path[0] === 1852) && - (path[1] === NUMBERS.COIN_TYPES.CARDANO || path[1] === 1815) + (path[0] === cardanoConfig.implementations['cardano-cip1852'].derivations.base.harden.purpose || + path[0] === 1852) && + (path[1] === cardanoConfig.implementations['cardano-cip1852'].derivations.base.harden.coinType || path[1] === 1815) ) } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts index 2e5aa30a39..db6d1b8f01 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/cardano-wallet.ts @@ -17,6 +17,8 @@ import {Observable} from 'rxjs' import {buildPortfolioBalanceManager} from '../../features/Portfolio/common/helpers/build-balance-manager' import {toBalanceManagerSyncArgs} from '../../features/Portfolio/common/transformers/toBalanceManagerSyncArgs' import {makeMemosManager, MemosManager} from '../../features/Transactions/common/memos/memosManager' +import {cardanoConfig} from '../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../features/WalletManager/common/derivation-config' import {protocolParamsPlaceholder} from '../../features/WalletManager/network-manager/network-manager' import LocalizableError from '../../kernel/i18n/LocalizableError' import {throwLoggedError} from '../../kernel/logger/helpers/throw-logged-error' @@ -41,12 +43,7 @@ import {AccountManager, accountManagerMaker, Addresses} from './account-manager/ import * as legacyApi from './api/api' import {calcLockedDeposit} from './assetUtils' import {createSwapCancellationLedgerPayload} from './common/signatureUtils' -import {cardanoConfig} from './constants/cardano-config' -import * as MAINNET from './constants/mainnet/constants' -import * as SANCHONET from './constants/sanchonet/constants' -import * as TESTNET from './constants/testnet/constants' import {filterAddressesByStakingKey, getDelegationStatus} from './delegationUtils' -import {getTime} from './getTime' import { doesCardanoAppVersionSupportCIP36, doesCardanoAppVersionSupportCIP1694, @@ -73,19 +70,11 @@ import {deriveRewardAddressHex, toRecipients} from './utils' import {makeUtxoManager, UtxoManager} from './utxoManager' import {utxosMaker} from './utxoManager/utxos' -export const makeCardanoWallet = ( - networkManager: Network.Manager, - implementation: Wallet.Implementation, - // legacy - constants: typeof MAINNET | typeof TESTNET | typeof SANCHONET, -) => { +export const makeCardanoWallet = (networkManager: Network.Manager, implementation: Wallet.Implementation) => { const implementationConfig = cardanoConfig.implementations[implementation] const appApi = AppApi.appApiMaker({baseUrl: networkManager.legacyApiBaseUrl}) - // legacy - const {PRIMARY_TOKEN} = constants - return class CardanoWallet implements YoroiWallet { readonly id: string @@ -296,13 +285,13 @@ export const makeCardanoWallet = ( } getAddressing(address: string) { - const startLevel = cardanoConfig.derivation.keyLevel.purpose + const startLevel = derivationConfig.keyLevel.purpose if (this.internalChain.isMyAddress(address)) { const path = [ implementationConfig.derivations.base.harden.purpose, implementationConfig.derivations.base.harden.coinType, - this.accountVisual + cardanoConfig.derivation.hardStart, + this.accountVisual + derivationConfig.hardStart, implementationConfig.derivations.base.roles.internal, this.internalChain.getIndexOfAddress(address), ] @@ -316,7 +305,7 @@ export const makeCardanoWallet = ( const path = [ implementationConfig.derivations.base.harden.purpose, implementationConfig.derivations.base.harden.coinType, - this.accountVisual + cardanoConfig.derivation.hardStart, + this.accountVisual + derivationConfig.hardStart, implementationConfig.derivations.base.roles.external, this.externalChain.getIndexOfAddress(address), ] @@ -388,7 +377,7 @@ export const makeCardanoWallet = ( .catch(() => Date.now()) const primaryTokenId = this.portfolioPrimaryTokenInfo.id - const absSlotNumber = new BigNumber(getTime(time).absoluteSlot) + const absSlotNumber = new BigNumber(this.networkManager.epoch.progress(new Date(time)).currentSlot) const changeAddr = this.getAddressedChangeAddress(addressMode) const addressedUtxos = await this.getAddressedUtxos() const registrationStatus = this.getDelegationStatus().isRegistered @@ -453,7 +442,7 @@ export const makeCardanoWallet = ( .then(({serverTime}) => serverTime || Date.now()) .catch(() => Date.now()) - const absSlotNumber = new BigNumber(getTime(time).absoluteSlot) + const absSlotNumber = new BigNumber(this.networkManager.epoch.progress(new Date(time)).currentSlot) const votingPublicKey = await Promise.resolve(Buffer.from(catalystKeyHex, 'hex')) .then((bytes) => CardanoMobile.PrivateKey.fromExtendedBytes(bytes)) .then((key) => key.toPublic()) @@ -486,7 +475,7 @@ export const makeCardanoWallet = ( const unsignedTx = await Cardano.createUnsignedVotingTx( absSlotNumber, - PRIMARY_TOKEN, + toLibToken(this.portfolioPrimaryTokenInfo), votingPublicKey, Array.from(implementationConfig.features.staking.addressing), stakingPublicKey, @@ -545,7 +534,7 @@ export const makeCardanoWallet = ( .catch(() => Date.now()) const primaryTokenId = this.portfolioPrimaryTokenInfo.id - const absSlotNumber = new BigNumber(getTime(time).absoluteSlot) + const absSlotNumber = new BigNumber(this.networkManager.epoch.progress(new Date(time)).currentSlot) const changeAddr = this.getAddressedChangeAddress(addressMode) const addressedUtxos = await this.getAddressedUtxos() const accountState = await legacyApi.getAccountState( @@ -557,14 +546,14 @@ export const makeCardanoWallet = ( const withdrawalTx = await Cardano.createUnsignedWithdrawalTx( accountState, - PRIMARY_TOKEN, + toLibToken(this.portfolioPrimaryTokenInfo), absSlotNumber, addressedUtxos, [ { addressing: { path: Array.from(implementationConfig.features.staking.addressing), - startLevel: cardanoConfig.derivation.keyLevel.purpose, + startLevel: derivationConfig.keyLevel.purpose, }, rewardAddress: this.rewardAddressHex, shouldDeregister, @@ -605,7 +594,7 @@ export const makeCardanoWallet = ( .then(({serverTime}) => serverTime || Date.now()) .catch(() => Date.now()) const primaryTokenId = this.portfolioPrimaryTokenInfo.id - const absSlotNumber = new BigNumber(getTime(time).absoluteSlot) + const absSlotNumber = new BigNumber(this.networkManager.epoch.progress(new Date(time)).currentSlot) const changeAddr = this.getAddressedChangeAddress(addressMode) const addressedUtxos = await this.getAddressedUtxos() @@ -783,11 +772,11 @@ export const makeCardanoWallet = ( .then(({serverTime}) => serverTime || Date.now()) .catch(() => Date.now()) const primaryTokenId = this.portfolioPrimaryTokenInfo.id - const absSlotNumber = new BigNumber(getTime(time).absoluteSlot) + const absSlotNumber = new BigNumber(this.networkManager.epoch.progress(new Date(time)).currentSlot) const changeAddr = this.getAddressedChangeAddress(addressMode) const addressedUtxos = await this.getAddressedUtxos() - const recipients = await toRecipients(entries, this.portfolioPrimaryTokenInfo) + const recipients = await toRecipients(entries, this.portfolioPrimaryTokenInfo, this.protocolParams) const containsDatum = recipients.some((recipient) => recipient.datum) @@ -838,7 +827,7 @@ export const makeCardanoWallet = ( const accountPrivateKey = await masterKey .derive(implementationConfig.derivations.base.harden.purpose) .then((key) => key.derive(implementationConfig.derivations.base.harden.coinType)) - .then((key) => key.derive(this.accountVisual + cardanoConfig.derivation.hardStart)) + .then((key) => key.derive(this.accountVisual + derivationConfig.hardStart)) const accountPrivateKeyHex = await accountPrivateKey.asBytes().then(toHex) let stakingPrivateKey @@ -870,7 +859,7 @@ export const makeCardanoWallet = ( if (datumDatas.length > 0) { const signedTx = await unsignedTx.unsignedTx.sign( - cardanoConfig.derivation.keyLevel.account, + derivationConfig.keyLevel.account, accountPrivateKeyHex, new Set(), [], @@ -882,7 +871,7 @@ export const makeCardanoWallet = ( } const signedTx = await unsignedTx.unsignedTx.sign( - cardanoConfig.derivation.keyLevel.account, + derivationConfig.keyLevel.account, accountPrivateKeyHex, new Set(), stakingKeys, diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/cip30/cip30-ledger.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/cip30/cip30-ledger.ts index 32367ea9a7..052688cec3 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/cip30/cip30-ledger.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/cip30/cip30-ledger.ts @@ -4,9 +4,9 @@ import {normalizeToAddress} from '@emurgo/yoroi-lib/dist/internals/utils/address import {HW, Wallet} from '@yoroi/types' import {toLedgerSignRequest} from '../../../features/Discover/common/ledger' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' import type {RawUtxo} from '../../types' import {assertHasAllSigners} from '../common/signatureUtils' -import {cardanoConfig} from '../constants/cardano-config' import {signTxWithLedger} from '../hw' import {CardanoTypes, YoroiWallet} from '../types' import {wrappedCsl} from '../wrappedCsl' diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/cip95/cip95.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/cip95/cip95.ts index 74a9ade5dc..2220362372 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/cip95/cip95.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/cip95/cip95.ts @@ -2,8 +2,8 @@ import {Wallet} from '@yoroi/types' import {WalletImplementation} from '@yoroi/types/lib/typescript/wallet/wallet' import {Buffer} from 'buffer' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' import {cip30ExtensionMaker} from '../cip30/cip30' -import {cardanoConfig} from '../constants/cardano-config' import {YoroiWallet} from '../types' import {wrappedCsl} from '../wrappedCsl' diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts index ae3851caa4..babde53fd8 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/common/signatureUtils.ts @@ -5,10 +5,10 @@ import {Wallet} from '@yoroi/types' import {Buffer} from 'buffer' import _ from 'lodash' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../../features/WalletManager/common/derivation-config' import {throwLoggedError} from '../../../kernel/logger/helpers/throw-logged-error' import {CardanoMobile} from '../../wallets' -import {cardanoConfig} from '../constants/cardano-config' -import {BIP44_DERIVATION_LEVELS, HARD_DERIVATION_START} from '../constants/common' import {YoroiWallet} from '../types' export const createSwapCancellationLedgerPayload = async ( @@ -46,7 +46,7 @@ export const convertBech32ToHex = async (bech32Address: string) => { return Buffer.from(bytes).toString('hex') } -export const harden = (num: number) => HARD_DERIVATION_START + num +export const harden = (num: number) => derivationConfig.hardStart + num export const getRequiredSigners = async ( tx: CSL_TYPES.Transaction, @@ -64,7 +64,7 @@ export const getRequiredSigners = async ( ? Array.from(cardanoConfig.implementations[implementation].features.staking.addressing) : undefined - const startLevel = BIP44_DERIVATION_LEVELS.PURPOSE + const startLevel = derivationConfig.keyLevel.purpose const addressedUtxos = wallet.allUtxos.map((utxo) => ({ txHash: utxo.tx_hash, @@ -118,7 +118,7 @@ export const getDerivationPathForAddress = ( return [ config.derivations.base.harden.purpose, config.derivations.base.harden.coinType, - cardanoConfig.derivation.hardStart + wallet.accountVisual, + derivationConfig.hardStart + wallet.accountVisual, config.derivations.base.roles.external, 0, ] @@ -130,7 +130,7 @@ export const getDerivationPathForAddress = ( return [ config.derivations.base.harden.purpose, config.derivations.base.harden.coinType, - cardanoConfig.derivation.hardStart + wallet.accountVisual, + derivationConfig.hardStart + wallet.accountVisual, role, index, ] diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/common.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/common.ts deleted file mode 100644 index 4e314756f7..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/common.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const WALLET_IMPLEMENTATION_ID = 'haskell-shelley' -export const COIN_TYPE = 2147485463 -export const HARD_DERIVATION_START = 2147483648 -export const CHIMERIC_ACCOUNT = 2 -export const STAKING_KEY_INDEX = 0 - -export const BIP44_DERIVATION_LEVELS = { - ROOT: 0, - PURPOSE: 1, - COIN_TYPE: 2, - ACCOUNT: 3, - CHAIN: 4, - ADDRESS: 5, -} as const - -export const KEY_DEPOSIT = '2000000' -export const POOL_DEPOSIT = '500000000' -export const LINEAR_FEE = { - COEFFICIENT: '44', - CONSTANT: '155381', -} as const - -export const MINIMUM_UTXO_VAL = '1000000' - -export const COINS_PER_UTXO_WORD = '34482' - -export const COINS_PER_UTXO_BYTE = '4310' diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts deleted file mode 100644 index daf47cfd6c..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/mainnet/constants.ts +++ /dev/null @@ -1,77 +0,0 @@ -import {DefaultAsset} from '../../../types' -import {COIN_TYPE, COINS_PER_UTXO_WORD, KEY_DEPOSIT, MINIMUM_UTXO_VAL, POOL_DEPOSIT} from '../common' - -export * from '../common' - -export const NETWORK_ID = 1 // mainnet - -export const CHAIN_NETWORK_ID = 1 - -export const PROTOCOL_MAGIC = 764824073 -export const GENESIS_DATE = '1506203091000' - -export const BYRON_BASE_CONFIG = { - // byron-era - PROTOCOL_MAGIC, - // aka byron network id - START_AT: 0, - GENESIS_DATE, - SLOTS_PER_EPOCH: 21600, - SLOT_DURATION: 20, -} as const - -export const SHELLEY_BASE_CONFIG = { - // shelley-era - START_AT: 208, - SLOTS_PER_EPOCH: 432000, - SLOT_DURATION: 1, -} as const - -export const API_ROOT = 'https://api.yoroiwallet.com/api' -export const TOKEN_INFO_SERVICE = 'https://cdn.yoroiwallet.com' -export const BACKEND = { - API_ROOT, - NFT_STORAGE_URL: 'https://fibo-validated-nft-images.s3.amazonaws.com', - TOKEN_INFO_SERVICE, - FETCH_UTXOS_MAX_ADDRESSES: 50, - TX_HISTORY_MAX_ADDRESSES: 50, - FILTER_USED_MAX_ADDRESSES: 50, - TX_HISTORY_RESPONSE_LIMIT: 50, -} as const - -const CARDANO_BASE_CONFIG = [BYRON_BASE_CONFIG, SHELLEY_BASE_CONFIG] -export const NETWORK_CONFIG = { - BACKEND, - BASE_CONFIG: CARDANO_BASE_CONFIG, - CHAIN_NETWORK_ID: CHAIN_NETWORK_ID.toString(), - COIN_TYPE, - ENABLED: true, - EXPLORER_URL_FOR_ADDRESS: (address: string) => `https://cardanoscan.io/address/${address}`, - EXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 ? `https://cardanoscan.io/token/${fingerprint}` : `https://cardanoscan.io/tokens`, - CEXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 ? `https://cexplorer.io/asset/${fingerprint}` : `https://cexplorer.io/asset`, - EXPLORER_URL_FOR_TX: (txid: string) => `https://cardanoscan.io/transaction/${txid}`, - POOL_EXPLORER: 'https://adapools.yoroiwallet.com/?source=mobile', - KEY_DEPOSIT, - MARKETING_NAME: 'Cardano Mainnet', - MINIMUM_UTXO_VAL, - NETWORK_ID, - PER_EPOCH_PERCENTAGE_REWARD: 69344, - POOL_DEPOSIT, - PROVIDER_ID: 1, - COINS_PER_UTXO_WORD, -} as const - -export const PRIMARY_TOKEN: DefaultAsset = { - identifier: '.', - isDefault: true, - metadata: { - policyId: '', - assetName: '', - numberOfDecimals: 6, - ticker: 'ADA', - longName: null, - maxSupply: '45000000000000000', - }, -} as const diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts deleted file mode 100644 index a123e5610e..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/sanchonet/constants.ts +++ /dev/null @@ -1,78 +0,0 @@ -import {DefaultAsset} from '../../../types' -import {COIN_TYPE, COINS_PER_UTXO_WORD, KEY_DEPOSIT, MINIMUM_UTXO_VAL, POOL_DEPOSIT} from '../common' - -export * from '../common' - -export const NETWORK_ID = 450 -export const API_ROOT = 'https://sanchonet-backend.yoroiwallet.com/api' -export const TOKEN_INFO_SERVICE = 'https://stage-cdn.yoroiwallet.com' - -export const BACKEND = { - API_ROOT, - NFT_STORAGE_URL: 'https://validated-nft-images.s3.amazonaws.com', - TOKEN_INFO_SERVICE, - FETCH_UTXOS_MAX_ADDRESSES: 50, - TX_HISTORY_MAX_ADDRESSES: 50, - FILTER_USED_MAX_ADDRESSES: 50, - TX_HISTORY_RESPONSE_LIMIT: 50, -} as const -export const CHAIN_NETWORK_ID = 0 - -export const PROTOCOL_MAGIC = 1097911063 -export const BYRON_BASE_CONFIG = { - // byron-era - PROTOCOL_MAGIC, - // aka byron network id - START_AT: 0, - GENESIS_DATE: '1686789000000', - SLOTS_PER_EPOCH: 4320, - SLOT_DURATION: 20, -} as const - -export const SHELLEY_BASE_CONFIG = { - GENESIS_DATE: '1686789000000', - PROTOCOL_MAGIC, - // shelley-era - START_AT: 0, - SLOTS_PER_EPOCH: 86400, - SLOT_DURATION: 1, -} as const - -const CARDANO_BASE_CONFIG = [BYRON_BASE_CONFIG, SHELLEY_BASE_CONFIG] -export const NETWORK_CONFIG = { - BACKEND, - BASE_CONFIG: CARDANO_BASE_CONFIG, - CHAIN_NETWORK_ID: CHAIN_NETWORK_ID.toString(), - COIN_TYPE, - ENABLED: true, - EXPLORER_URL_FOR_ADDRESS: (address: string) => `https://preprod.cardanoscan.io/address/${address}`, - EXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 - ? `https://preprod.cardanoscan.io/token/${fingerprint}` - : `https://preprod.cardanoscan.io/tokens`, - CEXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 ? `https://preprod.cexplorer.io/asset/${fingerprint}` : `https://preprod.cexplorer.io/asset`, - EXPLORER_URL_FOR_TX: (txid: string) => `https://preprod.cardanoscan.io/transaction/${txid}`, - POOL_EXPLORER: 'https://adapools.yoroiwallet.com/?source=mobile', - KEY_DEPOSIT, - MARKETING_NAME: 'Cardano Sancho Testnet', - MINIMUM_UTXO_VAL, - NETWORK_ID, - PER_EPOCH_PERCENTAGE_REWARD: 69344, - POOL_DEPOSIT, - PROVIDER_ID: 300, - COINS_PER_UTXO_WORD, -} as const - -export const PRIMARY_TOKEN: DefaultAsset = { - identifier: '.', - isDefault: true, - metadata: { - policyId: '', - assetName: '', - numberOfDecimals: 6, - ticker: 'TADA', - longName: null, - maxSupply: '45000000000000000', - }, -} as const diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts deleted file mode 100644 index 4ada898504..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/constants/testnet/constants.ts +++ /dev/null @@ -1,76 +0,0 @@ -import {DefaultAsset} from '../../../types' -import {COIN_TYPE, COINS_PER_UTXO_WORD, KEY_DEPOSIT, MINIMUM_UTXO_VAL, POOL_DEPOSIT} from '../common' - -export * from '../common' - -export const NETWORK_ID = 300 -export const API_ROOT = 'https://preprod-backend.yoroiwallet.com/api' -export const TOKEN_INFO_SERVICE = 'https://stage-cdn.yoroiwallet.com' - -export const BACKEND = { - API_ROOT, - NFT_STORAGE_URL: 'https://validated-nft-images.s3.amazonaws.com', - TOKEN_INFO_SERVICE, - FETCH_UTXOS_MAX_ADDRESSES: 50, - TX_HISTORY_MAX_ADDRESSES: 50, - FILTER_USED_MAX_ADDRESSES: 50, - TX_HISTORY_RESPONSE_LIMIT: 50, -} as const -export const CHAIN_NETWORK_ID = 0 - -export const PROTOCOL_MAGIC = 1097911063 - -export const BYRON_BASE_CONFIG = { - // byron-era - PROTOCOL_MAGIC, - // aka byron network id - START_AT: 0, - GENESIS_DATE: '1563999616000', - SLOTS_PER_EPOCH: 21600, - SLOT_DURATION: 20, -} as const -export const SHELLEY_BASE_CONFIG = { - // shelley-era - START_AT: 74, - SLOTS_PER_EPOCH: 432000, - SLOT_DURATION: 1, -} as const - -const CARDANO_BASE_CONFIG = [BYRON_BASE_CONFIG, SHELLEY_BASE_CONFIG] -export const NETWORK_CONFIG = { - BACKEND, - BASE_CONFIG: CARDANO_BASE_CONFIG, - CHAIN_NETWORK_ID: CHAIN_NETWORK_ID.toString(), - COIN_TYPE, - ENABLED: true, - EXPLORER_URL_FOR_ADDRESS: (address: string) => `https://preprod.cardanoscan.io/address/${address}`, - EXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 - ? `https://preprod.cardanoscan.io/token/${fingerprint}` - : `https://preprod.cardanoscan.io/tokens`, - CEXPLORER_URL_FOR_TOKEN: (fingerprint: string) => - fingerprint.length > 0 ? `https://preprod.cexplorer.io/asset/${fingerprint}` : `https://preprod.cexplorer.io/asset`, - EXPLORER_URL_FOR_TX: (txid: string) => `https://preprod.cardanoscan.io/transaction/${txid}`, - POOL_EXPLORER: 'https://adapools.yoroiwallet.com/?source=mobile', - KEY_DEPOSIT, - MARKETING_NAME: 'Cardano testnet', - MINIMUM_UTXO_VAL, - NETWORK_ID, - PER_EPOCH_PERCENTAGE_REWARD: 69344, - POOL_DEPOSIT, - PROVIDER_ID: 300, - COINS_PER_UTXO_WORD, -} as const - -export const PRIMARY_TOKEN: DefaultAsset = { - identifier: '.', - isDefault: true, - metadata: { - policyId: '', - assetName: '', - numberOfDecimals: 6, - ticker: 'TADA', - longName: null, - maxSupply: '45000000000000000', - }, -} as const diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/derivation-path-manager/derivation-path-manager.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/derivation-path-manager/derivation-path-manager.ts index 80990e7c01..145814c8f8 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/derivation-path-manager/derivation-path-manager.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/derivation-path-manager/derivation-path-manager.ts @@ -1,6 +1,6 @@ import {Wallet} from '@yoroi/types' -import {cardanoConfig} from '../constants/cardano-config' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' export const derivationPathManagerMaker = (implementation: Wallet.Implementation) => diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts index 69b43afc11..f8ce60a033 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.test.ts @@ -1,5 +1,6 @@ import {Balance} from '@yoroi/types' +import {protocolParamsPlaceholder} from '../../features/WalletManager/network-manager/network-manager' import {mocks as walletMocks} from '../mocks' import {getMinAmounts, withMinAmounts, withPrimaryToken} from './getMinAmounts' @@ -13,7 +14,9 @@ describe('withMinAmounts()', () => { '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual({ + expect( + await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo, protocolParamsPlaceholder), + ).toEqual({ '.': '1301620', '698a6ea0ca99f315034072af31eaac6ec11fe8558d3f48e9775aab9d.7444524950': '12', '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', @@ -29,7 +32,9 @@ describe('withMinAmounts()', () => { '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e': '55', } - expect(await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual(amounts) + expect( + await withMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo, protocolParamsPlaceholder), + ).toEqual(amounts) }) }) @@ -68,7 +73,9 @@ describe('getMinAmounts()', () => { const address = 'addr_test1qrrdv3uxj8shu27ea9djvnn3rl4w3lvh3cyck6yc36mvf6ctlqxj9g0azvpycncr9u600p6t556qhc3psk06uzzw6saq4kvdpq' - expect(await getMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo)).toEqual({ + expect( + await getMinAmounts(address, amounts, walletMocks.wallet.portfolioPrimaryTokenInfo, protocolParamsPlaceholder), + ).toEqual({ [walletMocks.wallet.portfolioPrimaryTokenInfo.id]: '1301620', }) }) @@ -84,7 +91,7 @@ describe('getMinAmounts()', () => { const primaryToken = walletMocks.wallet.portfolioPrimaryTokenInfo - await expect(getMinAmounts(address, amounts, primaryToken)).rejects.toEqual( + await expect(getMinAmounts(address, amounts, primaryToken, protocolParamsPlaceholder)).rejects.toEqual( new Error('getMinAmounts::Error not a valid address'), ) }) diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts index 2c63606617..ee736e8063 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/getMinAmounts.ts @@ -1,22 +1,22 @@ import {BigNum} from '@emurgo/cross-csl-core' import {normalizeToAddress} from '@emurgo/yoroi-lib/dist/internals/utils/addresses' -import {Balance, Portfolio} from '@yoroi/types' +import {Balance, Chain, Portfolio} from '@yoroi/types' import BigNumber from 'bignumber.js' import {Address} from '../types' import {Amounts, asQuantity, Quantities} from '../utils' import {CardanoMobile} from '../wallets' import {cardanoValueFromMultiToken} from './cardanoValueFromMultiToken' -import {COINS_PER_UTXO_BYTE} from './constants/common' import {MultiToken} from './MultiToken' export const withMinAmounts = async ( address: Address, amounts: Balance.Amounts, primaryTokenInfo: Portfolio.Token.Info, + protocolParams: Chain.Cardano.ProtocolParams, ): Promise => { const amountsWithPrimaryToken = withPrimaryToken(amounts, primaryTokenInfo) - const minAmounts = await getMinAmounts(address, amountsWithPrimaryToken, primaryTokenInfo) + const minAmounts = await getMinAmounts(address, amountsWithPrimaryToken, primaryTokenInfo, protocolParams) return Amounts.map(amountsWithPrimaryToken, (amount) => ({ ...amount, @@ -28,6 +28,7 @@ export const getMinAmounts = async ( address: Address, amounts: Balance.Amounts, primaryTokenInfo: Portfolio.Token.Info, + protocolParams: Chain.Cardano.ProtocolParams, ) => { const multiToken = new MultiToken( [ @@ -42,7 +43,7 @@ export const getMinAmounts = async ( const [value, coinsPerUtxoByte] = await Promise.all([ cardanoValueFromMultiToken(multiToken), - CardanoMobile.BigNum.fromStr(COINS_PER_UTXO_BYTE), + CardanoMobile.BigNum.fromStr(protocolParams.coinsPerUtxoByte), ]) const normalizedAddress = await normalizeToAddress(CardanoMobile, address).catch(() => { diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.test.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.test.ts deleted file mode 100644 index 84d12d31b3..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {GENESIS_DATE} from '../constants/mainnet/constants' -import {getTime} from './getTime' - -describe('getTime', () => { - test('genesis', () => { - expect(getTime(Number(GENESIS_DATE))).toEqual({ - absoluteSlot: 0, - epoch: 0, - percentageElapsed: 0, - secondsRemainingInEpoch: 432000, - slot: 0, - slotsPerEpoch: 432000, - slotsRemaining: 432000, - }) - }) - - test('recent', () => { - expect(getTime(1677859888202)).toEqual({ - absoluteSlot: 171656797, - epoch: 397, - percentageElapsed: 35, - secondsRemainingInEpoch: 279203, - slot: 152797, - slotsPerEpoch: 432000, - slotsRemaining: 279203, - }) - }) -}) diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.ts deleted file mode 100644 index 181c00378f..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/getTime.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {GENESIS_DATE} from '../constants/mainnet/constants' - -export const getTime = (currentTimeMS: number) => { - // mainnet - const shelleyStartTimeMS = Number(GENESIS_DATE) - const absoluteSlot = Math.floor((currentTimeMS - shelleyStartTimeMS) / 1000) - const slotsPerEpoch = 5 * 24 * 60 * 60 - const epoch = Math.floor(absoluteSlot / slotsPerEpoch) - const slotsInPreviousEpochs = epoch * slotsPerEpoch - const slot = Math.floor(absoluteSlot - slotsInPreviousEpochs) - const slotsRemaining = Math.floor(slotsPerEpoch - slot) - const secondsRemainingInEpoch = slotsRemaining * 1 - const percentageElapsed = Math.floor((100 * slot) / slotsPerEpoch) - - return { - epoch, - slot, - absoluteSlot, - slotsRemaining, - slotsPerEpoch, - secondsRemainingInEpoch, - percentageElapsed, - } -} diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/index.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/index.ts deleted file mode 100644 index 8be8d94e60..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/getTime/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './getTime' diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/hw/hw.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/hw/hw.ts index d2040c8de5..69bf862d67 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/hw/hw.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/hw/hw.ts @@ -15,6 +15,8 @@ import TransportBLE from '@ledgerhq/react-native-hw-transport-ble' import {HW, Wallet} from '@yoroi/types' import {BleError} from 'react-native-ble-plx' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../../features/WalletManager/common/derivation-config' import {ledgerMessages} from '../../../kernel/i18n/global-messages' import LocalizableError from '../../../kernel/i18n/LocalizableError' import {logger} from '../../../kernel/logger/logger' @@ -25,7 +27,6 @@ import { LedgerUserError, RejectedByUserError, } from '../../hw' -import {cardanoConfig} from '../constants/cardano-config' const MIN_ADA_APP_VERSION = '2.2.1' const MIN_ADA_APP_VERSION_SUPPORTING_CIP36 = 6 @@ -115,7 +116,7 @@ const getXPubPathRequest = ( const implementationConfig = cardanoConfig.implementations[implementation] const {purpose, coinType} = implementationConfig.derivations.base.harden return { - path: [purpose, coinType, cardanoConfig.derivation.hardStart + accountVisual], + path: [purpose, coinType, derivationConfig.hardStart + accountVisual], } } diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/key-manager/key-manager.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/key-manager/key-manager.ts index 1ca40f30ef..d191d544e6 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/key-manager/key-manager.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/key-manager/key-manager.ts @@ -2,7 +2,8 @@ import {WasmModuleProxy} from '@emurgo/cross-csl-core' import {Wallet} from '@yoroi/types' import {freeze} from 'immer' -import {cardanoConfig} from '../constants/cardano-config' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../../features/WalletManager/common/derivation-config' import {generateWalletRootKey} from '../mnemonic/mnemonic' export const keyManager = @@ -16,7 +17,7 @@ export const keyManager = const accountPubKeyHex = await rootKeyPtr .derive(config.derivations.base.harden.purpose) .then((withPurpose) => withPurpose.derive(config.derivations.base.harden.coinType)) - .then((withCoinType) => withCoinType.derive(cardanoConfig.derivation.hardStart + accountVisual)) + .then((withCoinType) => withCoinType.derive(derivationConfig.hardStart + accountVisual)) .then((withAccount) => withAccount.toPublic()) .then((accountPubRaw) => accountPubRaw.asBytes()) .then((accountPubBytes) => Buffer.from(accountPubBytes).toString('hex')) diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/mnemonic/mnemonic.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/mnemonic/mnemonic.ts index 60dd24ba95..83475be205 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/mnemonic/mnemonic.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/mnemonic/mnemonic.ts @@ -5,9 +5,10 @@ import {generateMnemonic, mnemonicToEntropy} from 'bip39' // @ts-ignore import {randomBytes} from 'react-native-randombytes' +import {cardanoConfig} from '../../../features/WalletManager/common/adapters/cardano/cardano-config' +import {derivationConfig} from '../../../features/WalletManager/common/derivation-config' import {CardanoMobile} from '../../wallets' import {AddressGenerator} from '../account-manager/account-manager' -import {cardanoConfig} from '../constants/cardano-config' import {wrappedCsl} from '../wrappedCsl' const mnemonicStrengh = 160 @@ -52,7 +53,7 @@ export const deriveAddressFromMnemonics = async ({ const accountPubKey = await CardanoMobile.Bip32PrivateKey.fromBytes(Buffer.from(rootKey, 'hex')) .then((root) => root.derive(purpose)) .then((withPurpose) => withPurpose.derive(coinType)) - .then((withCoinType) => withCoinType.derive(accountVisual + cardanoConfig.derivation.hardStart)) + .then((withCoinType) => withCoinType.derive(accountVisual + derivationConfig.hardStart)) .then((withAccount) => withAccount.toPublic()) const accountPubKeyHex = Buffer.from(await accountPubKey.asBytes()).toString('hex') diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/networks.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/networks.ts deleted file mode 100644 index 82a0d39ae7..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/networks.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import * as SANCHONET_CONFIG from '../cardano/constants/sanchonet/constants' -import type {NetworkId} from '../types/other' -import {NETWORK_REGISTRY} from '../types/other' -import {NUMBERS} from './numbers' - -const _DEFAULT_BACKEND_RULES = { - FETCH_UTXOS_MAX_ADDRESSES: 50, - TX_HISTORY_MAX_ADDRESSES: 50, - FILTER_USED_MAX_ADDRESSES: 50, - TX_HISTORY_RESPONSE_LIMIT: 50, -} - -export const BYRON_MAINNET = { - NETWORK_ID: NETWORK_REGISTRY.BYRON_MAINNET, - MARKETING_NAME: 'Mainnet', - ENABLED: false, - PROTOCOL_MAGIC: 764824073, - GENESIS_DATE: '1506203091000', - START_AT: 0, - SLOTS_PER_EPOCH: 21600, - SLOT_DURATION: 20, - COIN_TYPE: NUMBERS.COIN_TYPES.CARDANO, -} -const HASKELL_SHELLEY = { - NETWORK_ID: NETWORK_REGISTRY.HASKELL_SHELLEY, - MARKETING_NAME: 'Cardano Mainnet', - ENABLED: true, - CHAIN_NETWORK_ID: '1', - - POOL_EXPLORER: 'https://adapools.yoroiwallet.com/?source=mobile', - - BACKEND: { - API_ROOT: 'https://api.yoroiwallet.com/api', - NFT_STORAGE_URL: 'https://fibo-validated-nft-images.s3.amazonaws.com', - TOKEN_INFO_SERVICE: 'https://cdn.yoroiwallet.com', - ..._DEFAULT_BACKEND_RULES, - }, - BASE_CONFIG: [ - { - // byron-era - PROTOCOL_MAGIC: 764824073, - // aka byron network id - START_AT: 0, - GENESIS_DATE: '1506203091000', - SLOTS_PER_EPOCH: 21600, - SLOT_DURATION: 20, - }, - { - // shelley-era - START_AT: 208, - SLOTS_PER_EPOCH: 432000, - SLOT_DURATION: 1, - }, - ], - PER_EPOCH_PERCENTAGE_REWARD: 69344, - COIN_TYPE: NUMBERS.COIN_TYPES.CARDANO, - // @deprecated - MINIMUM_UTXO_VAL: '1000000', - COINS_PER_UTXO_WORD: '34482', - POOL_DEPOSIT: '500000000', - KEY_DEPOSIT: '2000000', -} -const HASKELL_SHELLEY_TESTNET = { - NETWORK_ID: NETWORK_REGISTRY.HASKELL_SHELLEY_TESTNET, - MARKETING_NAME: 'Cardano testnet', - ENABLED: true, - CHAIN_NETWORK_ID: '0', - - POOL_EXPLORER: 'https://adapools.yoroiwallet.com/?source=mobile', - - BACKEND: { - API_ROOT: 'https://preprod-backend.yoroiwallet.com/api', - NFT_STORAGE_URL: 'https://validated-nft-images.s3.amazonaws.com', - TOKEN_INFO_SERVICE: 'https://stage-cdn.yoroiwallet.com', - ..._DEFAULT_BACKEND_RULES, - }, - BASE_CONFIG: [ - { - PROTOCOL_MAGIC: 1097911063, - // aka byron network id - START_AT: 0, - GENESIS_DATE: '1563999616000', - SLOTS_PER_EPOCH: 21600, - SLOT_DURATION: 20, - }, - { - // shelley-era - START_AT: 74, - SLOTS_PER_EPOCH: 432000, - SLOT_DURATION: 1, - }, - ], - PER_EPOCH_PERCENTAGE_REWARD: 69344, - COIN_TYPE: NUMBERS.COIN_TYPES.CARDANO, - MINIMUM_UTXO_VAL: '1000000', - COINS_PER_UTXO_WORD: '34482', - POOL_DEPOSIT: '500000000', - KEY_DEPOSIT: '2000000', -} - -export const NETWORKS = { - // Deprecated - BYRON_MAINNET, - - HASKELL_SHELLEY, - HASKELL_SHELLEY_TESTNET, - SANCHONET: SANCHONET_CONFIG.NETWORK_CONFIG, -} -export type CardanoHaskellShelleyNetwork = - | typeof NETWORKS.HASKELL_SHELLEY - | typeof NETWORKS.HASKELL_SHELLEY_TESTNET - | typeof NETWORKS.SANCHONET -export const getCardanoNetworkConfigById = (networkId: NetworkId): CardanoHaskellShelleyNetwork => { - switch (networkId) { - case NETWORKS.HASKELL_SHELLEY.NETWORK_ID: - return NETWORKS.HASKELL_SHELLEY - - case NETWORKS.HASKELL_SHELLEY_TESTNET.NETWORK_ID: - return NETWORKS.HASKELL_SHELLEY_TESTNET - - case NETWORKS.SANCHONET.NETWORK_ID: - return NETWORKS.SANCHONET - - default: - throw new Error('network id is not a valid Haskell Shelley id') - } -} diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/numbers.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/numbers.ts deleted file mode 100644 index 132073cbd2..0000000000 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/numbers.ts +++ /dev/null @@ -1,30 +0,0 @@ -import {BigNumber} from 'bignumber.js' - -export const NUMBERS = { - DECIMAL_PLACES_IN_ADA: 6, - LOVELACES_PER_ADA: new BigNumber('1 000 000'.replace(/ /g, ''), 10), - HARD_DERIVATION_START: 2147483648, - WALLET_TYPE_PURPOSE: { - BIP44: 2147483692, // HARD_DERIVATION_START + 44; - CIP1852: 2147485500, // HARD_DERIVATION_START + 1852; - }, - COIN_TYPES: { - CARDANO: 2147485463, // HARD_DERIVATION_START + 1815; - }, - ACCOUNT_INDEX: 0, - CHAIN_DERIVATIONS: { - EXTERNAL: 0, - INTERNAL: 1, - CHIMERIC_ACCOUNT: 2, - }, - BIP44_DERIVATION_LEVELS: { - ROOT: 0, - PURPOSE: 1, - COIN_TYPE: 2, - ACCOUNT: 3, - CHAIN: 4, - ADDRESS: 5, - }, - STAKING_KEY_INDEX: 0, - EPOCH_REWARD_DENOMINATOR: new BigNumber(10).pow(8), -} as const diff --git a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts index 8d1790b663..12670c2e31 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/cardano/utils.ts @@ -1,6 +1,6 @@ /* eslint-disable no-empty */ import {SendToken} from '@emurgo/yoroi-lib' -import {Balance, Portfolio, Wallet} from '@yoroi/types' +import {Balance, Chain, Portfolio, Wallet} from '@yoroi/types' import {BigNumber} from 'bignumber.js' import {Buffer} from 'buffer' @@ -12,7 +12,6 @@ import {CardanoMobile} from '../wallets' import {toAssetNameHex, toPolicyId} from './api/utils' import {withMinAmounts} from './getMinAmounts' import {MultiToken} from './MultiToken' -import {CardanoHaskellShelleyNetwork} from './networks' import {CardanoTypes} from './types' import {wrappedCsl as getCSL} from './wrappedCsl' @@ -101,37 +100,18 @@ export const isByron = (implementation: Wallet.Implementation) => implementation export const isShelley = (implementation: Wallet.Implementation) => implementation === 'cardano-cip1852' -// need to accomodate base config parameters as required by certain API shared -// by yoroi extension and yoroi mobile -export const getCardanoBaseConfig = ( - networkConfig: CardanoHaskellShelleyNetwork, -): Array<{ - StartAt?: number - GenesisDate?: string - SlotsPerEpoch?: number - SlotDuration?: number -}> => [ - { - StartAt: networkConfig.BASE_CONFIG[0].START_AT, - GenesisDate: networkConfig.BASE_CONFIG[0].GENESIS_DATE, - SlotsPerEpoch: networkConfig.BASE_CONFIG[0].SLOTS_PER_EPOCH, - SlotDuration: networkConfig.BASE_CONFIG[0].SLOT_DURATION, - }, - { - StartAt: networkConfig.BASE_CONFIG[1].START_AT, - SlotsPerEpoch: networkConfig.BASE_CONFIG[1].SLOTS_PER_EPOCH, - SlotDuration: networkConfig.BASE_CONFIG[1].SLOT_DURATION, - }, -] - export const toSendTokenList = (amounts: Balance.Amounts, primaryTokenInfo: Portfolio.Token.Info): Array => { return Amounts.toArray(amounts).map(toSendToken(primaryTokenInfo)) } -export const toRecipients = async (entries: YoroiEntry[], primaryTokenInfo: Portfolio.Token.Info) => { +export const toRecipients = async ( + entries: YoroiEntry[], + primaryTokenInfo: Portfolio.Token.Info, + protocolParams: Chain.Cardano.ProtocolParams, +) => { return Promise.all( entries.map(async (entry) => { - const amounts = await withMinAmounts(entry.address, entry.amounts, primaryTokenInfo) + const amounts = await withMinAmounts(entry.address, entry.amounts, primaryTokenInfo, protocolParams) return { receiver: entry.address, tokens: toSendTokenList(amounts, primaryTokenInfo), diff --git a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts index 0fa5cbb77b..abd68ea412 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts @@ -19,12 +19,12 @@ import { UseQueryOptions, } from 'react-query' +import {cardanoConfig} from '../../features/WalletManager/common/adapters/cardano/cardano-config' import {useSelectedNetwork} from '../../features/WalletManager/common/hooks/useSelectedNetwork' import {isDev, isNightly} from '../../kernel/env' import {logger} from '../../kernel/logger/logger' import {deriveAddressFromXPub} from '../cardano/account-manager/derive-address-from-xpub' import {getSpendingKey, getStakingKey} from '../cardano/addressInfo/addressInfo' -import {cardanoConfig} from '../cardano/constants/cardano-config' import {WalletEvent, YoroiWallet} from '../cardano/types' import {TRANSACTION_DIRECTION, TRANSACTION_STATUS, YoroiSignedTx, YoroiUnsignedTx} from '../types' import {TipStatusResponse, TxSubmissionStatus} from '../types/other' diff --git a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts index 5735c5ed9f..13f1007b18 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/mocks/wallet.ts @@ -10,9 +10,9 @@ import {noop} from 'lodash' import {Observable} from 'rxjs' import {buildPortfolioTokenManagers} from '../../features/Portfolio/common/helpers/build-token-managers' +import {cardanoConfig} from '../../features/WalletManager/common/adapters/cardano/cardano-config' import {buildNetworkManagers} from '../../features/WalletManager/network-manager/network-manager' import {toTokenInfo, utf8ToHex} from '../cardano/api/utils' -import {CHIMERIC_ACCOUNT, STAKING_KEY_INDEX} from '../cardano/constants/testnet/constants' import {CardanoTypes, YoroiWallet} from '../cardano/types' import { RemotePoolMetaSuccess, @@ -153,8 +153,8 @@ const wallet: YoroiWallet = { '8e4e2f11b6ac2a269913286e26339779ab8767579d18d173cdd324929d94e2c43e3ec212cc8a36ed9860579dfe1e3ef4d6de778c5dbdd981623b48727cd96247' const accountPubKey = await CardanoMobile.Bip32PublicKey.fromBytes(Buffer.from(pubKeyHex, 'hex')) return accountPubKey - .derive(CHIMERIC_ACCOUNT) - .then((key) => key.derive(STAKING_KEY_INDEX)) + .derive(cardanoConfig.implementations['cardano-cip1852'].features.staking.derivation.role) + .then((key) => key.derive(cardanoConfig.implementations['cardano-cip1852'].features.staking.derivation.index)) .then((key) => key.toRawKey()) }, signRawTx(): Promise { diff --git a/apps/wallet-mobile/src/yoroi-wallets/utils/timeUtils.ts b/apps/wallet-mobile/src/yoroi-wallets/utils/timeUtils.ts index 622d520466..ffd32d9e1a 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/utils/timeUtils.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/utils/timeUtils.ts @@ -1,184 +1,23 @@ -export type ToAbsoluteSlotNumberRequest = { - epoch: number - slot: number -} -export type ToAbsoluteSlotNumberResponse = number - -export type ToRelativeSlotNumberRequest = ToAbsoluteSlotNumberResponse -export type ToRelativeSlotNumberResponse = ToAbsoluteSlotNumberRequest -export type ToRelativeSlotNumberFunc = (request: ToRelativeSlotNumberRequest) => ToRelativeSlotNumberResponse -export function genToRelativeSlotNumber( - config: Array<{ - StartAt?: number - SlotsPerEpoch?: number - }>, -): ToRelativeSlotNumberFunc { - return (absoluteSlot: ToRelativeSlotNumberRequest) => { - let SlotsPerEpoch = config[0].SlotsPerEpoch - let epochCount = 0 - let slotsLeft = absoluteSlot - - // for pairs of config changes (x, x+1), get the time between these pairs - for (let i = 0; i < config.length - 1; i++) { - const start = - config[i].StartAt ?? - (() => { - throw new Error('genToRelativeSlotNumber missing start') - })() - const end = - config[i + 1].StartAt ?? - (() => { - throw new Error('genToRelativeSlotNumber end') - })() - const numEpochs = end - start - - if (SlotsPerEpoch == null) { - throw new Error('genToRelativeSlotNumber params') - } - - // queried time is before the next protocol parameter choice - if (slotsLeft < SlotsPerEpoch * numEpochs) { - break - } - - slotsLeft -= SlotsPerEpoch * numEpochs - epochCount += numEpochs - - SlotsPerEpoch = config[i + 1].SlotsPerEpoch ?? SlotsPerEpoch - } - - if (SlotsPerEpoch == null) { - throw new Error('genToAbsoluteSlotNumber:: missing params') - } - - // find how many slots in the epochs since the last update - epochCount += Math.floor(slotsLeft / SlotsPerEpoch) - - return { - epoch: epochCount, - slot: slotsLeft % SlotsPerEpoch, - } - } -} - -export type TimeToAbsoluteSlotRequest = { - time: number -} -export type TimeToAbsoluteSlotResponse = { - slot: number - msIntoSlot: number -} -export type TimeToAbsoluteSlotFunc = (request: TimeToAbsoluteSlotRequest) => TimeToAbsoluteSlotResponse - -export function genTimeToSlot( - config: Array<{ - StartAt?: number - GenesisDate?: string - SlotsPerEpoch?: number - SlotDuration?: number - }>, -): TimeToAbsoluteSlotFunc { - return (request: TimeToAbsoluteSlotRequest) => { - const {GenesisDate} = config[0] - if (GenesisDate == null) { - throw new Error('genTimeToSlot missing genesis params') - } - let SlotDuration = config[0].SlotDuration - let SlotsPerEpoch = config[0].SlotsPerEpoch - let timeLeftToTip = request.time - Number.parseInt(GenesisDate, 10) - let slotCount = 0 - - // for pairs of config changes (x, x+1), get the time between these pairs - for (let i = 0; i < config.length - 1; i++) { - const start = - config[i].StartAt ?? - (() => { - throw new Error('genTimeToSlot missing start') - })() - const end = - config[i + 1].StartAt ?? - (() => { - throw new Error('genTimeToSlot missing end') - })() - const numEpochs = end - start - if (SlotDuration == null || SlotsPerEpoch == null) { - throw new Error('genTimeToSlot missing params') - } - - // queried time is before the next protocol parameter choice - if (timeLeftToTip < SlotsPerEpoch * SlotDuration * 1000 * numEpochs) { - break - } - slotCount += SlotsPerEpoch * numEpochs - timeLeftToTip -= SlotsPerEpoch * SlotDuration * 1000 * numEpochs - - SlotDuration = config[i + 1].SlotDuration ?? SlotDuration - SlotsPerEpoch = config[i + 1].SlotsPerEpoch ?? SlotsPerEpoch - } - - if (SlotDuration == null || SlotsPerEpoch == null) { - throw new Error('genTimeToSlot missing params') - } - - // find how many slots since the last update - const secondsSinceLastUpdate = timeLeftToTip / 1000 - slotCount += Math.floor(secondsSinceLastUpdate / SlotDuration) - - const msIntoSlot = timeLeftToTip % 1000 - const secondsIntoSlot = secondsSinceLastUpdate % SlotDuration - return { - slot: slotCount, - msIntoSlot: 1000 * secondsIntoSlot + msIntoSlot, - } - } -} - -export type CurrentEpochLengthRequest = void +export const delay = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)) -/** slots per epoch */ -export type CurrentEpochLengthResponse = number -export type CurrentEpochLengthFunc = (request: CurrentEpochLengthRequest) => CurrentEpochLengthResponse -export function genCurrentEpochLength( - config: Array<{ - SlotsPerEpoch?: number - }>, -): CurrentEpochLengthFunc { - return (_request: CurrentEpochLengthRequest) => { - const finalConfig = config.reduce((acc, next) => Object.assign(acc, next), {}) - return finalConfig.SlotsPerEpoch as number - } -} +const sec_in_day = 86400 +const sec_in_hour = 3600 +const sec_in_min = 60 +const ms_in_sec = 1000 -export type CurrentSlotLengthRequest = void -export type CurrentSlotLengthResponse = number -export type CurrentSlotLengthFunc = (request: CurrentSlotLengthRequest) => CurrentSlotLengthResponse -export function genCurrentSlotLength( - config: Array<{ - SlotDuration?: number - }>, -): CurrentSlotLengthFunc { - return (_request: CurrentSlotLengthRequest) => { - const finalConfig = config.reduce((acc, next) => Object.assign(acc, next), {}) - return finalConfig.SlotDuration as number - } -} +export const formatTimeSpan = (ms: number): string => { + if (ms < 0) return '' -export const delay = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)) + const totalSeconds = Math.round(Math.abs(ms) / ms_in_sec) -const ms_in_sec = 1000, - sec_in_day = 86400, - sec_in_hour = 3600, - sec_in_min = 60 + const days = Math.floor(totalSeconds / sec_in_day) + const hours = Math.floor((totalSeconds % sec_in_day) / sec_in_hour) + const minutes = Math.floor((totalSeconds % sec_in_hour) / sec_in_min) -export const formatTimeSpan = (ms: number) => { - if (ms < 0) return '' + const fmtDays = padWithZero(days) + 'd' + const fmtHours = padWithZero(hours) + 'h' + const fmtMinutes = padWithZero(minutes) + 'm' - let seconds = Math.round(Math.abs(ms) / ms_in_sec) - const days = Math.floor(seconds / sec_in_day) - seconds = Math.floor(seconds % sec_in_day) - const hours = Math.floor(seconds / sec_in_hour) - seconds = Math.floor(seconds % sec_in_hour) - const minutes = Math.floor(seconds / sec_in_min) - const [dd, hh, mm] = [days, hours, minutes].map((item) => (item < 10 ? '0' + item : item.toString())) - return `${dd}d : ${hh}h : ${mm}m` + return `${fmtDays} : ${fmtHours} : ${fmtMinutes}` } +const padWithZero = (n: number): string => (n < 10 ? `0${n}` : n.toString()) diff --git a/apps/wallet-mobile/translations/messages/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.json b/apps/wallet-mobile/translations/messages/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.json index 7ccbe8cab9..1261909ca4 100644 --- a/apps/wallet-mobile/translations/messages/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.json +++ b/apps/wallet-mobile/translations/messages/src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!My read-only wallet", "file": "src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx", "start": { - "line": 154, + "line": 152, "column": 21, - "index": 4787 + "index": 4782 }, "end": { - "line": 157, + "line": 155, "column": 3, - "index": 4914 + "index": 4909 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Checksum label", "file": "src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx", "start": { - "line": 158, + "line": 156, "column": 17, - "index": 4933 + "index": 4928 }, "end": { - "line": 161, + "line": 159, "column": 3, - "index": 5047 + "index": 5042 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Wallet Address(es):", "file": "src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx", "start": { - "line": 162, + "line": 160, "column": 22, - "index": 5071 + "index": 5066 }, "end": { - "line": 165, + "line": 163, "column": 3, - "index": 5195 + "index": 5190 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Key:", "file": "src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx", "start": { - "line": 166, + "line": 164, "column": 7, - "index": 5204 + "index": 5199 }, "end": { - "line": 169, + "line": 167, "column": 3, - "index": 5302 + "index": 5297 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Derivation path:", "file": "src/features/SetupWallet/legacy/SaveReadOnlyWallet/SaveReadOnlyWalletScreen.tsx", "start": { - "line": 170, + "line": 168, "column": 18, - "index": 5322 + "index": 5317 }, "end": { - "line": 173, + "line": 171, "column": 3, - "index": 5443 + "index": 5438 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/Dashboard.json b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/Dashboard.json index 0cc05e4962..1f25bb5c05 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/Dashboard.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/Dashboard.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Go to Staking Center", "file": "src/legacy/Dashboard/Dashboard.tsx", "start": { - "line": 249, + "line": 227, "column": 23, - "index": 8127 + "index": 7191 }, "end": { - "line": 252, + "line": 230, "column": 3, - "index": 8260 + "index": 7324 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json b/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json index dfce23b8b3..763f6976b1 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Delegate", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 197, + "line": 186, "column": 23, - "index": 6357 + "index": 5901 }, "end": { - "line": 200, + "line": 189, "column": 3, - "index": 6471 + "index": 6015 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!of fees", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 201, + "line": 190, "column": 10, - "index": 6483 + "index": 6027 }, "end": { - "line": 204, + "line": 193, "column": 3, - "index": 6583 + "index": 6127 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Current approximation of rewards that you will receive per epoch:", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 205, + "line": 194, "column": 22, - "index": 6607 + "index": 6151 }, "end": { - "line": 208, + "line": 197, "column": 3, - "index": 6777 + "index": 6321 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Unknown pool", "file": "src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.tsx", "start": { - "line": 209, + "line": 198, "column": 15, - "index": 6794 + "index": 6338 }, "end": { - "line": 212, + "line": 201, "column": 3, - "index": 6913 + "index": 6457 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json b/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json index 30704959bc..40827c0e12 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Invalid Pool Data", "file": "src/legacy/Staking/StakingCenter/StakingCenter.tsx", "start": { - "line": 131, + "line": 130, "column": 9, - "index": 4730 + "index": 4665 }, "end": { - "line": 134, + "line": 133, "column": 3, - "index": 4838 + "index": 4773 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!The data from the stake pool(s) you selected is invalid. Please try again", "file": "src/legacy/Staking/StakingCenter/StakingCenter.tsx", "start": { - "line": 135, + "line": 134, "column": 11, - "index": 4851 + "index": 4786 }, "end": { - "line": 138, + "line": 137, "column": 3, - "index": 5017 + "index": 4952 } } ] \ No newline at end of file diff --git a/packages/api/src/cardano/api/cardano-api-maker.mocks.ts b/packages/api/src/cardano/api/cardano-api-maker.mocks.ts index 5f192e9811..972c7019a2 100644 --- a/packages/api/src/cardano/api/cardano-api-maker.mocks.ts +++ b/packages/api/src/cardano/api/cardano-api-maker.mocks.ts @@ -26,6 +26,6 @@ const getProtocolParams = { }, } -export const mockCardanoApi: Api.Cardano.Actions = { +export const mockCardanoApi: Api.Cardano.Api = { getProtocolParams: getProtocolParams.success, } as const diff --git a/packages/api/src/cardano/api/cardano-api-maker.ts b/packages/api/src/cardano/api/cardano-api-maker.ts index 12052e1a6a..0ed82ef9af 100644 --- a/packages/api/src/cardano/api/cardano-api-maker.ts +++ b/packages/api/src/cardano/api/cardano-api-maker.ts @@ -10,7 +10,7 @@ export const cardanoApiMaker = ({ }: { network: Chain.SupportedNetworks request?: Fetcher -}): Readonly => { +}): Readonly => { const baseUrl = API_ENDPOINTS[network].root const getProtocolParams = getProtocolParamsWrapper(baseUrl, request) diff --git a/packages/types/src/api/cardano.ts b/packages/types/src/api/cardano.ts index 75f3273b15..622172b9be 100644 --- a/packages/types/src/api/cardano.ts +++ b/packages/types/src/api/cardano.ts @@ -146,14 +146,3 @@ export type ApiTokenIdentity = { name: string nameHex: string } - -export type ApiProtocolParams = Readonly<{ - coinsPerUtxoByte: string - keyDeposit: string - linearFee: { - coefficient: string - constant: string - } - poolDeposit: string - epoch: number -}> diff --git a/packages/types/src/chain/cardano.ts b/packages/types/src/chain/cardano.ts index 28ba96b25c..99886fbfa6 100644 --- a/packages/types/src/chain/cardano.ts +++ b/packages/types/src/chain/cardano.ts @@ -6,6 +6,18 @@ import { import {BalanceAmounts} from '../balance/token' +export type ChainCardanoProtocolParams = Readonly<{ + coinsPerUtxoByte: string + keyDeposit: string + linearFee: { + coefficient: string + constant: string + } + poolDeposit: string + epoch: number +}> + +// START legacy export type CardanoUnsignedTx = CardanoTxInfo & { unsignedTx: UnsignedTxType } @@ -52,3 +64,4 @@ export type CardanoVoting = { export type CardanoAddress = string export type CardanoTokenId = string +// END legacy diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 00994a6b61..0a6b69dfbc 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -93,7 +93,6 @@ import { ApiOnChainMetadataRecord, ApiOnChainMetadataRequest, ApiOnChainMetadataResponse, - ApiProtocolParams, ApiTokenId, ApiTokenIdentity, ApiTokenRegistryEntry, @@ -121,6 +120,7 @@ import { CardanoTxInfo, CardanoUnsignedTx, CardanoVoting, + ChainCardanoProtocolParams, } from './chain/cardano' import {ExchangeBlockchainCode} from './exchange/blockchain' import {ExchangeManagerOptions} from './exchange/build' @@ -445,9 +445,9 @@ export namespace Api { export type MetadataFile = ApiMetadataFile export type TokenId = ApiTokenId - export type ProtocolParams = ApiProtocolParams + export type ProtocolParams = ChainCardanoProtocolParams - export interface Actions { + export interface Api { getProtocolParams: () => Promise } } @@ -588,6 +588,7 @@ export namespace Chain { export type Voting = CardanoVoting export type Address = CardanoAddress export type TokenId = CardanoTokenId + export type ProtocolParams = ChainCardanoProtocolParams } } diff --git a/packages/types/src/network/manager.ts b/packages/types/src/network/manager.ts index 2bba8225ab..37607d4b33 100644 --- a/packages/types/src/network/manager.ts +++ b/packages/types/src/network/manager.ts @@ -1,5 +1,5 @@ -import {ApiProtocolParams} from '../api/cardano' import {AppObservableStorage} from '../app/observable-storage' +import {ChainCardanoProtocolParams} from '../chain/cardano' import {ChainSupportedNetworks} from '../chain/network' import {ExplorersExplorer} from '../explorers/explorer' import {ExplorersManager} from '../explorers/manager' @@ -20,15 +20,21 @@ export type NetworkConfig = { // NOTE: NetworkConfig will be a generic type in the future export type NetworkApi = { - protocolParams: () => Promise> + protocolParams: () => Promise> } -export type NetworkManager = { - tokenManager: PortfolioManagerToken - rootStorage: AppObservableStorage - legacyRootStorage: AppObservableStorage - api: NetworkApi - explorers: Record -} & NetworkConfig +export type NetworkManager = Readonly< + { + tokenManager: PortfolioManagerToken + rootStorage: AppObservableStorage + legacyRootStorage: AppObservableStorage + api: Readonly + explorers: Readonly> + epoch: Readonly<{ + info: (date: Date) => Readonly + progress: (date: Date) => Readonly + }> + } & Readonly +> export type NetworkEraConfig = { name: 'byron' | 'shelley'