store: keep coin units with the providers

This commit is contained in:
shum committed 2026-10-22 16:34:07 +00:00
1 parent 6b2bb17db3
commit 2ae70f7136
4 files changed
+19 -15

No files matched your search

@@ -22,8 +22,7 @@ import Data.Time.Clock (UTCTime)
import Simplex.Chat.PaymentService.Types (CryptoCurrency, InvoiceId)
import Simplex.Messaging.Agent.Store.Common (DBStore, withTransaction)
import StoreService.Names.Store (LateCredit (..), LateCreditState (..), LateSupport (..), NamePhase (..), creditLatePayment, lateCreditState, setLateSupport)
import StoreService.Providers (ProviderError (..), Rate (..))
import StoreService.Providers.BTCPay (unitDecimals)
import StoreService.Providers (ProviderError (..), Rate (..), unitDecimals)
import StoreService.Store.Invoices (lockInvoice)
import Text.Read (readMaybe)
@@ -38,7 +38,7 @@ import StoreService.Names.LateCredits (CreditOutcome (..), creditLateInvoice)
import StoreService.Names.Phases (Phases, RegistrationId (..))
import StoreService.Names.Store (CleanupKept (..), LateAlert (..), LateCredit (..), LateCreditState (..), LatePending (..), LateSupport (..), claimLateAlert, deleteUnpaidRegistration, lateAlertDue, latePending, uncreditedLateInvoices, unpaidCleanupCandidates)
import StoreService.Orders (decide, expireOverdue, settleOrder)
import StoreService.Providers (ListPass (..), PaymentSignal (..), Provider (..), ProviderError (..), Rate (..), Received (..), expiresItself, settleWindow)
import StoreService.Providers (ListPass (..), PaymentSignal (..), Provider (..), ProviderError (..), Rate (..), Received (..), expiresItself, settleWindow, unitName)
import StoreService.Store.Invoices (InvoiceProduct (..), InvoiceRow (..), OverdueInvoice (..), cryptoCurrencyText, getInvoice, getInvoiceByProviderRef, overdueInvoices, providerText, unpaidRefs)
import StoreService.Waiters (Waiters, waitingCount, waitingCountSTM)
import Control.Concurrent.STM
@@ -53,7 +53,7 @@ import qualified Data.Set as S
import Data.Text (Text)
import Data.Time.Clock (NominalDiffTime, UTCTime, addUTCTime, diffUTCTime, getCurrentTime)
import Numeric.Natural (Natural)
import Simplex.Chat.PaymentService.Types (CryptoCurrency (..), InvoiceId (..), InvoiceStatus (..), PaymentProvider (..))
import Simplex.Chat.PaymentService.Types (CryptoCurrency, InvoiceId (..), InvoiceStatus (..), PaymentProvider (..))
import Simplex.Messaging.Agent.Store.Common (DBStore, withTransaction)
import Simplex.Messaging.Util (tshow)
@@ -433,9 +433,6 @@ lateAlertText LateAlert {laState = LateCreditState {lsInvoice = InvoiceId invTex
(Just _, Nothing) -> tshow lsReceivedCents <> " cents received at the invoice's rate, not counted in units"
amounts unit received confirmed credited =
tshow received <> " " <> unit <> " received, " <> tshow confirmed <> " " <> unit <> " confirmed, " <> tshow credited <> " " <> unit <> " credited"
unitName = \case
CCBtc -> "satoshi"
CCXmr -> "piconero"
-- | Cancel the order at the provider first, so the buyer can no longer pay it.
closedAtProvider :: PollerEnv -> UTCTime -> OverdueInvoice -> IO Bool
@@ -1,5 +1,6 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module StoreService.Providers
( ProviderError (..),
@@ -8,6 +9,8 @@ module StoreService.Providers
Confirmed (..),
Uncreditable (..),
Rate (..),
unitDecimals,
unitName,
PaymentSignal (..),
ProviderInvoice (..),
Funded (..),
@@ -25,7 +28,7 @@ import Data.Scientific (Scientific)
import Data.Text (Text)
import Data.Time.Clock (NominalDiffTime, UTCTime)
import Network.HTTP.Types.Header (Header)
import Simplex.Chat.PaymentService.Types (CryptoCurrency, CurrencyAmount, PaymentProvider (..), ServicePaymentDestination, ServicePaymentMethod)
import Simplex.Chat.PaymentService.Types (CryptoCurrency (..), CurrencyAmount, PaymentProvider (..), ServicePaymentDestination, ServicePaymentMethod)
newtype ProviderError = ProviderError Text deriving (Eq, Show)
@@ -60,6 +63,17 @@ data Uncreditable = UCHighSpeed | UCUncounted | UCNoConfirmationShown
data Rate = Rate {rateText :: Text, rateValue :: Scientific}
deriving (Eq, Show)
-- | The decimals of each coin's atomic unit.
unitDecimals :: CryptoCurrency -> Int
unitDecimals = \case
CCBtc -> 8
CCXmr -> 12
unitName :: CryptoCurrency -> Text
unitName = \case
CCBtc -> "satoshi"
CCXmr -> "piconero"
-- The provider applies its own tolerance, so this cannot be recomputed from the amounts.
data Funded = PaidInFull | PaidInPart
deriving (Eq, Show)
@@ -7,7 +7,6 @@ module StoreService.Providers.BTCPay
( btcpayProvider,
btcMethodId,
xmrMethodId,
unitDecimals,
minorToDecimal,
paymentMethodsSignal,
listSignals,
@@ -32,6 +31,7 @@ import StoreService.Providers
Received (..),
Uncreditable (..),
settleWindow,
unitDecimals,
WebhookError (..),
)
import Control.Exception (try)
@@ -103,12 +103,6 @@ methodCurrencies = [(btcMethodId, CCBtc), (xmrMethodId, CCXmr)]
knownMethodIds :: [Text]
knownMethodIds = map fst methodCurrencies
-- | The decimals of each coin's atomic unit: satoshi and piconero.
unitDecimals :: CryptoCurrency -> Int
unitDecimals = \case
CCBtc -> 8
CCXmr -> 12
-- | The policies that settle a payment only after at least one confirmation.
confirmingPolicies :: [SpeedPolicy]
confirmingPolicies = [MediumSpeed, LowMediumSpeed, LowSpeed]