From 761a9528c450ffe3bc5933808057d73139c1d3ee Mon Sep 17 00:00:00 2001 From: gemdev111 <171273137+gemdev111@users.noreply.github.com> Date: Tue, 11 Aug 2026 02:41:47 +0300 Subject: [PATCH 1/3] Share one USD currency formatter Twelve files each built CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue), two of them inside computed properties. The package already names its shared formatters, BigNumberFormatter.standard and PercentFormatter.signed, so USD now has one too. It is a computed property rather than a stored constant: the initialiser defaults locale to Locale.current and keeps it, so a stored one would freeze formatting at first access and go stale when the region changes. --- .../Sources/ViewModels/AutocloseSceneViewModel.swift | 2 +- .../Sources/ViewModels/OpenPositionItemViewModel.swift | 2 +- .../Sources/ViewModels/PerpetualViewModel.swift | 2 +- .../Sources/ViewModels/TransactionPnlViewModel.swift | 2 +- .../Sources/ViewModels/TransactionPriceViewModel.swift | 2 +- .../Sources/ViewModels/PerpetualsPreviewViewModel.swift | 2 +- .../Sources/ViewModels/PortfolioSceneViewModel.swift | 2 +- ios/Packages/Formatters/Sources/AutocloseFormatter.swift | 2 +- .../Sources/Extensions/CurrencyFormatter+Formatters.swift | 8 ++++++++ .../Sources/ViewModels/PerpetualDetailsViewModel.swift | 2 +- ...PriceChangeViewModel+PrimitivesComponentsTestKit.swift | 2 +- .../TotalValueViewModel+PrimitivesComponentsTestKit.swift | 2 +- .../PrimitivesComponentsTests/PnLViewModelTests.swift | 2 +- 13 files changed, 20 insertions(+), 12 deletions(-) create mode 100644 ios/Packages/Formatters/Sources/Extensions/CurrencyFormatter+Formatters.swift diff --git a/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift index bc440a1aba..df678fcd12 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift @@ -13,7 +13,7 @@ import SwiftUI @Observable @MainActor public final class AutocloseSceneViewModel { - private let currencyFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + private let currencyFormatter = CurrencyFormatter.usd private let percentFormatter = PercentFormatter.signed private let perpetualFormatter = PerpetualFormatter(provider: .hypercore) private let type: AutocloseType diff --git a/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift index b28f0b52eb..a6bc30f2ac 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift @@ -16,7 +16,7 @@ struct OpenPositionItemViewModel: ListAssetItemViewable { init(data: AutocloseOpenData) { self.data = data - currencyFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + currencyFormatter = CurrencyFormatter.usd } var name: String { diff --git a/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift index 29cf017e3d..23af2ec340 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift @@ -18,7 +18,7 @@ public struct PerpetualViewModel { public init(perpetual: Perpetual, currencyStyle: CurrencyFormatterType = .abbreviated) { self.perpetual = perpetual marketValueFormatter = CurrencyFormatter(type: currencyStyle, currencyCode: Currency.usd.rawValue) - priceFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + priceFormatter = CurrencyFormatter.usd } public var name: String { diff --git a/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift b/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift index 055cb152f0..ccb1e3b599 100644 --- a/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift +++ b/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift @@ -22,7 +22,7 @@ extension TransactionPnlViewModel: ItemModelProvidable { return .empty } - let formatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + let formatter = CurrencyFormatter.usd let sign = metadata.pnl >= 0 ? "+" : "" let pnlFormatted = formatter.string(metadata.pnl) let color = metadata.pnl >= 0 ? Colors.green : Colors.red diff --git a/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift b/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift index 50d421c4d9..16ca9802b3 100644 --- a/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift +++ b/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift @@ -20,7 +20,7 @@ extension TransactionPriceViewModel: ItemModelProvidable { return .empty } - let formatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + let formatter = CurrencyFormatter.usd let priceFormatted = formatter.string(metadata.price) return .price( diff --git a/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift b/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift index 4ac4d8ba36..09760267a2 100644 --- a/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift +++ b/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift @@ -8,7 +8,7 @@ import Store @Observable @MainActor final class PerpetualsPreviewViewModel { - private let currencyFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + private let currencyFormatter = CurrencyFormatter.usd let positionsQuery: ObservableQuery let walletBalanceQuery: ObservableQuery diff --git a/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift b/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift index 07f8739356..e539c4424c 100644 --- a/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift +++ b/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift @@ -19,7 +19,7 @@ public final class PortfolioSceneViewModel: ChartListViewable { private let currencyFormatter: CurrencyFormatter private let priceFormatter: CurrencyFormatter private let percentFormatter = PercentFormatter.signed - private let perpetualFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + private let perpetualFormatter = CurrencyFormatter.usd var state: PortfolioState diff --git a/ios/Packages/Formatters/Sources/AutocloseFormatter.swift b/ios/Packages/Formatters/Sources/AutocloseFormatter.swift index c312437138..d6216d1d31 100644 --- a/ios/Packages/Formatters/Sources/AutocloseFormatter.swift +++ b/ios/Packages/Formatters/Sources/AutocloseFormatter.swift @@ -9,7 +9,7 @@ public struct AutocloseFormatter: Sendable { private let stopLossLabel: String public init( - currencyFormatter: CurrencyFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue), + currencyFormatter: CurrencyFormatter = CurrencyFormatter.usd, takeProfitLabel: String, stopLossLabel: String, ) { diff --git a/ios/Packages/Formatters/Sources/Extensions/CurrencyFormatter+Formatters.swift b/ios/Packages/Formatters/Sources/Extensions/CurrencyFormatter+Formatters.swift new file mode 100644 index 0000000000..c53123a396 --- /dev/null +++ b/ios/Packages/Formatters/Sources/Extensions/CurrencyFormatter+Formatters.swift @@ -0,0 +1,8 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Foundation +import Primitives + +public extension CurrencyFormatter { + static let usd = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) +} diff --git a/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift b/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift index bd2e616888..a3c208ffad 100644 --- a/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift +++ b/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift @@ -38,7 +38,7 @@ public struct PerpetualDetailsViewModel: Sendable, Identifiable { } private let type: PerpetualDetailsType - private let currencyFormatter = CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue) + private let currencyFormatter = CurrencyFormatter.usd private let numericFormatter = NumericFormatter() private let percentFormatter = PercentFormatter.signed private let percentSignLessFormatter = PercentFormatter.unsigned diff --git a/ios/Packages/PrimitivesComponents/TestKit/PriceChangeViewModel+PrimitivesComponentsTestKit.swift b/ios/Packages/PrimitivesComponents/TestKit/PriceChangeViewModel+PrimitivesComponentsTestKit.swift index d477f5ee70..eff48d4add 100644 --- a/ios/Packages/PrimitivesComponents/TestKit/PriceChangeViewModel+PrimitivesComponentsTestKit.swift +++ b/ios/Packages/PrimitivesComponents/TestKit/PriceChangeViewModel+PrimitivesComponentsTestKit.swift @@ -9,7 +9,7 @@ public extension PriceChangeViewModel { static func mock(value: Double?) -> PriceChangeViewModel { PriceChangeViewModel( value: value, - currencyFormatter: CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue), + currencyFormatter: CurrencyFormatter.usd, ) } } diff --git a/ios/Packages/PrimitivesComponents/TestKit/TotalValueViewModel+PrimitivesComponentsTestKit.swift b/ios/Packages/PrimitivesComponents/TestKit/TotalValueViewModel+PrimitivesComponentsTestKit.swift index 947f237779..381bdf32d5 100644 --- a/ios/Packages/PrimitivesComponents/TestKit/TotalValueViewModel+PrimitivesComponentsTestKit.swift +++ b/ios/Packages/PrimitivesComponents/TestKit/TotalValueViewModel+PrimitivesComponentsTestKit.swift @@ -13,7 +13,7 @@ public extension TotalValueViewModel { ) -> TotalValueViewModel { TotalValueViewModel( totalValue: .mock(value: value, pnlAmount: pnlAmount, pnlPercentage: pnlPercentage), - currencyFormatter: CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue), + currencyFormatter: CurrencyFormatter.usd, ) } } diff --git a/ios/Packages/PrimitivesComponents/Tests/PrimitivesComponentsTests/PnLViewModelTests.swift b/ios/Packages/PrimitivesComponents/Tests/PrimitivesComponentsTests/PnLViewModelTests.swift index 297a299169..31af328e29 100644 --- a/ios/Packages/PrimitivesComponents/Tests/PrimitivesComponentsTests/PnLViewModelTests.swift +++ b/ios/Packages/PrimitivesComponents/Tests/PrimitivesComponentsTests/PnLViewModelTests.swift @@ -37,7 +37,7 @@ extension PnLViewModel { PnLViewModel( pnl: pnl, marginAmount: marginAmount, - currencyFormatter: CurrencyFormatter(type: .currency, currencyCode: Currency.usd.rawValue), + currencyFormatter: CurrencyFormatter.usd, percentFormatter: PercentFormatter.signed, ) } From 5cb2043a549c2d4e2f1707b35c90c55f724f1cb4 Mon Sep 17 00:00:00 2001 From: gemdev111 <171273137+gemdev111@users.noreply.github.com> Date: Tue, 11 Aug 2026 02:49:05 +0300 Subject: [PATCH 2/3] Hold the USD formatters instead of rebuilding them per row CurrencyFormatter builds its DecimalFormat lazily and caches it on the instance, so constructing one per call throws that cache away every time. Four call sites did: the transaction subtitle inside a composable, the trigger order labels, and both perpetual branches of the per-transaction value getter. They now use a file level formatter like ProviderExtras and AmountAutocloseSheet already do. Every remaining USD formatter in the app is held in a property, a remember, or a one off constant. --- .../data/coordinators/transaction/GetTransactionsImpl.kt | 6 ++++-- .../perpetual/views/components/PositionProperties.kt | 4 +++- .../list_item/transaction/TransactionDataAggregateExt.kt | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/transaction/GetTransactionsImpl.kt b/android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/transaction/GetTransactionsImpl.kt index 85cc819224..84d21eeb57 100644 --- a/android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/transaction/GetTransactionsImpl.kt +++ b/android/data/coordinators/src/main/kotlin/com/gemwallet/android/data/coordinators/transaction/GetTransactionsImpl.kt @@ -38,6 +38,8 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import java.math.BigInteger +private val usdFiatFormatter = CurrencyFormatter(type = CurrencyFormatter.Type.Fiat, currency = Currency.USD) + class GetTransactionsImpl( private val transactionsRepository: TransactionRepository, scope: CoroutineScope = CoroutineScope(Dispatchers.IO), @@ -111,11 +113,11 @@ class TransactionDataAggregateImpl( AmountSign.Incoming.format(formatter.string(value, asset)) } ?: "" } - TransactionType.PerpetualOpenPosition -> CurrencyFormatter(type = CurrencyFormatter.Type.Fiat, currency = Currency.USD).string( + TransactionType.PerpetualOpenPosition -> usdFiatFormatter.string( CryptoFiatConverter.toFiat(Crypto(data.transaction.value), HypercoreUSDC.decimals, price = 1.0).atomicValue, ) TransactionType.PerpetualClosePosition -> pnl?.let { - PriceChangeFormatter(CurrencyFormatter(type = CurrencyFormatter.Type.Fiat, currency = Currency.USD)).string(it) + PriceChangeFormatter(usdFiatFormatter).string(it) } ?: "" TransactionType.StakeUndelegate, TransactionType.StakeRewards, diff --git a/android/features/perpetual/presents/src/main/kotlin/com/gemwallet/android/features/perpetual/views/components/PositionProperties.kt b/android/features/perpetual/presents/src/main/kotlin/com/gemwallet/android/features/perpetual/views/components/PositionProperties.kt index 3cb2d851dc..4b9c408b20 100644 --- a/android/features/perpetual/presents/src/main/kotlin/com/gemwallet/android/features/perpetual/views/components/PositionProperties.kt +++ b/android/features/perpetual/presents/src/main/kotlin/com/gemwallet/android/features/perpetual/views/components/PositionProperties.kt @@ -22,6 +22,8 @@ import com.gemwallet.android.ui.theme.paddingMiddle import com.wallet.core.primitives.Currency import com.wallet.core.primitives.PerpetualMarginType +private val usdFormatter = CurrencyFormatter(currency = Currency.USD) + internal fun LazyListScope.positionProperties( position: PerpetualPositionDetailsDataAggregate?, onAutocloseClick: () -> Unit, @@ -121,5 +123,5 @@ private fun PerpetualMarginType.title(): String { } private fun Double?.formatTriggerOrder(label: String): String? { - return this?.let { "$label: ${CurrencyFormatter(currency = Currency.USD).string(it)}" } + return this?.let { "$label: ${usdFormatter.string(it)}" } } diff --git a/android/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/transaction/TransactionDataAggregateExt.kt b/android/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/transaction/TransactionDataAggregateExt.kt index 41e1327004..6e5833b137 100644 --- a/android/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/transaction/TransactionDataAggregateExt.kt +++ b/android/ui/src/main/kotlin/com/gemwallet/android/ui/components/list_item/transaction/TransactionDataAggregateExt.kt @@ -18,6 +18,8 @@ import com.wallet.core.primitives.TransactionDirection import com.wallet.core.primitives.TransactionState import com.wallet.core.primitives.TransactionType +private val usdFiatFormatter = CurrencyFormatter(type = CurrencyFormatter.Type.Fiat, currency = Currency.USD) + @Composable fun TransactionDataAggregate.getTitle(): String = perpetualTitle(type, perpetualDirection) ?: stringResource(type.getTitle(direction, state)) @@ -72,7 +74,7 @@ fun TransactionDataAggregate.formatAddress(): String? = when (type) { TransactionType.PerpetualOpenPosition, TransactionType.PerpetualClosePosition, TransactionType.PerpetualModifyPosition -> perpetualPrice?.let { - "${stringResource(R.string.asset_price)}: ${CurrencyFormatter(type = CurrencyFormatter.Type.Fiat, currency = Currency.USD).string(it)}" + "${stringResource(R.string.asset_price)}: ${usdFiatFormatter.string(it)}" } TransactionType.StakeFreeze -> resourceType?.let { "${stringResource(id = R.string.transfer_to)} ${stringResource(it.titleRes())}" From a6c26f55c97feb9b7917c0b2202cf49835246f7a Mon Sep 17 00:00:00 2001 From: gemdev111 <171273137+gemdev111@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:09:33 +0300 Subject: [PATCH 3/3] Inject the USD formatter through init --- .../Sources/ViewModels/AutocloseSceneViewModel.swift | 5 +++-- .../Sources/ViewModels/OpenPositionItemViewModel.swift | 4 ++-- .../Sources/ViewModels/PerpetualViewModel.swift | 8 ++++++-- .../Sources/ViewModels/TransactionPnlViewModel.swift | 7 ++++--- .../Sources/ViewModels/TransactionPriceViewModel.swift | 7 ++++--- .../Sources/ViewModels/PerpetualsPreviewViewModel.swift | 5 +++-- .../Sources/ViewModels/PortfolioSceneViewModel.swift | 4 +++- ios/Packages/Formatters/Sources/AutocloseFormatter.swift | 2 +- .../Sources/ViewModels/PerpetualDetailsViewModel.swift | 5 +++-- 9 files changed, 29 insertions(+), 18 deletions(-) diff --git a/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift index df678fcd12..b643564799 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/AutocloseSceneViewModel.swift @@ -13,7 +13,7 @@ import SwiftUI @Observable @MainActor public final class AutocloseSceneViewModel { - private let currencyFormatter = CurrencyFormatter.usd + private let currencyFormatter: CurrencyFormatter private let percentFormatter = PercentFormatter.signed private let perpetualFormatter = PerpetualFormatter(provider: .hypercore) private let type: AutocloseType @@ -21,8 +21,9 @@ public final class AutocloseSceneViewModel { var input: AutocloseInput - public init(type: AutocloseType) { + public init(type: AutocloseType, currencyFormatter: CurrencyFormatter = .usd) { self.type = type + self.currencyFormatter = currencyFormatter estimator = AutocloseEstimator(type: type) input = AutocloseInput( diff --git a/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift index a6bc30f2ac..7a04e70269 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/OpenPositionItemViewModel.swift @@ -14,9 +14,9 @@ struct OpenPositionItemViewModel: ListAssetItemViewable { var action: ((ListAssetItemAction) -> Void)? - init(data: AutocloseOpenData) { + init(data: AutocloseOpenData, currencyFormatter: CurrencyFormatter = .usd) { self.data = data - currencyFormatter = CurrencyFormatter.usd + self.currencyFormatter = currencyFormatter } var name: String { diff --git a/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift b/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift index 23af2ec340..e68aad02a0 100644 --- a/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift +++ b/ios/Features/Perpetuals/Sources/ViewModels/PerpetualViewModel.swift @@ -15,10 +15,14 @@ public struct PerpetualViewModel { private let priceFormatter: CurrencyFormatter private let percentFormatter = PercentFormatter.signed - public init(perpetual: Perpetual, currencyStyle: CurrencyFormatterType = .abbreviated) { + public init( + perpetual: Perpetual, + currencyStyle: CurrencyFormatterType = .abbreviated, + priceFormatter: CurrencyFormatter = .usd, + ) { self.perpetual = perpetual + self.priceFormatter = priceFormatter marketValueFormatter = CurrencyFormatter(type: currencyStyle, currencyCode: Currency.usd.rawValue) - priceFormatter = CurrencyFormatter.usd } public var name: String { diff --git a/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift b/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift index ccb1e3b599..52cf96cbac 100644 --- a/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift +++ b/ios/Features/Transactions/Sources/ViewModels/TransactionPnlViewModel.swift @@ -10,9 +10,11 @@ import SwiftUI struct TransactionPnlViewModel { private let metadata: TransactionPerpetualMetadata? + private let currencyFormatter: CurrencyFormatter - init(metadata: TransactionPerpetualMetadata?) { + init(metadata: TransactionPerpetualMetadata?, currencyFormatter: CurrencyFormatter = .usd) { self.metadata = metadata + self.currencyFormatter = currencyFormatter } } @@ -22,9 +24,8 @@ extension TransactionPnlViewModel: ItemModelProvidable { return .empty } - let formatter = CurrencyFormatter.usd let sign = metadata.pnl >= 0 ? "+" : "" - let pnlFormatted = formatter.string(metadata.pnl) + let pnlFormatted = currencyFormatter.string(metadata.pnl) let color = metadata.pnl >= 0 ? Colors.green : Colors.red return .pnl( diff --git a/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift b/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift index 16ca9802b3..01ae441c9b 100644 --- a/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift +++ b/ios/Features/Transactions/Sources/ViewModels/TransactionPriceViewModel.swift @@ -8,9 +8,11 @@ import Primitives struct TransactionPriceViewModel { private let metadata: TransactionPerpetualMetadata? + private let currencyFormatter: CurrencyFormatter - init(metadata: TransactionPerpetualMetadata?) { + init(metadata: TransactionPerpetualMetadata?, currencyFormatter: CurrencyFormatter = .usd) { self.metadata = metadata + self.currencyFormatter = currencyFormatter } } @@ -20,8 +22,7 @@ extension TransactionPriceViewModel: ItemModelProvidable { return .empty } - let formatter = CurrencyFormatter.usd - let priceFormatted = formatter.string(metadata.price) + let priceFormatted = currencyFormatter.string(metadata.price) return .price( title: Localized.Asset.price, diff --git a/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift b/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift index 09760267a2..3462d91430 100644 --- a/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift +++ b/ios/Features/WalletTab/Sources/ViewModels/PerpetualsPreviewViewModel.swift @@ -8,7 +8,7 @@ import Store @Observable @MainActor final class PerpetualsPreviewViewModel { - private let currencyFormatter = CurrencyFormatter.usd + private let currencyFormatter: CurrencyFormatter let positionsQuery: ObservableQuery let walletBalanceQuery: ObservableQuery @@ -21,7 +21,8 @@ final class PerpetualsPreviewViewModel { walletBalanceQuery.value } - init(walletId: WalletId) { + init(walletId: WalletId, currencyFormatter: CurrencyFormatter = .usd) { + self.currencyFormatter = currencyFormatter positionsQuery = ObservableQuery(PerpetualPositionsRequest(walletId: walletId), initialValue: []) walletBalanceQuery = ObservableQuery(PerpetualWalletBalanceRequest(walletId: walletId), initialValue: .zero) } diff --git a/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift b/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift index e539c4424c..55dbab8978 100644 --- a/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift +++ b/ios/Features/WalletTab/Sources/ViewModels/PortfolioSceneViewModel.swift @@ -19,7 +19,7 @@ public final class PortfolioSceneViewModel: ChartListViewable { private let currencyFormatter: CurrencyFormatter private let priceFormatter: CurrencyFormatter private let percentFormatter = PercentFormatter.signed - private let perpetualFormatter = CurrencyFormatter.usd + private let perpetualFormatter: CurrencyFormatter var state: PortfolioState @@ -38,10 +38,12 @@ public final class PortfolioSceneViewModel: ChartListViewable { service: PortfolioDataService, preferences: ObservablePreferences, defaultType: PortfolioType = .wallet, + perpetualFormatter: CurrencyFormatter = .usd, ) { self.wallet = wallet self.service = service self.preferences = preferences + self.perpetualFormatter = perpetualFormatter let currencyCode = preferences.preferences.currency currencyFormatter = CurrencyFormatter(type: .currency, currencyCode: currencyCode) priceFormatter = CurrencyFormatter(currencyCode: currencyCode) diff --git a/ios/Packages/Formatters/Sources/AutocloseFormatter.swift b/ios/Packages/Formatters/Sources/AutocloseFormatter.swift index d6216d1d31..0354cc4afc 100644 --- a/ios/Packages/Formatters/Sources/AutocloseFormatter.swift +++ b/ios/Packages/Formatters/Sources/AutocloseFormatter.swift @@ -9,7 +9,7 @@ public struct AutocloseFormatter: Sendable { private let stopLossLabel: String public init( - currencyFormatter: CurrencyFormatter = CurrencyFormatter.usd, + currencyFormatter: CurrencyFormatter = .usd, takeProfitLabel: String, stopLossLabel: String, ) { diff --git a/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift b/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift index a3c208ffad..86fe8d960e 100644 --- a/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift +++ b/ios/Packages/PrimitivesComponents/Sources/ViewModels/PerpetualDetailsViewModel.swift @@ -38,7 +38,7 @@ public struct PerpetualDetailsViewModel: Sendable, Identifiable { } private let type: PerpetualDetailsType - private let currencyFormatter = CurrencyFormatter.usd + private let currencyFormatter: CurrencyFormatter private let numericFormatter = NumericFormatter() private let percentFormatter = PercentFormatter.signed private let percentSignLessFormatter = PercentFormatter.unsigned @@ -47,8 +47,9 @@ public struct PerpetualDetailsViewModel: Sendable, Identifiable { stopLossLabel: Localized.Perpetual.stopLoss, ) - public init(type: PerpetualDetailsType) { + public init(type: PerpetualDetailsType, currencyFormatter: CurrencyFormatter = .usd) { self.type = type + self.currencyFormatter = currencyFormatter } var data: PerpetualConfirmData {