Changeset View
Changeset View
Standalone View
Standalone View
apps/marlin-wallet/web/src/transaction-history.ts
| // Copyright (c) 2025 The Bitcoin developers | // Copyright (c) 2025 The Bitcoin developers | ||||
| // Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
| // file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
| import { webViewLog, webViewError } from './common'; | import { webViewLog, webViewError } from './common'; | ||||
| import { calculateTransactionAmountAtomsFromTx, atomsToUnit } from './amount'; | import { calculateTransactionAmountAtomsFromTx, atomsToUnit } from './amount'; | ||||
| import { Wallet } from 'ecash-wallet'; | import { Wallet } from 'ecash-wallet'; | ||||
| import { ChronikClient, type Tx } from 'chronik-client'; | import { ChronikClient, type Tx } from 'chronik-client'; | ||||
| import { getAddress } from './wallet'; | import { getAddress } from './wallet'; | ||||
| import { AppSettings } from './settings'; | import { AppSettings } from './settings'; | ||||
| import { formatPrice } from 'ecash-price'; | import { formatPrice } from 'ecash-price'; | ||||
| import type { MarlinPriceFetcher } from './price'; | import type { MarlinPriceFetcher } from './price'; | ||||
| import { | import { | ||||
| activeCryptoTicker, | |||||
| activeAssetDecimals, | activeAssetDecimals, | ||||
| activeTokenId, | activeTokenId, | ||||
| allowFiatForActiveAsset, | allowFiatForActiveAsset, | ||||
| activeQuoteCurrency, | activeQuoteCurrency, | ||||
| formatActiveAssetAmount, | |||||
| } from './active-asset'; | } from './active-asset'; | ||||
| // ============================================================================ | // ============================================================================ | ||||
| // TRANSACTION HISTORY MANAGER | // TRANSACTION HISTORY MANAGER | ||||
| // ============================================================================ | // ============================================================================ | ||||
| /** Visible rows to collect per initial load or scroll (token-filtered). */ | /** Visible rows to collect per initial load or scroll (token-filtered). */ | ||||
| export const VISIBLE_BATCH_TARGET = 25; | export const VISIBLE_BATCH_TARGET = 25; | ||||
| ▲ Show 20 Lines • Show All 217 Lines • ▼ Show 20 Lines | async displayTransactions(transactions: Tx[]): Promise<void> { | ||||
| const pricePerXec = allowFiatForActiveAsset() | const pricePerXec = allowFiatForActiveAsset() | ||||
| ? await this.priceFetcher?.current({ | ? await this.priceFetcher?.current({ | ||||
| source: activeQuoteCurrency(), | source: activeQuoteCurrency(), | ||||
| quote: this.appSettings.fiatCurrency, | quote: this.appSettings.fiatCurrency, | ||||
| }) | }) | ||||
| : null; | : null; | ||||
| const tokenId = activeTokenId(); | const tokenId = activeTokenId(); | ||||
| const primaryTicker = activeCryptoTicker(); | |||||
| const tokenDecimals = activeAssetDecimals(); | const tokenDecimals = activeAssetDecimals(); | ||||
| const xecFormatOptions = { | const xecFormatOptions = { | ||||
| locale: this.appSettings.locale, | locale: this.appSettings.locale, | ||||
| decimals: tokenDecimals, | decimals: tokenDecimals, | ||||
| alwaysShowSign: true, | alwaysShowSign: true, | ||||
| }; | }; | ||||
| const fiatFormatOptions = { | const fiatFormatOptions = { | ||||
| Show All 36 Lines | async displayTransactions(transactions: Tx[]): Promise<void> { | ||||
| const amountPrimary = atomsToUnit(atoms, activeAssetDecimals()); | const amountPrimary = atomsToUnit(atoms, activeAssetDecimals()); | ||||
| const isReceived = amountPrimary >= 0; | const isReceived = amountPrimary >= 0; | ||||
| const amountClass = isReceived ? 'received' : 'sent'; | const amountClass = isReceived ? 'received' : 'sent'; | ||||
| const primaryAmount = | const primaryAmount = | ||||
| this.appSettings.primaryBalanceType === 'XEC' || | this.appSettings.primaryBalanceType === 'XEC' || | ||||
| pricePerXec === null | pricePerXec === null | ||||
| ? formatPrice( | ? formatActiveAssetAmount(amountPrimary, xecFormatOptions) | ||||
| amountPrimary, | |||||
| primaryTicker, | |||||
| xecFormatOptions, | |||||
| ) | |||||
| : formatPrice( | : formatPrice( | ||||
| amountPrimary * pricePerXec, | amountPrimary * pricePerXec, | ||||
| this.appSettings.fiatCurrency, | this.appSettings.fiatCurrency, | ||||
| fiatFormatOptions, | fiatFormatOptions, | ||||
| ); | ); | ||||
| let secondaryAmount: string = ''; | let secondaryAmount: string = ''; | ||||
| if (pricePerXec !== null) { | if (pricePerXec !== null) { | ||||
| secondaryAmount = | secondaryAmount = | ||||
| this.appSettings.primaryBalanceType === 'XEC' | this.appSettings.primaryBalanceType === 'XEC' | ||||
| ? formatPrice( | ? formatPrice( | ||||
| amountPrimary * pricePerXec, | amountPrimary * pricePerXec, | ||||
| this.appSettings.fiatCurrency, | this.appSettings.fiatCurrency, | ||||
| fiatFormatOptions, | fiatFormatOptions, | ||||
| ) | ) | ||||
| : formatPrice( | : formatActiveAssetAmount( | ||||
| amountPrimary, | amountPrimary, | ||||
| primaryTicker, | |||||
| xecFormatOptions, | xecFormatOptions, | ||||
| ); | ); | ||||
| } | } | ||||
| return ` | return ` | ||||
| <div class="transaction-item"> | <div class="transaction-item"> | ||||
| <div class="transaction-info"> | <div class="transaction-info"> | ||||
| <div class="transaction-time">${String(time)}</div> | <div class="transaction-time">${String(time)}</div> | ||||
| ▲ Show 20 Lines • Show All 77 Lines • Show Last 20 Lines | |||||