From a46e243447840969dd0c865ce04ff4fdb0f0539f Mon Sep 17 00:00:00 2001 From: Radmir Date: Thu, 26 Mar 2026 18:31:48 +0500 Subject: [PATCH] Fix currency rate not applied on first price insert The upsert doUpdate path (with rate conversion) only runs on conflict. On first insert, prices were stored in USD regardless of selected currency. Changed AssetPrice.record to accept rate parameter so both INSERT and UPDATE paths write correctly converted prices. --- .../Store/Sources/Models/PriceRecord.swift | 8 ++--- .../Store/Sources/Stores/PriceStore.swift | 5 ++-- .../Tests/StoreTests/PriceStoreTests.swift | 29 +++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 Packages/Store/Tests/StoreTests/PriceStoreTests.swift diff --git a/Packages/Store/Sources/Models/PriceRecord.swift b/Packages/Store/Sources/Models/PriceRecord.swift index c30db1565..ed97ef30e 100644 --- a/Packages/Store/Sources/Models/PriceRecord.swift +++ b/Packages/Store/Sources/Models/PriceRecord.swift @@ -89,11 +89,11 @@ extension PriceRecord: Identifiable { } extension AssetPrice { - var record: PriceRecord { - return PriceRecord( + func record(fiatPrice: Double) -> PriceRecord { + PriceRecord( assetId: assetId, - price: price, - priceUsd: price, + price: fiatPrice, + priceUsd: self.price, priceChangePercentage24h: priceChangePercentage24h ) } diff --git a/Packages/Store/Sources/Stores/PriceStore.swift b/Packages/Store/Sources/Stores/PriceStore.swift index 906496340..fd10c1efa 100644 --- a/Packages/Store/Sources/Stores/PriceStore.swift +++ b/Packages/Store/Sources/Stores/PriceStore.swift @@ -29,11 +29,12 @@ public struct PriceStore: Sendable { let rate = try getRate(currency: currency) try db.write { db in for assetPrice in prices { - let _ = try assetPrice.record.upsertAndFetch( + let convertedPrice = assetPrice.price * rate.rate + let _ = try assetPrice.record(fiatPrice: convertedPrice).upsertAndFetch( db, onConflict: [], doUpdate: { _ in [ - PriceRecord.Columns.price.set(to: assetPrice.price * rate.rate), + PriceRecord.Columns.price.set(to: convertedPrice), PriceRecord.Columns.priceUsd.set(to: assetPrice.price), PriceRecord.Columns.priceChangePercentage24h.set(to: assetPrice.priceChangePercentage24h), PriceRecord.Columns.updatedAt.set(to: Date()), diff --git a/Packages/Store/Tests/StoreTests/PriceStoreTests.swift b/Packages/Store/Tests/StoreTests/PriceStoreTests.swift new file mode 100644 index 000000000..81611ba43 --- /dev/null +++ b/Packages/Store/Tests/StoreTests/PriceStoreTests.swift @@ -0,0 +1,29 @@ +// Copyright (c). Gem Wallet. All rights reserved. + +import Testing +import Store +import Primitives +import PrimitivesTestKit +import StoreTestKit + +struct PriceStoreTests { + + @Test + func firstInsertAppliesCurrencyRate() throws { + let db = DB.mockWithChains([.ethereum]) + let priceStore = PriceStore(db: db) + let fiatRateStore = FiatRateStore(db: db) + + let assetId = Chain.ethereum.assetId + let rate = 90.0 + let priceUsd = 2500.0 + let currency = Currency.rub.rawValue + + try fiatRateStore.add([FiatRate(symbol: currency, rate: rate)]) + try priceStore.updatePrices(prices: [.mock(assetId: assetId, price: priceUsd)], currency: currency) + + let result = try priceStore.getPrices(for: [assetId.identifier]) + + #expect(result.first?.price == priceUsd * rate) + } +}