From 326e7048879e632d991623bd4f71f434a8f3e5da Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Fri, 26 Jan 2024 19:44:08 +0300 Subject: [PATCH 01/13] fixed not displaying rewards balance when pending withdrawal is present --- build-release.sh | 2 +- .../app/components/topbar/NavWalletDetails.js | 18 +------- .../topbar/NavWalletDetailsRevamp.js | 11 ++--- .../wallet/my-wallets/WalletDetails.js | 8 +--- .../app/containers/NavBarContainer.js | 18 ++------ .../app/containers/NavBarContainerRevamp.js | 16 ++----- .../app/containers/wallet/MyWalletsPage.js | 18 ++------ .../dialogs/WalletRestoreDialogContainer.js | 13 ++---- .../wallet/staking/CardanoStakingPage.js | 46 +++++-------------- .../app/stores/toplevel/DelegationStore.js | 36 +++++++++++---- .../app/stores/toplevel/TransactionsStore.js | 8 ++++ 11 files changed, 69 insertions(+), 125 deletions(-) diff --git a/build-release.sh b/build-release.sh index c584fdf506..b776aef9c1 100644 --- a/build-release.sh +++ b/build-release.sh @@ -7,7 +7,7 @@ then RELEASE_TYPE="nightly" elif [ $1 = "nightly-mv2" ]; then RELEASE_TYPE="nightly-mv2" else - echo "First parameter is expected 'stable', 'stable-mv2', or 'nightly'" + echo "First parameter is expected 'stable', 'stable-mv2', 'nightly', or 'nightly-mv2'" return 1 fi diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js index 0cc12c2ca2..de7759054f 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js @@ -30,12 +30,7 @@ type Props = {| +shouldHideBalance: boolean, +highlightTitle?: boolean, +showEyeIcon?: boolean, - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ - +rewards: null | void | MultiToken, + +rewards: ?MultiToken, +walletAmount: null | MultiToken, +infoText?: string, +showDetails?: boolean, @@ -82,11 +77,7 @@ export default class NavWalletDetails extends Component { const totalAmount = this.getTotalAmount(); - const showsRewards = ( - this.props.rewards !== undefined && - showDetails !== null && - showDetails === true - ); + const showsRewards = showDetails === true; const showEyeIconSafe = showEyeIcon != null && showEyeIcon; const { unitOfAccountSetting } = this.props; return ( @@ -152,11 +143,6 @@ export default class NavWalletDetails extends Component { } - {this.props.rewards === undefined && ( -
- {intl.formatMessage(globalMessages.walletSendConfirmationTotalLabel)} -
- )} )} diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js index 19b098b04d..771d4f203a 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js @@ -25,12 +25,7 @@ type Props = {| +shouldHideBalance: boolean, +highlightTitle?: boolean, +showEyeIcon?: boolean, - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ - +rewards: null | void | MultiToken, + +rewards: ?MultiToken, +walletAmount: null | MultiToken, +infoText?: string, +showDetails?: boolean, @@ -169,10 +164,10 @@ export default class NavWalletDetailsRevamp extends Component { } getTotalAmount: void => null | MultiToken = () => { - if (this.props.rewards === undefined) { + if (this.props.rewards == null) { return this.props.walletAmount; } - if (this.props.rewards === null || this.props.walletAmount === null) { + if (this.props.walletAmount == null) { return null; } return this.props.rewards.joinAddCopy(this.props.walletAmount); diff --git a/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js b/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js index f2dd912c46..8e591d60c9 100644 --- a/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js +++ b/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js @@ -18,12 +18,7 @@ import type { TokenRow } from '../../../api/ada/lib/storage/database/primitives/ type Props = {| +onUpdateHideBalance: void => Promise, +shouldHideBalance: boolean, - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ - +rewards?: null | void | MultiToken, + +rewards: ?MultiToken, +walletAmount: null | MultiToken, +infoText?: string, +getTokenInfo: ($ReadOnly>) => $ReadOnly, @@ -34,7 +29,6 @@ type Props = {| export default class WalletDetails extends Component { static defaultProps: {| infoText: void, rewards: null |} = { infoText: undefined, - rewards: null, }; static contextTypes: {| intl: $npm$ReactIntl$IntlFormat |} = { diff --git a/packages/yoroi-extension/app/containers/NavBarContainer.js b/packages/yoroi-extension/app/containers/NavBarContainer.js index b997a611d4..5d208b24df 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainer.js +++ b/packages/yoroi-extension/app/containers/NavBarContainer.js @@ -183,20 +183,8 @@ export default class NavBarContainer extends Component { ); } - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ - getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - const delegationRequest = this.generated.stores.delegation.getDelegationRequests(publicDeriver); - if (delegationRequest == null) return undefined; - - const balanceResult = delegationRequest.getDelegatedBalance.result; - if (balanceResult == null) { - return null; - } - return balanceResult.accountPart; + getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { + return this.generated.stores.delegation.getRewardBalance(publicDeriver); }; @computed get generated(): {| @@ -235,6 +223,7 @@ export default class NavBarContainer extends Component { app: {| currentRoute: string |}, delegation: {| getDelegationRequests: (PublicDeriver<>) => void | DelegationRequests, + getRewardBalance: (PublicDeriver<>) => ?MultiToken, |}, profile: {| shouldHideBalance: boolean, @@ -292,6 +281,7 @@ export default class NavBarContainer extends Component { }, delegation: { getDelegationRequests: stores.delegation.getDelegationRequests, + getRewardBalance: stores.delegation.getRewardBalance, }, transactions: { balance: stores.transactions.balance, diff --git a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js index 38e4bfb2d0..178d3c9340 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js +++ b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js @@ -239,20 +239,8 @@ export default class NavBarContainerRevamp extends Component { }, []); }; - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - const delegationRequest = this.generated.stores.delegation.getDelegationRequests(publicDeriver); - if (delegationRequest == null) return undefined; - - const balanceResult = delegationRequest.getDelegatedBalance.result; - if (balanceResult == null) { - return null; - } - return balanceResult.accountPart; + return this.generated.stores.delegation.getRewardBalance(publicDeriver); }; @computed get generated(): {| @@ -298,6 +286,7 @@ export default class NavBarContainerRevamp extends Component { uiDialogs: {| isOpen: any => boolean |}, delegation: {| getDelegationRequests: (PublicDeriver<>) => void | DelegationRequests, + getRewardBalance: (PublicDeriver<>) => ?MultiToken, |}, profile: {| shouldHideBalance: boolean, @@ -360,6 +349,7 @@ export default class NavBarContainerRevamp extends Component { }, delegation: { getDelegationRequests: stores.delegation.getDelegationRequests, + getRewardBalance: stores.delegation.getRewardBalance, }, transactions: { getBalance: stores.transactions.getBalance, diff --git a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js index 7468818010..6fe8f33d52 100644 --- a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js +++ b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js @@ -337,20 +337,8 @@ class MyWalletsPage extends Component { return walletSubRow; }; - /** - * undefined => wallet is not a reward wallet - * null => still calculating - * value => done calculating - */ - getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - const delegationRequest = this.generated.stores.delegation.getDelegationRequests(publicDeriver); - if (delegationRequest == null) return undefined; - - const balanceResult = delegationRequest.getDelegatedBalance.result; - if (balanceResult == null) { - return null; - } - return balanceResult.accountPart; + getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { + return this.generated.stores.delegation.getRewardBalance(publicDeriver); }; @computed get generated(): {| @@ -401,6 +389,7 @@ class MyWalletsPage extends Component { |}, delegation: {| getDelegationRequests: (PublicDeriver<>) => void | DelegationRequests, + getRewardBalance: (PublicDeriver<>) => ?MultiToken, |}, tokenInfoStore: {| tokenInfo: TokenInfoMap, @@ -459,6 +448,7 @@ class MyWalletsPage extends Component { }, delegation: { getDelegationRequests: stores.delegation.getDelegationRequests, + getRewardBalance: stores.delegation.getRewardBalance, }, }, actions: { diff --git a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js index 5ec5a90bd4..416e2fb6d6 100644 --- a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js +++ b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js @@ -107,15 +107,8 @@ export default class WalletRestoreDialogContainer extends Component { await this.generated.actions.profile.updateHideBalance.trigger(); }; - getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - const delegationRequest = this.generated.stores.delegation.getDelegationRequests(publicDeriver); - if (delegationRequest == null) return undefined; - - const balanceResult = delegationRequest.getDelegatedBalance.result; - if (balanceResult == null) { - return null; - } - return balanceResult.accountPart; + getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { + return this.generated.stores.delegation.getRewardBalance(publicDeriver); }; openToTransactions: (PublicDeriver<>) => void = publicDeriver => { @@ -441,6 +434,7 @@ export default class WalletRestoreDialogContainer extends Component { |}, delegation: {| getDelegationRequests: (PublicDeriver<>) => void | DelegationRequests, + getRewardBalance: (PublicDeriver<>) => ?MultiToken, |}, walletRestore: {| recoveryResult: void | {| @@ -505,6 +499,7 @@ export default class WalletRestoreDialogContainer extends Component { }, delegation: { getDelegationRequests: stores.delegation.getDelegationRequests, + getRewardBalance: stores.delegation.getRewardBalance, }, wallets: { restoreRequest: { diff --git a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js index f4582cb6ad..853a9abb7a 100644 --- a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js +++ b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js @@ -86,13 +86,7 @@ class CardanoStakingPage extends Component { const selectedPlate = this.generated.stores.wallets.activeWalletPlate; const stakingListBias = selectedPlate?.TextPart || 'bias'; - const delegationRequests = this.generated.stores.delegation.getDelegationRequests( - selectedWallet - ); - if (delegationRequests == null) { - throw new Error(`${nameof(SeizaFetcher)} opened for non-reward wallet`); - } - + const delegatedPoolId = this.generated.stores.delegation.getDelegatedPoolId(selectedWallet); if (urlTemplate != null) { const totalAda = this._getTotalAda(); const locale = this.generated.stores.profile.currentLocale; @@ -103,10 +97,7 @@ class CardanoStakingPage extends Component { } const balance = this.generated.stores.transactions.getBalance(publicDeriver); const isWalletWithNoFunds = balance != null && balance.getDefaultEntry().amount.isZero(); - const poolList = ( - delegationRequests.getDelegatedBalance.result?.delegation != null && - this._isRegistered(publicDeriver) - ) ? [delegationRequests.getDelegatedBalance.result?.delegation] : []; + const poolList = (delegatedPoolId != null && this._isRegistered(publicDeriver)) ? [delegatedPoolId] : []; const classicCardanoStakingPage = (
@@ -199,19 +190,12 @@ class CardanoStakingPage extends Component { } const delegationStore = this.generated.stores.delegation; - const delegationRequests = delegationStore.getDelegationRequests(publicDeriver); - if (delegationRequests == null) { - throw new Error(`${nameof(CardanoStakingPage)} opened for non-reward wallet`); - } - const balance = this.generated.stores.transactions.getBalance(publicDeriver); if (balance == null) { return null; } - const rewardBalance = - delegationRequests.getDelegatedBalance.result == null - ? new MultiToken([], publicDeriver.getParent().getDefaultToken()) - : delegationRequests.getDelegatedBalance.result.accountPart; + const rewardBalance = delegationStore.getRewardBalance(publicDeriver) + ?? new MultiToken([], publicDeriver.getParent().getDefaultToken()); const tokenInfo = genLookupOrFail(this.generated.stores.tokenInfoStore.tokenInfo)( rewardBalance.getDefaultEntry() ); @@ -474,21 +458,7 @@ class CardanoStakingPage extends Component { }; _isRegistered: (PublicDeriver<>) => ?boolean = publicDeriver => { - if (!isCardanoHaskell(publicDeriver.getParent().getNetworkInfo())) { - return undefined; - } - const delegationRequests = this.generated.stores.delegation.getDelegationRequests( - publicDeriver - ); - if (delegationRequests == null) return undefined; - if ( - !delegationRequests.getDelegatedBalance.wasExecuted || - delegationRequests.getDelegatedBalance.isExecuting || - delegationRequests.getDelegatedBalance.result == null - ) { - return undefined; - } - return delegationRequests.getDelegatedBalance.result.stakeRegistered; + return this.generated.stores.delegation.isStakeRegistered(publicDeriver); }; @computed get generated(): {| @@ -545,6 +515,9 @@ class CardanoStakingPage extends Component { |}, delegation: {| getDelegationRequests: (PublicDeriver<>) => void | DelegationRequests, + getRewardBalance: (PublicDeriver<>) => ?MultiToken, + getDelegatedPoolId: (PublicDeriver<>) => ?string, + isStakeRegistered: (PublicDeriver<>) => ?boolean, getLocalPoolInfo: ($ReadOnly, string) => void | PoolMeta, poolInfoQuery: {| error: ?LocalizableError, @@ -632,6 +605,9 @@ class CardanoStakingPage extends Component { }, delegation: { getDelegationRequests: stores.delegation.getDelegationRequests, + getRewardBalance: stores.delegation.getRewardBalance, + getDelegatedPoolId: stores.delegation.getDelegatedPoolId, + isStakeRegistered: stores.delegation.isStakeRegistered, getLocalPoolInfo: stores.delegation.getLocalPoolInfo, poolInfoQuery: { isExecuting: stores.delegation.poolInfoQuery.isExecuting, diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 6c73c3da59..272056b422 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -1,28 +1,26 @@ // @flow -import { observable, action, } from 'mobx'; +import { action, observable, } from 'mobx'; import { find } from 'lodash'; import type { NetworkRow } from '../../api/ada/lib/storage/database/primitives/tables'; -import { - PublicDeriver, -} from '../../api/ada/lib/storage/models/PublicDeriver/index'; +import { PublicDeriver, } from '../../api/ada/lib/storage/models/PublicDeriver/index'; import LocalizedRequest from '../lib/LocalizedRequest'; import Store from '../base/Store'; import type { + GetCurrentDelegationFunc, GetDelegatedBalanceFunc, RewardHistoryFunc, - GetCurrentDelegationFunc, } from '../../api/common/lib/storage/bridge/delegationUtils'; +import { GetDelegatedBalanceResponse } from '../../api/common/lib/storage/bridge/delegationUtils'; import CachedRequest from '../lib/LocalizedCachedRequest'; import LocalizableError from '../../i18n/LocalizableError'; import { getApiForNetwork } from '../../api/common/utils'; -import { - PoolMissingApiError, -} from '../../api/common/errors'; +import { PoolMissingApiError, } from '../../api/common/errors'; import type { MangledAmountFunc } from '../stateless/mangledAddresses'; import type { ActionsMap } from '../../actions/index'; import type { StoresMap } from '../index'; import type { PoolInfo } from '@emurgo/yoroi-lib'; +import { MultiToken } from '../../api/common/lib/MultiToken'; export type DelegationRequests = {| publicDeriver: PublicDeriver<>, @@ -122,6 +120,28 @@ export default class DelegationStore extends Store { return undefined; // can happen if the wallet is not a Shelley wallet } + _getDelegatedBalabceResult: PublicDeriver<> => ?GetDelegatedBalanceResponse = (publicDeriver) => { + const delegationRequest = this.stores.delegation.getDelegationRequests(publicDeriver); + if (delegationRequest == null) return null; + return delegationRequest.getDelegatedBalance.result; + } + + getRewardBalance: PublicDeriver<> => ?MultiToken = (publicDeriver) => { + if (this.stores.transactions.hasPendingWithdrawals(publicDeriver)) { + // In case we have a pending tx that already spends the rewards + return null; + } + return this._getDelegatedBalabceResult(publicDeriver)?.accountPart ?? null; + } + + getDelegatedPoolId: PublicDeriver<> => ?string = (publicDeriver) => { + return this._getDelegatedBalabceResult(publicDeriver)?.delegation ?? null; + } + + isStakeRegistered: PublicDeriver<> => ?boolean = (publicDeriver) => { + return this._getDelegatedBalabceResult(publicDeriver)?.stakeRegistered ?? null; + } + getLocalPoolInfo: ( $ReadOnly, string, diff --git a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js index 5faded2943..93903dfb39 100644 --- a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js @@ -857,6 +857,14 @@ export default class TransactionsStore extends Store { .map(tx => tx.transaction); }; + hasPendingWithdrawals: (PublicDeriver<>) => boolean = (publicDeriver) => { + return this._submittedTransactions.some(tx => { + return tx.publicDeriverId === publicDeriver.publicDeriverId + // legacy type check, fix so the type is always this + && tx.transaction instanceof CardanoShelleyTransaction && tx.transaction.withdrawals.length > 0; + }); + } + @action clearSubmittedTransactions: (PublicDeriver<>) => void = publicDeriver => { for (let i = 0; i < this._submittedTransactions.length; ) { From 7a3b8f96a9a75bca8bac0028a894f6df2888fab8 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Fri, 26 Jan 2024 19:47:11 +0300 Subject: [PATCH 02/13] fixed displaying rewards balance when no utxo balance is present --- .../app/components/topbar/NavWalletDetailsRevamp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js index 771d4f203a..79efe8f3c6 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js @@ -168,7 +168,7 @@ export default class NavWalletDetailsRevamp extends Component { return this.props.walletAmount; } if (this.props.walletAmount == null) { - return null; + return this.props.rewards; } return this.props.rewards.joinAddCopy(this.props.walletAmount); }; From bc8a670fe86805e1bc1f0372f845fb37b346fa95 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Fri, 26 Jan 2024 19:49:57 +0300 Subject: [PATCH 03/13] flow fixes --- .../app/components/wallet/my-wallets/WalletDetails.js | 2 +- packages/yoroi-extension/app/stores/toplevel/DelegationStore.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js b/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js index 8e591d60c9..e08239062c 100644 --- a/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js +++ b/packages/yoroi-extension/app/components/wallet/my-wallets/WalletDetails.js @@ -27,7 +27,7 @@ type Props = {| @observer export default class WalletDetails extends Component { - static defaultProps: {| infoText: void, rewards: null |} = { + static defaultProps: {| infoText: void |} = { infoText: undefined, }; diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 272056b422..56241b8141 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -11,7 +11,7 @@ import type { GetDelegatedBalanceFunc, RewardHistoryFunc, } from '../../api/common/lib/storage/bridge/delegationUtils'; -import { GetDelegatedBalanceResponse } from '../../api/common/lib/storage/bridge/delegationUtils'; +import type { GetDelegatedBalanceResponse } from '../../api/common/lib/storage/bridge/delegationUtils'; import CachedRequest from '../lib/LocalizedCachedRequest'; import LocalizableError from '../../i18n/LocalizableError'; import { getApiForNetwork } from '../../api/common/utils'; From 75ae120e726e820c6e866d86cf7ee318027f3f06 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Fri, 26 Jan 2024 19:58:30 +0300 Subject: [PATCH 04/13] typo fix --- .../app/stores/toplevel/DelegationStore.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 56241b8141..25741a97ef 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -120,7 +120,7 @@ export default class DelegationStore extends Store { return undefined; // can happen if the wallet is not a Shelley wallet } - _getDelegatedBalabceResult: PublicDeriver<> => ?GetDelegatedBalanceResponse = (publicDeriver) => { + _getDelegatedBalanceResult: PublicDeriver<> => ?GetDelegatedBalanceResponse = (publicDeriver) => { const delegationRequest = this.stores.delegation.getDelegationRequests(publicDeriver); if (delegationRequest == null) return null; return delegationRequest.getDelegatedBalance.result; @@ -131,15 +131,15 @@ export default class DelegationStore extends Store { // In case we have a pending tx that already spends the rewards return null; } - return this._getDelegatedBalabceResult(publicDeriver)?.accountPart ?? null; + return this._getDelegatedBalanceResult(publicDeriver)?.accountPart ?? null; } getDelegatedPoolId: PublicDeriver<> => ?string = (publicDeriver) => { - return this._getDelegatedBalabceResult(publicDeriver)?.delegation ?? null; + return this._getDelegatedBalanceResult(publicDeriver)?.delegation ?? null; } isStakeRegistered: PublicDeriver<> => ?boolean = (publicDeriver) => { - return this._getDelegatedBalabceResult(publicDeriver)?.stakeRegistered ?? null; + return this._getDelegatedBalanceResult(publicDeriver)?.stakeRegistered ?? null; } getLocalPoolInfo: ( From daeade5b5c8344b7a93bb68e4509a9cf82e15255 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Fri, 26 Jan 2024 19:59:35 +0300 Subject: [PATCH 05/13] lint fixes --- .../app/containers/wallet/staking/CardanoStakingPage.js | 5 +---- .../yoroi-extension/app/stores/toplevel/DelegationStore.js | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js index 853a9abb7a..3ce5e4d401 100644 --- a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js +++ b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js @@ -39,10 +39,7 @@ import type { LayoutComponentMap } from '../../../styles/context/layout'; import { Box } from '@mui/system'; import type { PoolData } from './SeizaFetcher'; import type { WalletChecksum } from '@emurgo/cip4-js'; -import { - isCardanoHaskell, - isTestnet, -} from '../../../api/ada/lib/storage/database/prepackaged/networks'; +import { isTestnet } from '../../../api/ada/lib/storage/database/prepackaged/networks'; export type GeneratedData = typeof CardanoStakingPage.prototype.generated; diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 25741a97ef..b529a1726b 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -10,8 +10,8 @@ import type { GetCurrentDelegationFunc, GetDelegatedBalanceFunc, RewardHistoryFunc, + GetDelegatedBalanceResponse, } from '../../api/common/lib/storage/bridge/delegationUtils'; -import type { GetDelegatedBalanceResponse } from '../../api/common/lib/storage/bridge/delegationUtils'; import CachedRequest from '../lib/LocalizedCachedRequest'; import LocalizableError from '../../i18n/LocalizableError'; import { getApiForNetwork } from '../../api/common/utils'; From b77315c3080c8cbfe38e86344435902da7415ec8 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Sat, 27 Jan 2024 23:38:43 +0300 Subject: [PATCH 06/13] disabled pending withdrawals check --- .../app/stores/toplevel/DelegationStore.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index b529a1726b..730ee55aec 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -127,10 +127,10 @@ export default class DelegationStore extends Store { } getRewardBalance: PublicDeriver<> => ?MultiToken = (publicDeriver) => { - if (this.stores.transactions.hasPendingWithdrawals(publicDeriver)) { - // In case we have a pending tx that already spends the rewards - return null; - } + // if (this.stores.transactions.hasPendingWithdrawals(publicDeriver)) { + // // In case we have a pending tx that already spends the rewards + // return null; + // } return this._getDelegatedBalanceResult(publicDeriver)?.accountPart ?? null; } From 066905a5c66df12d0ffd7e3d4b69572c44dee567 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Sun, 28 Jan 2024 22:46:53 +0300 Subject: [PATCH 07/13] fixed to ignore yet unsynced local rewards in case a withdrawal has been processed --- .../app/stores/base/BaseCardanoTimeStore.js | 6 ++- .../app/stores/toplevel/DelegationStore.js | 9 ++-- .../app/stores/toplevel/TransactionsStore.js | 41 +++++++++++++------ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/packages/yoroi-extension/app/stores/base/BaseCardanoTimeStore.js b/packages/yoroi-extension/app/stores/base/BaseCardanoTimeStore.js index 8879297d80..7595607cd6 100644 --- a/packages/yoroi-extension/app/stores/base/BaseCardanoTimeStore.js +++ b/packages/yoroi-extension/app/stores/base/BaseCardanoTimeStore.js @@ -103,7 +103,11 @@ export default class BaseCardanoTimeStore extends Store { const currentRelativeTime = toRelativeSlotNumber(currentAbsoluteSlot.slot); runInAction(() => { - currTimeRequests.currentEpoch = currentRelativeTime.epoch; + if (currTimeRequests.currentEpoch !== currentRelativeTime.epoch) { + // Clearing processed withdrawals in case epoch changes + this.stores.transactions.clearProcessedWithdrawals(selected); + currTimeRequests.currentEpoch = currentRelativeTime.epoch; + } currTimeRequests.currentSlot = currentRelativeTime.slot; currTimeRequests.msIntoSlot = currentAbsoluteSlot.msIntoSlot; }); diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 730ee55aec..7934f941be 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -127,10 +127,11 @@ export default class DelegationStore extends Store { } getRewardBalance: PublicDeriver<> => ?MultiToken = (publicDeriver) => { - // if (this.stores.transactions.hasPendingWithdrawals(publicDeriver)) { - // // In case we have a pending tx that already spends the rewards - // return null; - // } + if (this.stores.transactions.hasProcessedWithdrawals(publicDeriver)) { + // In case we have a processed withdrawal for the wallet + // We cancel out any still present reward, in case it has not synced yet + return null; + } return this._getDelegatedBalanceResult(publicDeriver)?.accountPart ?? null; } diff --git a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js index 93903dfb39..1d20e8c9d6 100644 --- a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js @@ -48,10 +48,7 @@ import { PRIMARY_ASSET_CONSTANTS } from '../../api/ada/lib/storage/database/prim import type { NetworkRow } from '../../api/ada/lib/storage/database/primitives/tables'; import type { CardanoAddressedUtxo } from '../../api/ada/transactions/types'; import moment from 'moment'; -import { - loadSubmittedTransactions, - persistSubmittedTransactions, -} from '../../api/localStorage'; +import { loadSubmittedTransactions, persistSubmittedTransactions, } from '../../api/localStorage'; import { getAllAddressesForWallet } from '../../api/ada/lib/storage/bridge/traitUtils'; import { toRequestAddresses } from '../../api/ada/lib/storage/bridge/updateTransactions' import type { TransactionExportRow } from '../../api/export'; @@ -114,6 +111,15 @@ export default class TransactionsStore extends Store { @observable _submittedTransactions: Array = []; + /* + * This transient state only used to store a flag that a reward withdrawal has been processed for some wallet. + * Needed to cancel out the utxo balance being synced before the reward balance which was causing a higher + * total balance to be displayed for few seconds. + * + * NOT PERSISTED + */ + @observable _processedWithdrawals: Array = []; + getTransactionRowsToExportRequest: LocalizedRequest< ((void) => Promise) => Promise > = new LocalizedRequest<((void) => Promise) => Promise>(func => func()); @@ -277,12 +283,14 @@ export default class TransactionsStore extends Store { _afterLoadingNewTxs: ( Array, PublicDeriver<>, - ) => Promise = async (result, publicDeriver) => { + ) => Promise = async (result: Array, publicDeriver: PublicDeriver<>) => { const timestamps: Set = new Set(); const remoteTransactionIds: Set = new Set(); - for (const { txid, date } of result) { + let walletHasWithdrawal = false; + for (const { txid, date, withdrawals } of result) { timestamps.add(date.valueOf()); remoteTransactionIds.add(txid); + walletHasWithdrawal = walletHasWithdrawal || (withdrawals?.length > 0); } const defaultTokenInfo = this.stores.tokenInfoStore.getDefaultTokenInfo( publicDeriver.getParent().getNetworkInfo().NetworkId, @@ -299,6 +307,9 @@ export default class TransactionsStore extends Store { let submittedTransactionsChanged = false; runInAction(() => { + if (walletHasWithdrawal) { + this._processedWithdrawals.push(publicDeriver.publicDeriverId); + } for (let i = 0; i < this._submittedTransactions.length; ) { if (remoteTransactionIds.has(this._submittedTransactions[i].transaction.txid)) { this._submittedTransactions.splice(i, 1); @@ -857,12 +868,18 @@ export default class TransactionsStore extends Store { .map(tx => tx.transaction); }; - hasPendingWithdrawals: (PublicDeriver<>) => boolean = (publicDeriver) => { - return this._submittedTransactions.some(tx => { - return tx.publicDeriverId === publicDeriver.publicDeriverId - // legacy type check, fix so the type is always this - && tx.transaction instanceof CardanoShelleyTransaction && tx.transaction.withdrawals.length > 0; - }); + hasProcessedWithdrawals: (PublicDeriver<>) => boolean = (publicDeriver) => { + return this._processedWithdrawals.includes(publicDeriver.publicDeriverId); + } + + clearProcessedWithdrawals: (PublicDeriver<>) => boolean = (publicDeriver) => { + for (let i = 0; i < this._processedWithdrawals.length; ) { + if (this._processedWithdrawals[i] === publicDeriver.publicDeriverId) { + this._processedWithdrawals.splice(i, 1); + } else { + i++; + } + } } @action From 37c129b4c2d37da61caff1689cfa99b33e4ae2c7 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Sun, 28 Jan 2024 23:18:00 +0300 Subject: [PATCH 08/13] fixed to account for withdrawals in tx amounts --- packages/yoroi-extension/app/api/ada/index.js | 3 +++ .../app/components/wallet/transactions/TransactionRevamp.js | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/yoroi-extension/app/api/ada/index.js b/packages/yoroi-extension/app/api/ada/index.js index 46232b489d..ed25b04d86 100644 --- a/packages/yoroi-extension/app/api/ada/index.js +++ b/packages/yoroi-extension/app/api/ada/index.js @@ -2398,6 +2398,9 @@ export default class AdaApi { for (const input of signRequest.inputs()) { amount.joinSubtractMutable(input.value); } + for (const withdrawal of signRequest.withdrawals()) { + amount.joinSubtractMutable(withdrawal.amount); + } let isIntraWallet = true; for (const output of signRequest.outputs()) { if (ownAddresses.has(output.address)) { diff --git a/packages/yoroi-extension/app/components/wallet/transactions/TransactionRevamp.js b/packages/yoroi-extension/app/components/wallet/transactions/TransactionRevamp.js index 3f91fd230e..6420b79370 100644 --- a/packages/yoroi-extension/app/components/wallet/transactions/TransactionRevamp.js +++ b/packages/yoroi-extension/app/components/wallet/transactions/TransactionRevamp.js @@ -297,9 +297,6 @@ export default class TransactionRevamp extends Component { ); } - const amount = this.renderAmountDisplay({ entry: request.entry, getRawNumber: true }); - const isPositiveNumber = typeof amount === 'string' ? amount.charAt(0) === '+' : false; // eslint-disable-line - return ( {this.renderAmountDisplay({ entry: request.entry })} {this.getTicker(request.entry)} @@ -957,6 +954,7 @@ export default class TransactionRevamp extends Component { data, address, addressIndex, + transform: amount => amount.abs().negated(), }); })}
From 40f06673c7aecdaa8fd2f1e907be103b6b20f7cc Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Tue, 30 Jan 2024 12:34:57 +0300 Subject: [PATCH 09/13] after merge updates --- .../yoroi-extension/app/containers/NavBarContainer.js | 2 +- .../app/containers/NavBarContainerRevamp.js | 2 +- .../app/containers/wallet/MyWalletsPage.js | 2 +- .../wallet/dialogs/WalletRestoreDialogContainer.js | 2 +- .../containers/wallet/staking/CardanoStakingPage.js | 10 +++++----- .../app/stores/toplevel/DelegationStore.js | 1 - .../app/stores/toplevel/TransactionsStore.js | 9 ++++++--- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/yoroi-extension/app/containers/NavBarContainer.js b/packages/yoroi-extension/app/containers/NavBarContainer.js index 91f35c577b..d39d5d278e 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainer.js +++ b/packages/yoroi-extension/app/containers/NavBarContainer.js @@ -170,6 +170,6 @@ export default class NavBarContainer extends Component { } getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.generated.stores.delegation.getRewardBalance(publicDeriver); + return this.props.stores.delegation.getRewardBalance(publicDeriver); }; } diff --git a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js index 52b971e916..2ea19330d4 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js +++ b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js @@ -230,6 +230,6 @@ export default class NavBarContainerRevamp extends Component { }; getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - return this.generated.stores.delegation.getRewardBalance(publicDeriver); + return this.props.stores.delegation.getRewardBalance(publicDeriver); }; } diff --git a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js index 133f00984f..2f40347b65 100644 --- a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js +++ b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js @@ -325,7 +325,7 @@ class MyWalletsPage extends Component { }; getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.generated.stores.delegation.getRewardBalance(publicDeriver); + return this.props.stores.delegation.getRewardBalance(publicDeriver); }; } export default (withLayout(MyWalletsPage): ComponentType); diff --git a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js index f58c59f8f5..b207bb27e1 100644 --- a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js +++ b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js @@ -88,7 +88,7 @@ export default class WalletRestoreDialogContainer extends Component { }; getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.generated.stores.delegation.getRewardBalance(publicDeriver); + return this.props.stores.delegation.getRewardBalance(publicDeriver); }; openToTransactions: (PublicDeriver<>) => void = publicDeriver => { diff --git a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js index 96f19ac827..ff444dda17 100644 --- a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js +++ b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js @@ -78,7 +78,7 @@ class CardanoStakingPage extends Component { const selectedPlate = this.props.stores.wallets.activeWalletPlate; const stakingListBias = selectedPlate?.TextPart || 'bias'; - const delegatedPoolId = this.generated.stores.delegation.getDelegatedPoolId(selectedWallet); + const delegatedPoolId = this.props.stores.delegation.getDelegatedPoolId(selectedWallet); if (urlTemplate != null) { const totalAda = this._getTotalAda(); const locale = this.props.stores.profile.currentLocale; @@ -181,14 +181,14 @@ class CardanoStakingPage extends Component { throw new Error(`${nameof(CardanoStakingPage)} no public deriver. Should never happen`); } - const delegationStore = this.generated.stores.delegation; - const balance = this.generated.stores.transactions.getBalance(publicDeriver); + const delegationStore = this.props.stores.delegation; + const balance = this.props.stores.transactions.getBalance(publicDeriver); if (balance == null) { return null; } const rewardBalance = delegationStore.getRewardBalance(publicDeriver) ?? new MultiToken([], publicDeriver.getParent().getDefaultToken()); - const tokenInfo = genLookupOrFail(this.generated.stores.tokenInfoStore.tokenInfo)( + const tokenInfo = genLookupOrFail(this.props.stores.tokenInfoStore.tokenInfo)( rewardBalance.getDefaultEntry() ); return balance @@ -450,7 +450,7 @@ class CardanoStakingPage extends Component { }; _isRegistered: (PublicDeriver<>) => ?boolean = publicDeriver => { - return this.generated.stores.delegation.isStakeRegistered(publicDeriver); + return this.props.stores.delegation.isStakeRegistered(publicDeriver); }; } diff --git a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js index 60cabe4558..bf4b5a9687 100644 --- a/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/DelegationStore.js @@ -14,7 +14,6 @@ import type { } from '../../api/common/lib/storage/bridge/delegationUtils'; import CachedRequest from '../lib/LocalizedCachedRequest'; import LocalizableError from '../../i18n/LocalizableError'; -import { getApiForNetwork } from '../../api/common/utils'; import { PoolMissingApiError, } from '../../api/common/errors'; import type { MangledAmountFunc } from '../stateless/mangledAddresses'; import type { ActionsMap } from '../../actions/index'; diff --git a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js index ef3795d4b2..81cce0fe66 100644 --- a/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js +++ b/packages/yoroi-extension/app/stores/toplevel/TransactionsStore.js @@ -286,10 +286,13 @@ export default class TransactionsStore extends Store { const timestamps: Set = new Set(); const remoteTransactionIds: Set = new Set(); let walletHasWithdrawal = false; - for (const { txid, date, withdrawals } of result) { + for (const tx of result) { + const { txid, date } = tx; timestamps.add(date.valueOf()); remoteTransactionIds.add(txid); - walletHasWithdrawal = walletHasWithdrawal || (withdrawals?.length > 0); + if (tx instanceof CardanoShelleyTransaction && tx.withdrawals.length > 0) { + walletHasWithdrawal = true; + } } const defaultTokenInfo = this.stores.tokenInfoStore.getDefaultTokenInfo( publicDeriver.getParent().getNetworkInfo().NetworkId, @@ -869,7 +872,7 @@ export default class TransactionsStore extends Store { return this._processedWithdrawals.includes(publicDeriver.publicDeriverId); } - clearProcessedWithdrawals: (PublicDeriver<>) => boolean = (publicDeriver) => { + clearProcessedWithdrawals: (PublicDeriver<>) => void = (publicDeriver) => { for (let i = 0; i < this._processedWithdrawals.length; ) { if (this._processedWithdrawals[i] === publicDeriver.publicDeriverId) { this._processedWithdrawals.splice(i, 1); From e465ad7cb114a76340e3281b7768cc64eb507731 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Tue, 30 Jan 2024 12:38:00 +0300 Subject: [PATCH 10/13] lint fixes --- .../app/containers/wallet/staking/CardanoStakingPage.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js index ff444dda17..38c9656770 100644 --- a/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js +++ b/packages/yoroi-extension/app/containers/wallet/staking/CardanoStakingPage.js @@ -33,10 +33,7 @@ import { withLayout } from '../../../styles/context/layout'; import type { LayoutComponentMap } from '../../../styles/context/layout'; import { Box } from '@mui/system'; import type { PoolData } from './SeizaFetcher'; -import { - isCardanoHaskell, - isTestnet, -} from '../../../api/ada/lib/storage/database/prepackaged/networks'; +import { isTestnet } from '../../../api/ada/lib/storage/database/prepackaged/networks'; type Props = {| ...StoresAndActionsProps, From d5e8842bd02efe3c21431eec63dec10bff74815b Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Wed, 31 Jan 2024 00:21:49 +0300 Subject: [PATCH 11/13] fixed amount calculation --- .../app/api/common/lib/MultiToken.js | 10 ++++++++ .../app/components/common/AmountDisplay.js | 2 +- .../app/components/topbar/NavWalletDetails.js | 10 ++------ .../topbar/NavWalletDetailsRevamp.js | 10 ++------ .../app/components/topbar/WalletCard.js | 25 ++++++------------- 5 files changed, 23 insertions(+), 34 deletions(-) diff --git a/packages/yoroi-extension/app/api/common/lib/MultiToken.js b/packages/yoroi-extension/app/api/common/lib/MultiToken.js index 2e7128683b..49fa4481b4 100644 --- a/packages/yoroi-extension/app/api/common/lib/MultiToken.js +++ b/packages/yoroi-extension/app/api/common/lib/MultiToken.js @@ -26,6 +26,16 @@ export class MultiToken { values: Array; defaults: DefaultTokenEntry; + /** + * If both passed tokens are not null - they are added. + * If either is null - the one not null is returned. + * If both is null - null is returned. + */ + static sumOrEitherNotNull(token1: ?MultiToken, token2: ?MultiToken): ?MultiToken { + if (token1 == null || token2 == null) return token1 ?? token2; + return token1.joinAddCopy(token2); + } + static from(multiTokenData: {| values: Array<{| identifier: string, networkId: number, amount: string |}>, defaults: DefaultTokenEntry, diff --git a/packages/yoroi-extension/app/components/common/AmountDisplay.js b/packages/yoroi-extension/app/components/common/AmountDisplay.js index c0a93c48b3..0ec619a3fe 100644 --- a/packages/yoroi-extension/app/components/common/AmountDisplay.js +++ b/packages/yoroi-extension/app/components/common/AmountDisplay.js @@ -17,7 +17,7 @@ type Props = {| +showFiat?: boolean, +shouldHideBalance: boolean, +getTokenInfo: ($ReadOnly>) => $ReadOnly, - +amount: null | MultiToken, + +amount: ?MultiToken, +unitOfAccountSetting: UnitOfAccountSettingType, +getCurrentPrice: (from: string, to: string) => ?string, |}; diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js index de7759054f..a004700540 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetails.js @@ -167,14 +167,8 @@ export default class NavWalletDetails extends Component { ); } - getTotalAmount: void => (null | MultiToken) = () => { - if (this.props.rewards === undefined) { - return this.props.walletAmount; - } - if (this.props.rewards === null || this.props.walletAmount === null) { - return null; - } - return this.props.walletAmount.joinAddCopy(this.props.rewards); + getTotalAmount: void => ?MultiToken = () => { + return MultiToken.sumOrEitherNotNull(this.props.walletAmount, this.props.rewards); } renderAmountDisplay: {| diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js index 79efe8f3c6..3dea59162b 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js @@ -163,13 +163,7 @@ export default class NavWalletDetailsRevamp extends Component { ); } - getTotalAmount: void => null | MultiToken = () => { - if (this.props.rewards == null) { - return this.props.walletAmount; - } - if (this.props.walletAmount == null) { - return this.props.rewards; - } - return this.props.rewards.joinAddCopy(this.props.walletAmount); + getTotalAmount: void => ?MultiToken = () => { + return MultiToken.sumOrEitherNotNull(this.props.walletAmount, this.props.rewards) }; } diff --git a/packages/yoroi-extension/app/components/topbar/WalletCard.js b/packages/yoroi-extension/app/components/topbar/WalletCard.js index decc37d43e..7a1f8ade4a 100644 --- a/packages/yoroi-extension/app/components/topbar/WalletCard.js +++ b/packages/yoroi-extension/app/components/topbar/WalletCard.js @@ -1,23 +1,20 @@ // @flow -import { Component } from 'react'; import type { Node } from 'react'; +import { Component } from 'react'; import { observer } from 'mobx-react'; -import { intlShape, defineMessages } from 'react-intl'; +import type { $npm$ReactIntl$IntlFormat, $npm$ReactIntl$MessageDescriptor } from 'react-intl'; +import { defineMessages, intlShape } from 'react-intl'; import styles from './WalletCard.scss'; import WalletAccountIcon from './WalletAccountIcon'; +import type { TokenLookupKey } from '../../api/common/lib/MultiToken'; import { MultiToken } from '../../api/common/lib/MultiToken'; import classnames from 'classnames'; import type { WalletChecksum } from '@emurgo/cip4-js'; -import type { $npm$ReactIntl$IntlFormat, $npm$ReactIntl$MessageDescriptor } from 'react-intl'; import type { ConceptualWallet } from '../../api/ada/lib/storage/models/ConceptualWallet/index'; +import { isLedgerNanoWallet, isTrezorTWallet, } from '../../api/ada/lib/storage/models/ConceptualWallet/index'; import globalMessages from '../../i18n/global-messages'; -import { - isLedgerNanoWallet, - isTrezorTWallet, -} from '../../api/ada/lib/storage/models/ConceptualWallet/index'; -import type { TokenLookupKey } from '../../api/common/lib/MultiToken'; import type { TokenRow } from '../../api/ada/lib/storage/database/primitives/tables'; -import { ReactComponent as DragIcon } from '../../assets/images/add-wallet/wallet-list/drag.inline.svg'; +import { ReactComponent as DragIcon } from '../../assets/images/add-wallet/wallet-list/drag.inline.svg'; import { Draggable } from 'react-beautiful-dnd'; import type { UnitOfAccountSettingType } from '../../types/unitOfAccountType'; import AmountDisplay from '../common/AmountDisplay'; @@ -192,14 +189,8 @@ export default class WalletCard extends Component { ); } - getTotalAmount: void => null | MultiToken = () => { - if (this.props.rewards === undefined) { - return this.props.walletAmount; - } - if (this.props.rewards === null || this.props.walletAmount === null) { - return null; - } - return this.props.rewards.joinAddCopy(this.props.walletAmount); + getTotalAmount: void => ?MultiToken = () => { + return MultiToken.sumOrEitherNotNull(this.props.walletAmount, this.props.rewards); }; countTokenTypes: void => {|tokenTypes: number, nfts: number|} = () => { From cd53ebdb82d98ece8fbeff25a52eac09f8a16a22 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Wed, 31 Jan 2024 19:37:38 +0300 Subject: [PATCH 12/13] reward balance fix --- .../topbar/NavWalletDetailsRevamp.js | 2 +- .../app/containers/NavBarContainer.js | 14 ++++++-------- .../app/containers/NavBarContainerRevamp.js | 18 +++++++----------- .../app/containers/wallet/MyWalletsPage.js | 7 ++----- .../dialogs/WalletRestoreDialogContainer.js | 7 ++----- .../app/stores/toplevel/TransactionsStore.js | 7 ++++--- 6 files changed, 22 insertions(+), 33 deletions(-) diff --git a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js index 3dea59162b..f9bb67d3aa 100644 --- a/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js +++ b/packages/yoroi-extension/app/components/topbar/NavWalletDetailsRevamp.js @@ -164,6 +164,6 @@ export default class NavWalletDetailsRevamp extends Component { } getTotalAmount: void => ?MultiToken = () => { - return MultiToken.sumOrEitherNotNull(this.props.walletAmount, this.props.rewards) + return MultiToken.sumOrEitherNotNull(this.props.walletAmount, this.props.rewards); }; } diff --git a/packages/yoroi-extension/app/containers/NavBarContainer.js b/packages/yoroi-extension/app/containers/NavBarContainer.js index d39d5d278e..80fc6a1e21 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainer.js +++ b/packages/yoroi-extension/app/containers/NavBarContainer.js @@ -57,7 +57,8 @@ export default class NavBarContainer extends Component { const wallets = this.props.stores.wallets.publicDerivers; const walletComponents = wallets.map(wallet => { - const balance = this.props.stores.transactions.balance; + const balance = this.props.stores.transactions.getBalance(wallet); + const rewards = this.props.stores.delegation.getRewardBalance(wallet); const lastSyncInfo = this.props.stores.transactions.lastSyncInfo; const parent = wallet.getParent(); @@ -81,9 +82,9 @@ export default class NavBarContainer extends Component { detailComponent={ { return ; } - const balance = this.props.stores.transactions.balance; + const balance = this.props.stores.transactions.getBalance(publicDeriver); + const rewards = this.props.stores.delegation.getRewardBalance(publicDeriver); return ( { ); } - - getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.props.stores.delegation.getRewardBalance(publicDeriver); - }; } diff --git a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js index 2ea19330d4..1599b4fcc8 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js +++ b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js @@ -76,6 +76,7 @@ export default class NavBarContainerRevamp extends Component { : this.props.stores.wallets.getPublicKeyCache(withPubKey).plate; const balance = this.props.stores.transactions.getBalance(publicDeriver); + const rewards = this.props.stores.delegation.getRewardBalance(publicDeriver); return ( { wallet={settingsCache} onUpdateHideBalance={this.updateHideBalance} shouldHideBalance={profile.shouldHideBalance} - rewards={this.getRewardBalance(publicDeriver)} + rewards={rewards} walletAmount={balance} getTokenInfo={genLookupOrFail(this.props.stores.tokenInfoStore.tokenInfo)} defaultToken={this.props.stores.tokenInfoStore.getDefaultTokenInfo( @@ -129,11 +130,10 @@ export default class NavBarContainerRevamp extends Component { const cardanoWallets = []; wallets.forEach(wallet => { - const walletBalance = this.props.stores.transactions.getBalance(wallet); + const walletAmount = this.props.stores.transactions.getBalance(wallet); + const rewards = this.props.stores.delegation.getRewardBalance(wallet); const parent = wallet.getParent(); - const settingsCache = this.props.stores.walletSettings.getConceptualWalletSettingsCache( - parent - ); + const settingsCache = this.props.stores.walletSettings.getConceptualWalletSettingsCache(parent); const withPubKey = asGetPublicKey(wallet); const plate = @@ -143,8 +143,8 @@ export default class NavBarContainerRevamp extends Component { const walletMap = { walletId: wallet.getPublicDeriverId(), - rewards: this.getRewardBalance(wallet), - walletAmount: walletBalance, + rewards, + walletAmount, getTokenInfo: genLookupOrFail(this.props.stores.tokenInfoStore.tokenInfo), plate, wallet, @@ -228,8 +228,4 @@ export default class NavBarContainerRevamp extends Component { return acc; }, []); }; - - getRewardBalance: (PublicDeriver<>) => null | void | MultiToken = publicDeriver => { - return this.props.stores.delegation.getRewardBalance(publicDeriver); - }; } diff --git a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js index 2f40347b65..6c28cbb50c 100644 --- a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js +++ b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js @@ -218,6 +218,7 @@ class MyWalletsPage extends Component { })(); const balance = this.props.stores.transactions.getBalance(publicDeriver); + const rewards = this.props.stores.delegation.getRewardBalance(publicDeriver); const withPubKey = asGetPublicKey(publicDeriver); const plate = @@ -237,7 +238,7 @@ class MyWalletsPage extends Component { walletSumDetails={ { return walletSubRow; }; - - getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.props.stores.delegation.getRewardBalance(publicDeriver); - }; } export default (withLayout(MyWalletsPage): ComponentType); diff --git a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js index b207bb27e1..3bc303f310 100644 --- a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js +++ b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js @@ -87,10 +87,6 @@ export default class WalletRestoreDialogContainer extends Component { await this.props.actions.profile.updateHideBalance.trigger(); }; - getRewardBalance: (PublicDeriver<>) => ?MultiToken = publicDeriver => { - return this.props.stores.delegation.getRewardBalance(publicDeriver); - }; - openToTransactions: (PublicDeriver<>) => void = publicDeriver => { this.props.actions.wallets.setActiveWallet.trigger({ wallet: publicDeriver, @@ -155,6 +151,7 @@ export default class WalletRestoreDialogContainer extends Component { ? null : this.props.stores.wallets.getPublicKeyCache(withPubKey).plate; const balance = this.props.stores.transactions.getBalance(publicDeriver); + const rewards = this.props.stores.delegation.getRewardBalance(publicDeriver); return ( { walletSumDetails={ { let submittedTransactionsChanged = false; runInAction(() => { - if (walletHasWithdrawal) { - this._processedWithdrawals.push(publicDeriver.publicDeriverId); - } for (let i = 0; i < this._submittedTransactions.length; ) { if (remoteTransactionIds.has(this._submittedTransactions[i].transaction.txid)) { + if (walletHasWithdrawal) { + // Set local processed withdrawals only if there was a pending local transaction + this._processedWithdrawals.push(publicDeriver.publicDeriverId); + } this._submittedTransactions.splice(i, 1); submittedTransactionsChanged = true; } else { From de4b506cc66fea33f0d633dfad1ce39652b43bc9 Mon Sep 17 00:00:00 2001 From: vantuz-subhuman Date: Wed, 31 Jan 2024 23:44:48 +0300 Subject: [PATCH 13/13] lint fixes --- packages/yoroi-extension/app/containers/NavBarContainer.js | 1 - packages/yoroi-extension/app/containers/NavBarContainerRevamp.js | 1 - packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js | 1 - .../containers/wallet/dialogs/WalletRestoreDialogContainer.js | 1 - 4 files changed, 4 deletions(-) diff --git a/packages/yoroi-extension/app/containers/NavBarContainer.js b/packages/yoroi-extension/app/containers/NavBarContainer.js index 80fc6a1e21..6e9fe0de4f 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainer.js +++ b/packages/yoroi-extension/app/containers/NavBarContainer.js @@ -15,7 +15,6 @@ import { ROUTES } from '../routes-config'; import { asGetPublicKey } from '../api/ada/lib/storage/models/PublicDeriver/traits'; import { PublicDeriver } from '../api/ada/lib/storage/models/PublicDeriver'; import type { $npm$ReactIntl$IntlFormat } from 'react-intl'; -import { MultiToken } from '../api/common/lib/MultiToken'; import { genLookupOrFail } from '../stores/stateless/tokenHelpers'; import BuySellDialog from '../components/buySell/BuySellDialog'; import globalMessages from '../i18n/global-messages'; diff --git a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js index 1599b4fcc8..c92c0e5990 100644 --- a/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js +++ b/packages/yoroi-extension/app/containers/NavBarContainerRevamp.js @@ -10,7 +10,6 @@ import { ROUTES } from '../routes-config'; import { ConceptualWallet } from '../api/ada/lib/storage/models/ConceptualWallet/index'; import { asGetPublicKey } from '../api/ada/lib/storage/models/PublicDeriver/traits'; import { PublicDeriver } from '../api/ada/lib/storage/models/PublicDeriver'; -import { MultiToken } from '../api/common/lib/MultiToken'; import { genLookupOrFail, getTokenName } from '../stores/stateless/tokenHelpers'; import { networks } from '../api/ada/lib/storage/database/prepackaged/networks'; import { addressToDisplayString } from '../api/ada/lib/storage/bridge/utils'; diff --git a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js index 6c28cbb50c..ab754aa745 100644 --- a/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js +++ b/packages/yoroi-extension/app/containers/wallet/MyWalletsPage.js @@ -12,7 +12,6 @@ import { ROUTES } from '../../routes-config'; import { ConceptualWallet } from '../../api/ada/lib/storage/models/ConceptualWallet/index'; import { asGetPublicKey } from '../../api/ada/lib/storage/models/PublicDeriver/traits'; import { PublicDeriver } from '../../api/ada/lib/storage/models/PublicDeriver/index'; -import { MultiToken } from '../../api/common/lib/MultiToken'; import { genLookupOrFail, getTokenName } from '../../stores/stateless/tokenHelpers'; import { getReceiveAddress } from '../../stores/stateless/addressStores'; import { addressToDisplayString } from '../../api/ada/lib/storage/bridge/utils'; diff --git a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js index 3bc303f310..4c479849e0 100644 --- a/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js +++ b/packages/yoroi-extension/app/containers/wallet/dialogs/WalletRestoreDialogContainer.js @@ -28,7 +28,6 @@ import { asGetPublicKey } from '../../../api/ada/lib/storage/models/PublicDerive import { PublicDeriver } from '../../../api/ada/lib/storage/models/PublicDeriver'; import NavPlate from '../../../components/topbar/NavPlate'; import WalletDetails from '../../../components/wallet/my-wallets/WalletDetails'; -import { MultiToken } from '../../../api/common/lib/MultiToken'; import { ROUTES } from '../../../routes-config'; const messages = defineMessages({