diff --git a/packages/shared/components/activity-info/GenericActivityInformation.svelte b/packages/shared/components/activity-info/GenericActivityInformation.svelte index 9713e0ce988..531a78da616 100644 --- a/packages/shared/components/activity-info/GenericActivityInformation.svelte +++ b/packages/shared/components/activity-info/GenericActivityInformation.svelte @@ -28,7 +28,8 @@ $: formattedGiftedStorageDeposit = formatTokenAmountPrecise(activity?.giftedStorageDeposit ?? 0, getBaseToken()) $: formattedSurplus = formatTokenAmountPrecise(activity?.surplus ?? 0, getBaseToken()) $: formattedGasFee = formatTokenAmountPrecise(Number(gasFee ?? 0), getBaseToken()) - $: formattedManaPrefix = activity.direction === ActivityDirection.Incoming ? '' : '- ' + $: formattedManaPrefix = + activity.direction === ActivityDirection.Incoming || Number(activity?.mana) === 0 ? '' : '- ' $: formattedMana = formattedManaPrefix + formatTokenAmountBestMatch(Number(activity?.mana ?? 0), DEFAULT_MANA) let transactionDetailsList: IKeyValueBoxList diff --git a/packages/shared/lib/core/wallet/tests/formatTokenAmountDefault.test.ts b/packages/shared/lib/core/wallet/tests/formatTokenAmountDefault.test.ts index 8efbaaef983..01aecc32526 100644 --- a/packages/shared/lib/core/wallet/tests/formatTokenAmountDefault.test.ts +++ b/packages/shared/lib/core/wallet/tests/formatTokenAmountDefault.test.ts @@ -28,11 +28,13 @@ describe('File: formatTokenAmountDefault.ts', () => { }) it('should throw an error if amount is not an integer', () => { const amount = 42.069 - expect(() => formatTokenAmountDefault(amount, decimalToken)).toThrow() + const formattedAmount = formatTokenAmountDefault(amount, decimalToken) + expect(formattedAmount).toBe('-') }) it('should throw an error if amount is negative', () => { const amount = -42069 - expect(() => formatTokenAmountDefault(amount, decimalToken)).toThrow() + const formattedAmount = formatTokenAmountDefault(amount, decimalToken) + expect(formattedAmount).toBe('-') }) it('should add correct decimal character for german', () => { appSettings.update((state) => ({ ...state, language: 'de' })) diff --git a/packages/shared/lib/core/wallet/utils/formatTokenAmountDefault.ts b/packages/shared/lib/core/wallet/utils/formatTokenAmountDefault.ts index f0d7561e6fb..3e05d11fe76 100644 --- a/packages/shared/lib/core/wallet/utils/formatTokenAmountDefault.ts +++ b/packages/shared/lib/core/wallet/utils/formatTokenAmountDefault.ts @@ -8,15 +8,19 @@ export function formatTokenAmountDefault( unit?: string, useGrouping: boolean = true ): string { - if (amount < 0) { - throw new Error('Amount is negative') - } else if (isDecimal(amount)) { - throw new Error('Amount is a decimal number') - } else if (unit && tokenMetadata?.standard === TokenStandard.BaseToken && unit === tokenMetadata?.subunit) { - return formatNumber(amount, 0, 0, 0, useGrouping) - } else { - const value = tokenMetadata?.decimals ? amount / 10 ** tokenMetadata?.decimals : amount - return formatNumber(value, 0, tokenMetadata?.decimals ?? 0, 0, useGrouping) + try { + if (amount < 0) { + throw new Error('Amount is negative') + } else if (isDecimal(amount)) { + throw new Error('Amount is a decimal number') + } else if (unit && tokenMetadata?.standard === TokenStandard.BaseToken && unit === tokenMetadata?.subunit) { + return formatNumber(amount, 0, 0, 0, useGrouping) + } else { + const value = tokenMetadata?.decimals ? amount / 10 ** tokenMetadata?.decimals : amount + return formatNumber(value, 0, tokenMetadata?.decimals ?? 0, 0, useGrouping) + } + } catch (err) { + return '-' } } diff --git a/packages/shared/lib/core/wallet/utils/index.ts b/packages/shared/lib/core/wallet/utils/index.ts index 68e9d0a9eb7..5b9910fd607 100644 --- a/packages/shared/lib/core/wallet/utils/index.ts +++ b/packages/shared/lib/core/wallet/utils/index.ts @@ -39,6 +39,7 @@ export * from './syncWalletsInParallel' export * from './validateWalletName' export * from './isVisibleAsset' export * from './isVisibleActivity' +export * from './isOutputOfSelectedWalletAddress' // Folders export * from './generateActivity' diff --git a/packages/shared/lib/core/wallet/utils/isOutputOfSelectedWalletAddress.ts b/packages/shared/lib/core/wallet/utils/isOutputOfSelectedWalletAddress.ts new file mode 100644 index 00000000000..0beb20fb6e4 --- /dev/null +++ b/packages/shared/lib/core/wallet/utils/isOutputOfSelectedWalletAddress.ts @@ -0,0 +1,16 @@ +import { CommonOutput, UnlockConditionType, OutputData, AddressUnlockCondition } from '@iota/sdk/out/types' +import { selectedWallet } from '../stores' +import { get } from 'svelte/store' +import { AddressConverter } from './AddressConverter' + +export async function isOutputOfSelectedWalletAddress(outputData: OutputData): Promise { + const output = outputData.output as CommonOutput + const walletAddress = await get(selectedWallet)?.address() + const address = ( + output.unlockConditions.find( + (unlockCondition) => unlockCondition.type === UnlockConditionType.Address + ) as AddressUnlockCondition + ).address + const bech32Address = AddressConverter.addressToBech32(address) + return bech32Address === walletAddress +} diff --git a/packages/shared/lib/core/wallet/utils/outputs/preprocessIncomingTransaction.ts b/packages/shared/lib/core/wallet/utils/outputs/preprocessIncomingTransaction.ts index df339a85cea..364cb5620b8 100644 --- a/packages/shared/lib/core/wallet/utils/outputs/preprocessIncomingTransaction.ts +++ b/packages/shared/lib/core/wallet/utils/outputs/preprocessIncomingTransaction.ts @@ -26,7 +26,7 @@ export function preprocessIncomingTransaction(transaction: TransactionWithMetada const manaCost = outputs .filter((output) => !output.remainder) - .reduce((acc, output) => acc + Number(output.output.mana), 0) + .reduce((acc, output) => acc + Number(output.output.mana ?? 0), 0) return { outputs, diff --git a/packages/shared/lib/core/wallet/utils/outputs/preprocessOutgoingTransaction.ts b/packages/shared/lib/core/wallet/utils/outputs/preprocessOutgoingTransaction.ts index e2643a26001..4b4393787c6 100644 --- a/packages/shared/lib/core/wallet/utils/outputs/preprocessOutgoingTransaction.ts +++ b/packages/shared/lib/core/wallet/utils/outputs/preprocessOutgoingTransaction.ts @@ -1,12 +1,5 @@ import { IProcessedTransaction, IWrappedOutput } from '../../interfaces' -import { - AccountOutput, - Output, - OutputType, - OutputWithMetadata, - TransactionWithMetadata, - UTXOInput, -} from '@iota/sdk/out/types' +import { Output, OutputType, OutputWithMetadata, TransactionWithMetadata, UTXOInput } from '@iota/sdk/out/types' import { computeOutputId } from './computeOutputId' import { getOutputIdFromTransactionIdAndIndex } from './getOutputIdFromTransactionIdAndIndex' import { getDirectionFromOutgoingTransaction } from '../transactions' @@ -15,6 +8,9 @@ import { getPassiveManaForOutput } from '@core/network' import { MILLISECONDS_PER_SECOND } from '@core/utils' import { getUnixTimestampFromNodeInfoAndSlotIndex, nodeInfoProtocolParameters } from '@core/network' import { get } from 'svelte/store' +import { isImplicitAccountOutput } from '../isImplicitAccountOutput' +import { isOutputOfSelectedWalletAddress } from '../isOutputOfSelectedWalletAddress' +import { isAccountOutput } from '../isAccountOutput' export async function preprocessOutgoingTransaction( transaction: TransactionWithMetadata, @@ -39,16 +35,15 @@ export async function preprocessOutgoingTransaction( const inputs = await Promise.all(inputIds.map((inputId) => wallet.getOutput(inputId))) - let manaCost = 0 - const prevAccountOutput = inputs.find((input) => (input.output as AccountOutput).accountId) - if (prevAccountOutput) { - const prevMana = getPassiveManaForOutput(prevAccountOutput) ?? 0 - const postAccountOutput = outputs.find( - (output) => - (prevAccountOutput.output as AccountOutput).accountId === (output.output as AccountOutput).accountId - ) - manaCost = prevMana - Number(postAccountOutput?.output?.mana ?? 0) - } + const inputsToConsiderWhenCalculatingMana = inputs.filter( + (input) => isAccountOutput(input) || isImplicitAccountOutput(input) || isOutputOfSelectedWalletAddress(input) + ) + const prevManaCost = inputsToConsiderWhenCalculatingMana.reduce( + (acc, input) => acc + (getPassiveManaForOutput(input) ?? 0), + 0 + ) + + const postManaCost = outputs.reduce((acc, output) => acc + Number(output.output.mana ?? 0), 0) return { outputs: outputs, @@ -56,7 +51,7 @@ export async function preprocessOutgoingTransaction( direction, time: new Date(slotUnixTimestamp * MILLISECONDS_PER_SECOND), inclusionState: transaction.inclusionState, - mana: manaCost, + mana: prevManaCost - postManaCost, wrappedInputs: inputs, } }