diff --git a/.github/workflows/badge-web.yml b/.github/workflows/badge-web.yml index 4961c79fd1..71f4255f82 100644 --- a/.github/workflows/badge-web.yml +++ b/.github/workflows/badge-web.yml @@ -6,11 +6,11 @@ on: - master - stable paths: - - "apps/simplex-badge-service/web/**" + - "apps/simplex-store-service/web/**" - ".github/workflows/badge-web.yml" pull_request: paths: - - "apps/simplex-badge-service/web/**" + - "apps/simplex-store-service/web/**" - ".github/workflows/badge-web.yml" jobs: @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest defaults: run: - working-directory: apps/simplex-badge-service/web + working-directory: apps/simplex-store-service/web steps: - uses: actions/checkout@v4 @@ -26,7 +26,7 @@ jobs: with: node-version: 24 cache: npm - cache-dependency-path: apps/simplex-badge-service/web/package-lock.json + cache-dependency-path: apps/simplex-store-service/web/package-lock.json - run: npm ci diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0bd229a576..a87b6476be 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ on: - "apps/simplex-chat/**" - "apps/simplex-bot/**" - "apps/simplex-bot-advanced/**" - - "apps/simplex-badge-service/**" + - "apps/simplex-store-service/**" - "apps/simplex-broadcast-bot/**" - "apps/simplex-directory-service/**" - "tests/**" diff --git a/.gitignore b/.gitignore index 4ceea4d1a1..df897f3b24 100644 --- a/.gitignore +++ b/.gitignore @@ -88,10 +88,12 @@ website/test/stubs-layout-cache/_includes/*.js apps/android/app/release apps/multiplatform/.kotlin/sessions # anywhere in the tree: this file holds a real BTCPay api_key and webhook_secret +store_service.ini +# a local ini under its name before the store service rename holds the same secrets badge_service.ini -# Badge service Docker deployment: the Dockerfile, compose, and example config are tracked; the +# Store service Docker deployment: the Dockerfile, compose, and example config are tracked; the # live config (a secret) and its data volume are not. -scripts/badge-service/badge_service.ini -scripts/badge-service/data/ -scripts/badge-service/web/ +scripts/store-service/store_service.ini +scripts/store-service/data/ +scripts/store-service/web/ diff --git a/apps/simplex-badge-service/Main.hs b/apps/simplex-store-service/Main.hs similarity index 76% rename from apps/simplex-badge-service/Main.hs rename to apps/simplex-store-service/Main.hs index 68369995e2..fb2798d875 100644 --- a/apps/simplex-badge-service/Main.hs +++ b/apps/simplex-store-service/Main.hs @@ -2,8 +2,8 @@ module Main where -import BadgeService.Options (BadgeServiceOpts (..)) -import BadgeService.Service +import StoreService.Options (StoreServiceOpts (..)) +import StoreService.Service import Control.Logger.Simple (LogConfig (..), LogLevel (..), setLogLevel, withGlobalLogging) import GHC.IO.Encoding (setLocaleEncoding) import Simplex.Chat.Terminal (terminalChatConfig) @@ -17,7 +17,7 @@ main = do mapM_ (`hSetEncoding` utf8) [stdout, stderr] withGlobalLogging LogConfig {lc_file = Nothing, lc_stderr = True} $ do setLogLevel LogWarn - opts@BadgeServiceOpts {runCLI} <- welcomeGetOpts + opts@StoreServiceOpts {runCLI} <- welcomeGetOpts if runCLI - then badgeServiceCLI opts - else newServiceState >>= badgeService opts terminalChatConfig + then storeServiceCLI opts + else newServiceState >>= storeService opts terminalChatConfig diff --git a/apps/simplex-badge-service/README.md b/apps/simplex-store-service/README.md similarity index 95% rename from apps/simplex-badge-service/README.md rename to apps/simplex-store-service/README.md index 83b7ca4c40..6ff25c0549 100644 --- a/apps/simplex-badge-service/README.md +++ b/apps/simplex-store-service/README.md @@ -1,8 +1,8 @@ -# SimpleX badge service +# SimpleX store service -`simplex-badge-service` runs the whole supporter-badge service as one process, two +`simplex-store-service` runs the whole store service as one process, two lanes: a SimpleX chat bot that answers service RPC over a double-ratchet contact -address, and — only when `--service-config` names a `badge_service.ini` — the badge-codes +address, and — only when `--service-config` names a `store_service.ini` — the badge-codes web checkout (BTCPay and Stripe payment, code issuance, the poller). **Without `--service-config` the web listener does not start at all**; the process still runs the chat side and nothing else. @@ -11,7 +11,7 @@ The wire protocol for the RPC side is [`docs/protocol/badges-rpc.md`](../../docs/protocol/badges-rpc.md). The web checkout is specified in [`plans/badges-codes/2026-08-27-badge-codes.md`](../../plans/badges-codes/2026-08-27-badge-codes.md), -whose §9 is the `badge_service.ini` reference, with the implementation plan in +whose §9 is the `store_service.ini` reference, with the implementation plan in [`plans/badges-codes/2026-08-31-service-btcpay.md`](../../plans/badges-codes/2026-08-31-service-btcpay.md). Earlier plans (`2026-07-30-supporter-badges-v3-ux.md`, `2026-07-31-badges-core-implementation.md`, `2026-08-04-badges-mvp-scope.md`) predate the web checkout and describe the RPC-only @@ -37,13 +37,13 @@ purchase that already exists. Build prerequisites and the general contribution flow are in [`docs/CONTRIBUTING.md`](../../docs/CONTRIBUTING.md). ``` -cabal build exe:simplex-badge-service +cabal build exe:simplex-store-service ``` ## Run ``` -simplex-badge-service --help +simplex-store-service --help ``` - default (no `--run-cli`): background service mode, no interactive terminal. @@ -62,7 +62,7 @@ The service checks the secret against the configured public key at that index an if they disagree: credentials signed with the wrong key cannot be verified by any client, and the codes redeemed against them would be spent for nothing. -The key can come from `badge_service.ini` instead: +The key can come from `store_service.ini` instead: ```ini [issuer] @@ -76,40 +76,40 @@ Rotating is a change to both and a restart, once clients trust the new index. The command line wins over the file when both `--issuer-key-idx` and `--issuer-secret` are given. Note that a secret passed as a flag is visible to every user on the machine through `ps`, where one -in the ini is only as readable as the file: `badge_service.ini` is gitignored and already holds the +in the ini is only as readable as the file: `store_service.ini` is gitignored and already holds the provider API keys and webhook secrets. Other options: -- `--service-config INI_FILE`: path to `badge_service.ini`. Omit it to run the chat/RPC side +- `--service-config INI_FILE`: path to `store_service.ini`. Omit it to run the chat/RPC side only; the process never starts a web listener without it, and never starts one under `--run-cli`, which parses and validates the whole file (`[listener] static_dir` included) but uses only its `[issuer]` section. An issuer key is still required either way. - `--service-name NAME`: the bot's display name, without `*`s or spaces (default `SimpleX Badges`). - `--client-service`: use the client service certificate. - also accepts the standard SimpleX Chat core options — database path, SMP/XFTP servers, - `--socks-proxy`, `--log-level`/`-l`, and the rest — run `simplex-badge-service --help` + `--socks-proxy`, `--log-level`/`-l`, and the rest — run `simplex-store-service --help` for the complete list. ### Running the web checkout -`badge_service.ini` holds the listener bind address and `static_dir`, an optional +`store_service.ini` holds the listener bind address and `static_dir`, an optional `[btcpay]` section (omitting it disables Bitcoin and Monero), an optional `[stripe]` section (omitting it disables card payments), an optional `[group]` section (omitting it turns off the group's commands, though a group created earlier still has its code messages updated) and the poll cadence. -`badge_service.ini.example` is the committed template; `badge_service.ini` itself is +`store_service.ini.example` is the committed template; `store_service.ini` itself is gitignored, since a real one holds API keys and webhook secrets. The full walkthrough is in [`web/README.md`](web/README.md#running-the-real-service-against-this-build). Short version: ``` -cd apps/simplex-badge-service/web && npm install && npm run build && cd ../../.. -cp apps/simplex-badge-service/badge_service.ini.example apps/simplex-badge-service/badge_service.ini -cabal run simplex-badge-service -- \ +cd apps/simplex-store-service/web && npm install && npm run build && cd ../../.. +cp apps/simplex-store-service/store_service.ini.example apps/simplex-store-service/store_service.ini +cabal run simplex-store-service -- \ --issuer-key-idx IDX --issuer-secret SECRET \ - --service-config apps/simplex-badge-service/badge_service.ini + --service-config apps/simplex-store-service/store_service.ini ``` `IDX` and `SECRET` must be one of the issuer keys clients already ship, not a fresh @@ -249,7 +249,7 @@ why issuing codes lives in the service rather than in core. ### From the group -With `[group]` in `badge_service.ini`, the service manages one group and serves three commands in +With `[group]` in `store_service.ini`, the service manages one group and serves three commands in it: `/issue [months ] [uses ]` and `/bulk [months ] count ` for moderators and above, `/revoke ` for admins and owners. `months` is 1 to 255, `uses` 1 to 1000 and `count` 1 to 100; a value outside these gets the usage reply. A member's role is checked as the diff --git a/apps/simplex-badge-service/src/BadgeService/Catalog.hs b/apps/simplex-store-service/src/StoreService/Catalog.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Catalog.hs rename to apps/simplex-store-service/src/StoreService/Catalog.hs index 2ebb06facf..01959f54f6 100644 --- a/apps/simplex-badge-service/src/BadgeService/Catalog.hs +++ b/apps/simplex-store-service/src/StoreService/Catalog.hs @@ -3,7 +3,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module BadgeService.Catalog +module StoreService.Catalog ( OfferInvalid (..), CatalogRefusal (..), offerTotal, diff --git a/apps/simplex-badge-service/src/BadgeService/Codes.hs b/apps/simplex-store-service/src/StoreService/Codes.hs similarity index 90% rename from apps/simplex-badge-service/src/BadgeService/Codes.hs rename to apps/simplex-store-service/src/StoreService/Codes.hs index 06d3517359..7d0168e080 100644 --- a/apps/simplex-badge-service/src/BadgeService/Codes.hs +++ b/apps/simplex-store-service/src/StoreService/Codes.hs @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} -module BadgeService.Codes +module StoreService.Codes ( issueOneCode, issueFailedText, revokeBadgeCode, @@ -9,8 +9,8 @@ module BadgeService.Codes ) where -import BadgeService.Store (RevokeResult, insertBadgeCode, revokeCode) -import BadgeService.Store.Invoices (truncateToSecond) +import StoreService.Store (RevokeResult, insertBadgeCode, revokeCode) +import StoreService.Store.Invoices (truncateToSecond) import Data.Int (Int64) import Data.Text (Text) import Data.Time.Clock (getCurrentTime) diff --git a/apps/simplex-badge-service/src/BadgeService/Config.hs b/apps/simplex-store-service/src/StoreService/Config.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Config.hs rename to apps/simplex-store-service/src/StoreService/Config.hs index 9e33f4459d..a8c2545571 100644 --- a/apps/simplex-badge-service/src/BadgeService/Config.hs +++ b/apps/simplex-store-service/src/StoreService/Config.hs @@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Config +module StoreService.Config ( ListenerConfig (..), BTCPayConfig (..), StripeConfig (..), @@ -21,7 +21,7 @@ module BadgeService.Config where import qualified Control.Exception as E -import BadgeService.Log (logWarn) +import StoreService.Log (logWarn) import Control.Monad (mfilter) import Data.Attoparsec.Text (Parser, endOfInput, isEndOfLine, parseOnly, satisfy, skipMany, skipSpace, skipWhile) import qualified Data.ByteString.Char8 as B diff --git a/apps/simplex-badge-service/src/BadgeService/Group.hs b/apps/simplex-store-service/src/StoreService/Group.hs similarity index 98% rename from apps/simplex-badge-service/src/BadgeService/Group.hs rename to apps/simplex-store-service/src/StoreService/Group.hs index 28117655ef..2732bed2f5 100644 --- a/apps/simplex-badge-service/src/BadgeService/Group.hs +++ b/apps/simplex-store-service/src/StoreService/Group.hs @@ -5,7 +5,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} -module BadgeService.Group +module StoreService.Group ( ensureManagedGroup, runGroupLane, inertGroupConfig, @@ -24,12 +24,12 @@ module BadgeService.Group ) where -import BadgeService.Codes (issueFailedText, issueOneCode, revokeBadgeCode, singleUse) -import BadgeService.Config (GroupConfig (..)) -import BadgeService.Group.Command (CmdAction (..), GroupCmd (..), groupCmdAction, groupCommands) -import BadgeService.Log (logError, logInfo, logWarn) -import BadgeService.Store (CodeTracker (..), ManagedGroup (..), RevokeResult (..), clearCodeGroupItems, getCodeTracker, getEditableTrackers, getManagedGroup, insertManagedGroup, markOwnerBootstrapped, setCodeGroupItem) -import BadgeService.Store.Invoices (truncateToSecond) +import StoreService.Codes (issueFailedText, issueOneCode, revokeBadgeCode, singleUse) +import StoreService.Config (GroupConfig (..)) +import StoreService.Group.Command (CmdAction (..), GroupCmd (..), groupCmdAction, groupCommands) +import StoreService.Log (logError, logInfo, logWarn) +import StoreService.Store (CodeTracker (..), ManagedGroup (..), RevokeResult (..), clearCodeGroupItems, getCodeTracker, getEditableTrackers, getManagedGroup, insertManagedGroup, markOwnerBootstrapped, setCodeGroupItem) +import StoreService.Store.Invoices (truncateToSecond) import Control.Concurrent.STM (TQueue, atomically, flushTQueue, readTQueue, readTVarIO, writeTQueue) import Control.Monad (forM_, forever, mfilter, replicateM, unless, void) import Control.Monad.Except (runExceptT) diff --git a/apps/simplex-badge-service/src/BadgeService/Group/Command.hs b/apps/simplex-store-service/src/StoreService/Group/Command.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Group/Command.hs rename to apps/simplex-store-service/src/StoreService/Group/Command.hs index 799e1a2fcf..460450e44e 100644 --- a/apps/simplex-badge-service/src/BadgeService/Group/Command.hs +++ b/apps/simplex-store-service/src/StoreService/Group/Command.hs @@ -2,7 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} -module BadgeService.Group.Command +module StoreService.Group.Command ( GroupCmd (..), CmdAction (..), groupCmdAction, diff --git a/apps/simplex-badge-service/src/BadgeService/Log.hs b/apps/simplex-store-service/src/StoreService/Log.hs similarity index 98% rename from apps/simplex-badge-service/src/BadgeService/Log.hs rename to apps/simplex-store-service/src/StoreService/Log.hs index a2f54f4420..a4aab7e42b 100644 --- a/apps/simplex-badge-service/src/BadgeService/Log.hs +++ b/apps/simplex-store-service/src/StoreService/Log.hs @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} -- | The SMP agent logs unconditionally at info on the global logger, so the service keeps its own info lines on this separate channel when that logger is raised to Warn. -module BadgeService.Log +module StoreService.Log ( logInfo, logWarn, logError, diff --git a/apps/simplex-badge-service/src/BadgeService/Names/Chain.hs b/apps/simplex-store-service/src/StoreService/Names/Chain.hs similarity index 97% rename from apps/simplex-badge-service/src/BadgeService/Names/Chain.hs rename to apps/simplex-store-service/src/StoreService/Names/Chain.hs index dd23fcac6e..35cd39974c 100644 --- a/apps/simplex-badge-service/src/BadgeService/Names/Chain.hs +++ b/apps/simplex-store-service/src/StoreService/Names/Chain.hs @@ -2,7 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Names.Chain +module StoreService.Names.Chain ( ChainClient (..), ChainError (..), TxHash (..), @@ -11,7 +11,7 @@ module BadgeService.Names.Chain ) where -import BadgeService.Names.Registration (RegisterIntent, commitCalldata, registerWithCreditCalldata) +import StoreService.Names.Registration (RegisterIntent, commitCalldata, registerWithCreditCalldata) import Control.Concurrent.STM (TVar) import Control.Exception (try) import Control.Monad.Except (ExceptT, liftEither, runExceptT, throwError) diff --git a/apps/simplex-badge-service/src/BadgeService/Names/Registration.hs b/apps/simplex-store-service/src/StoreService/Names/Registration.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Names/Registration.hs rename to apps/simplex-store-service/src/StoreService/Names/Registration.hs index 0881b6cb24..6d187c811a 100644 --- a/apps/simplex-badge-service/src/BadgeService/Names/Registration.hs +++ b/apps/simplex-store-service/src/StoreService/Names/Registration.hs @@ -2,7 +2,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module BadgeService.Names.Registration +module StoreService.Names.Registration ( Registration (..), RegisterIntent (..), sponsorDomain, diff --git a/apps/simplex-badge-service/src/BadgeService/Options.hs b/apps/simplex-store-service/src/StoreService/Options.hs similarity index 80% rename from apps/simplex-badge-service/src/BadgeService/Options.hs rename to apps/simplex-store-service/src/StoreService/Options.hs index 1d2423771a..cd2309372b 100644 --- a/apps/simplex-badge-service/src/BadgeService/Options.hs +++ b/apps/simplex-store-service/src/StoreService/Options.hs @@ -3,15 +3,15 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module BadgeService.Options - ( BadgeServiceOpts (..), - getBadgeServiceOpts, - badgeServiceOpts, +module StoreService.Options + ( StoreServiceOpts (..), + getStoreServiceOpts, + storeServiceOpts, mkChatOpts, ) where -import BadgeService.Config (BadgeIssuerKey (..)) +import StoreService.Config (BadgeIssuerKey (..)) import qualified Data.ByteString.Char8 as B import qualified Data.Text as T import Options.Applicative @@ -19,7 +19,7 @@ import Simplex.Chat.Controller (updateStr, versionNumber, versionString) import Simplex.Chat.Options (ChatCmdLog (..), ChatOpts (..), CoreChatOpts, CreateBotOpts (..), coreChatOptsP) import Simplex.Messaging.Encoding.String (strDecode) -data BadgeServiceOpts = BadgeServiceOpts +data StoreServiceOpts = StoreServiceOpts { coreOptions :: CoreChatOpts, serviceName :: T.Text, clientService :: Bool, @@ -30,14 +30,14 @@ data BadgeServiceOpts = BadgeServiceOpts testing :: Bool } -badgeServiceOpts :: FilePath -> FilePath -> Parser BadgeServiceOpts -badgeServiceOpts appDir defaultDbName = do +storeServiceOpts :: FilePath -> FilePath -> Parser StoreServiceOpts +storeServiceOpts appDir defaultDbName = do coreOptions <- coreChatOptsP appDir defaultDbName serviceName <- strOption ( long "service-name" <> metavar "SERVICE_NAME" - <> help "The display name of the badge service bot, without *'s and spaces (SimpleX Badges)" + <> help "The display name of the store service bot, without *'s and spaces (SimpleX Badges)" <> value "SimpleX Badges" ) clientService <- @@ -53,14 +53,14 @@ badgeServiceOpts appDir defaultDbName = do runCLI <- switch ( long "run-cli" - <> help "Run badge service as CLI" + <> help "Run store service as CLI" ) serviceConfigFile <- optional ( strOption ( long "service-config" <> metavar "INI_FILE" - <> help "Path to badge_service.ini: parsed in full in every mode, but --run-cli starts no web listener" + <> help "Path to store_service.ini: parsed in full in every mode, but --run-cli starts no web listener" ) ) issuerKeyIdx <- @@ -80,7 +80,7 @@ badgeServiceOpts appDir defaultDbName = do <> help "Issuer secret from `simplex-chat badge keygen` (base64url)" ) pure - BadgeServiceOpts + StoreServiceOpts { coreOptions, serviceName = T.pack serviceName, clientService, @@ -94,19 +94,19 @@ badgeServiceOpts appDir defaultDbName = do testing = False } -getBadgeServiceOpts :: FilePath -> FilePath -> IO BadgeServiceOpts -getBadgeServiceOpts appDir defaultDbName = +getStoreServiceOpts :: FilePath -> FilePath -> IO StoreServiceOpts +getStoreServiceOpts appDir defaultDbName = execParser $ info - (helper <*> versionOption <*> badgeServiceOpts appDir defaultDbName) - (header versionStr <> fullDesc <> progDesc "Start SimpleX Badge Service with DB_FILE options") + (helper <*> versionOption <*> storeServiceOpts appDir defaultDbName) + (header versionStr <> fullDesc <> progDesc "Start SimpleX Store Service with DB_FILE options") where versionStr = versionString versionNumber versionOption = infoOption versionAndUpdate (long "version" <> short 'v' <> help "Show version") versionAndUpdate = versionStr <> "\n" <> updateStr -mkChatOpts :: BadgeServiceOpts -> ChatOpts -mkChatOpts BadgeServiceOpts {coreOptions, serviceName, clientService} = +mkChatOpts :: StoreServiceOpts -> ChatOpts +mkChatOpts StoreServiceOpts {coreOptions, serviceName, clientService} = ChatOpts { coreOptions, chatCmd = "", diff --git a/apps/simplex-badge-service/src/BadgeService/Orders.hs b/apps/simplex-store-service/src/StoreService/Orders.hs similarity index 95% rename from apps/simplex-badge-service/src/BadgeService/Orders.hs rename to apps/simplex-store-service/src/StoreService/Orders.hs index 63359b0880..32be2ebc74 100644 --- a/apps/simplex-badge-service/src/BadgeService/Orders.hs +++ b/apps/simplex-store-service/src/StoreService/Orders.hs @@ -2,11 +2,11 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module BadgeService.Orders (settleOrder, decide, codeLifetime) where +module StoreService.Orders (settleOrder, decide, codeLifetime) where -import BadgeService.Providers (Funded (..), PaymentSignal (..), Received (..)) -import BadgeService.Store.Invoices (InvoicePayment (..), InvoiceRow (..), markCodePaid, paymentStatusText, settlementCodeHash, settlementInvoice, truncateToSecond, updateInvoiceStatus, upsertPayment) -import BadgeService.Waiters (Waiters, publish, publishPayment) +import StoreService.Providers (Funded (..), PaymentSignal (..), Received (..)) +import StoreService.Store.Invoices (InvoicePayment (..), InvoiceRow (..), markCodePaid, paymentStatusText, settlementCodeHash, settlementInvoice, truncateToSecond, updateInvoiceStatus, upsertPayment) +import StoreService.Waiters (Waiters, publish, publishPayment) import Control.Concurrent.STM (atomically) import Control.Monad (when) import Data.ByteString (ByteString) diff --git a/apps/simplex-badge-service/src/BadgeService/Poller.hs b/apps/simplex-store-service/src/StoreService/Poller.hs similarity index 97% rename from apps/simplex-badge-service/src/BadgeService/Poller.hs rename to apps/simplex-store-service/src/StoreService/Poller.hs index c22df44ddb..5c8631bd65 100644 --- a/apps/simplex-badge-service/src/BadgeService/Poller.hs +++ b/apps/simplex-store-service/src/StoreService/Poller.hs @@ -4,7 +4,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Poller +module StoreService.Poller ( PollerEnv (..), ReadHints, newReadHints, @@ -27,14 +27,14 @@ module BadgeService.Poller ) where -import BadgeService.Config (PollConfig (..)) -import BadgeService.Orders (decide, settleOrder) -import BadgeService.Providers (ListPass (..), PaymentSignal (..), Provider (..), ProviderError (..), Received (..), expiresItself, settleWindow) -import BadgeService.Store.Invoices (InvoiceRow (..), OverdueInvoice (..), expireOverdue, getInvoiceByProviderRef, overdueInvoices, providerText, unpaidRefs) -import BadgeService.Waiters (Waiters, publish, waitingCount, waitingCountSTM) +import StoreService.Config (PollConfig (..)) +import StoreService.Orders (decide, settleOrder) +import StoreService.Providers (ListPass (..), PaymentSignal (..), Provider (..), ProviderError (..), Received (..), expiresItself, settleWindow) +import StoreService.Store.Invoices (InvoiceRow (..), OverdueInvoice (..), expireOverdue, getInvoiceByProviderRef, overdueInvoices, providerText, unpaidRefs) +import StoreService.Waiters (Waiters, publish, waitingCount, waitingCountSTM) import Control.Concurrent.STM import Control.Exception (SomeAsyncException, SomeException, fromException, throwIO, try) -import BadgeService.Log (logError, logInfo, logWarn) +import StoreService.Log (logError, logInfo, logWarn) import Control.Monad (filterM, forever, unless, void, when) import Data.List (find, partition, sortOn) import Data.Map.Strict (Map) diff --git a/apps/simplex-badge-service/src/BadgeService/Providers.hs b/apps/simplex-store-service/src/StoreService/Providers.hs similarity index 98% rename from apps/simplex-badge-service/src/BadgeService/Providers.hs rename to apps/simplex-store-service/src/StoreService/Providers.hs index 8faabd2a2c..c0904094c5 100644 --- a/apps/simplex-badge-service/src/BadgeService/Providers.hs +++ b/apps/simplex-store-service/src/StoreService/Providers.hs @@ -1,7 +1,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE NamedFieldPuns #-} -module BadgeService.Providers +module StoreService.Providers ( ProviderError (..), WebhookError (..), Received (..), diff --git a/apps/simplex-badge-service/src/BadgeService/Providers/BTCPay.hs b/apps/simplex-store-service/src/StoreService/Providers/BTCPay.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Providers/BTCPay.hs rename to apps/simplex-store-service/src/StoreService/Providers/BTCPay.hs index 2df54789a3..1a910205c6 100644 --- a/apps/simplex-badge-service/src/BadgeService/Providers/BTCPay.hs +++ b/apps/simplex-store-service/src/StoreService/Providers/BTCPay.hs @@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Providers.BTCPay +module StoreService.Providers.BTCPay ( btcpayProvider, btcMethodId, xmrMethodId, @@ -16,8 +16,8 @@ module BadgeService.Providers.BTCPay ) where -import BadgeService.Config (BTCPayConfig (..), speedPolicyName) -import BadgeService.Providers +import StoreService.Config (BTCPayConfig (..), speedPolicyName) +import StoreService.Providers ( ListPass (..), OrderDraft (..), PaymentSignal (..), @@ -30,7 +30,7 @@ import BadgeService.Providers WebhookError (..), ) import Control.Exception (try) -import BadgeService.Log (logError, logInfo, logWarn) +import StoreService.Log (logError, logInfo, logWarn) import Control.Monad (unless) import Crypto.Hash (Digest, SHA256) import Crypto.MAC.HMAC (HMAC, hmac, hmacGetDigest) diff --git a/apps/simplex-badge-service/src/BadgeService/Providers/Stripe.hs b/apps/simplex-store-service/src/StoreService/Providers/Stripe.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Providers/Stripe.hs rename to apps/simplex-store-service/src/StoreService/Providers/Stripe.hs index 93f55f37b2..aff7100cf7 100644 --- a/apps/simplex-badge-service/src/BadgeService/Providers/Stripe.hs +++ b/apps/simplex-store-service/src/StoreService/Providers/Stripe.hs @@ -3,15 +3,15 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Providers.Stripe +module StoreService.Providers.Stripe ( stripeProvider, signalOf, IntentRead (..), ) where -import BadgeService.Config (StripeConfig (..)) -import BadgeService.Providers +import StoreService.Config (StripeConfig (..)) +import StoreService.Providers ( ListPass (..), OrderDraft (..), PaymentSignal (..), diff --git a/apps/simplex-badge-service/src/BadgeService/Service.hs b/apps/simplex-store-service/src/StoreService/Service.hs similarity index 89% rename from apps/simplex-badge-service/src/BadgeService/Service.hs rename to apps/simplex-store-service/src/StoreService/Service.hs index c1636bccf5..334d081422 100644 --- a/apps/simplex-badge-service/src/BadgeService/Service.hs +++ b/apps/simplex-store-service/src/StoreService/Service.hs @@ -4,37 +4,37 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} -module BadgeService.Service +module StoreService.Service ( ServiceState (..), newServiceState, welcomeGetOpts, checkIssuerKey, - badgeService, - badgeServiceCLI, - badgeServiceResponse, + storeService, + storeServiceCLI, + storeServiceResponse, badgeErrorRetryAfter, IssueCodeOpts (..), issueBadgeCode, ) where -import BadgeService.Catalog (defaultCatalog) -import BadgeService.Codes (issueFailedText, issueOneCode, singleUse) -import BadgeService.Config (BadgeIssuerKey (..), ServiceConfig (..), readServiceConfig) -import BadgeService.Group (GroupEvent, ensureManagedGroup, groupEvent, hasTracker, refreshTracker, revokeWithTracker, runGroupLane) -import BadgeService.Group.Command (badgeTypeP, codeP, maxMonths, textTokenP) -import BadgeService.Options -import BadgeService.Poller (newPollerEnv, newReadHints, runPoller) -import BadgeService.Providers.BTCPay (btcpayProvider) -import BadgeService.Providers.Stripe (stripeProvider) -import BadgeService.Store -import BadgeService.Store.Invoices (seedCatalog, truncateToSecond) -import BadgeService.Store.Migrate (runBadgeServiceMigrations) -import BadgeService.Waiters (Waiters, newWaiters) -import BadgeService.Web.Server (exportWebapp, newWebEnv, runWebListener) +import StoreService.Catalog (defaultCatalog) +import StoreService.Codes (issueFailedText, issueOneCode, singleUse) +import StoreService.Config (BadgeIssuerKey (..), ServiceConfig (..), readServiceConfig) +import StoreService.Group (GroupEvent, ensureManagedGroup, groupEvent, hasTracker, refreshTracker, revokeWithTracker, runGroupLane) +import StoreService.Group.Command (badgeTypeP, codeP, maxMonths, textTokenP) +import StoreService.Options +import StoreService.Poller (newPollerEnv, newReadHints, runPoller) +import StoreService.Providers.BTCPay (btcpayProvider) +import StoreService.Providers.Stripe (stripeProvider) +import StoreService.Store +import StoreService.Store.Invoices (seedCatalog, truncateToSecond) +import StoreService.Store.Migrate (runStoreServiceMigrations) +import StoreService.Waiters (Waiters, newWaiters) +import StoreService.Web.Server (exportWebapp, newWebEnv, runWebListener) import Control.Applicative (optional) import Control.Concurrent.STM -import BadgeService.Log (logError, logInfo) +import StoreService.Log (logError, logInfo) import Control.Monad import Control.Monad.IO.Class (liftIO) import qualified Data.Aeson as J @@ -83,22 +83,22 @@ newServiceState = do groupEventQ <- newTQueueIO pure ServiceState {serviceCC, serviceRequestQ, groupEventQ} -welcomeGetOpts :: IO BadgeServiceOpts +welcomeGetOpts :: IO StoreServiceOpts welcomeGetOpts = do appDir <- getAppUserDataDirectory "simplex" - opts@BadgeServiceOpts {coreOptions, testing, serviceName} <- getBadgeServiceOpts appDir "simplex_badge_service" + opts@StoreServiceOpts {coreOptions, testing, serviceName} <- getStoreServiceOpts appDir "simplex_badge_service" unless testing $ do - putStrLn $ "SimpleX Badge Service v" ++ versionNumber + putStrLn $ "SimpleX Store Service v" ++ versionNumber printDbOpts coreOptions putStrLn $ "Service name: " ++ T.unpack serviceName pure opts -checkIssuerKey :: BadgeServiceOpts -> Maybe ServiceConfig -> ChatConfig -> IO (Either String BadgeIssuerKey) -checkIssuerKey BadgeServiceOpts {issuerKey} serviceCfg cfg = case issuerKey of +checkIssuerKey :: StoreServiceOpts -> Maybe ServiceConfig -> ChatConfig -> IO (Either String BadgeIssuerKey) +checkIssuerKey StoreServiceOpts {issuerKey} serviceCfg cfg = case issuerKey of Left e -> pure (Left e) Right (Just k) -> checkOne cfg k Right Nothing -> case serviceCfg >>= issuer of - Nothing -> pure $ Left "an issuer key is required - pass --issuer-key-idx and --issuer-secret, or add an [issuer] section to badge_service.ini (see `simplex-chat badge keygen`)" + Nothing -> pure $ Left "an issuer key is required - pass --issuer-key-idx and --issuer-secret, or add an [issuer] section to store_service.ini (see `simplex-chat badge keygen`)" Just k -> checkOne cfg k checkOne :: ChatConfig -> BadgeIssuerKey -> IO (Either String BadgeIssuerKey) @@ -110,7 +110,7 @@ checkOne ChatConfig {badgePublicKeys} k@BadgeIssuerKey {keyIdx, secretKey} = Just _ -> Left $ "issuer secret does not match the configured key at index " <> show keyIdx <> ", its public key is " <> T.unpack (safeDecodeUtf8 $ strEncode pk) Nothing -> Left $ "no configured badge key at index " <> show keyIdx <> ", clients could not verify what this service signs" -requireIssuerKey :: BadgeServiceOpts -> Maybe ServiceConfig -> ChatConfig -> IO BadgeIssuerKey +requireIssuerKey :: StoreServiceOpts -> Maybe ServiceConfig -> ChatConfig -> IO BadgeIssuerKey requireIssuerKey opts serviceCfg cfg = checkIssuerKey opts serviceCfg cfg >>= either (\e -> putStrLn ("Error: " <> e) >> exitFailure) pure @@ -120,8 +120,8 @@ readConfigOrExit path = Left e -> putStrLn (path <> ": " <> e) >> exitFailure Right sc -> pure sc -badgeService :: BadgeServiceOpts -> ChatConfig -> ServiceState -> IO () -badgeService opts@BadgeServiceOpts {serviceConfigFile} cfg env = do +storeService :: StoreServiceOpts -> ChatConfig -> ServiceState -> IO () +storeService opts@StoreServiceOpts {serviceConfigFile} cfg env = do serviceCfg <- traverse readConfigOrExit serviceConfigFile key <- requireIssuerKey opts serviceCfg cfg waiters <- newWaiters @@ -171,8 +171,8 @@ seedServiceCatalog st = do "badge catalog: " <> tshow (length prices) <> " prices and " <> tshow (length offers) <> " offers compiled in, " <> tshow seededPrices <> " prices and " <> tshow seededOffers <> " offers inserted" -badgeServiceCLI :: BadgeServiceOpts -> IO () -badgeServiceCLI opts@BadgeServiceOpts {serviceConfigFile} = do +storeServiceCLI :: StoreServiceOpts -> IO () +storeServiceCLI opts@StoreServiceOpts {serviceConfigFile} = do serviceCfg <- traverse readConfigOrExit serviceConfigFile key <- requireIssuerKey opts serviceCfg terminalChatConfig env <- newServiceState @@ -248,12 +248,12 @@ processQueuedRequests key trackerQ_ env = do (u, reqId, sigKey, reqData) <- atomically $ readTQueue $ serviceRequestQ env handleServiceRequest key cc trackerQ_ u reqId sigKey reqData -badgePreStartHook :: BadgeServiceOpts -> ChatController -> IO () +badgePreStartHook :: StoreServiceOpts -> ChatController -> IO () badgePreStartHook opts ChatController {config, chatStore} = - runBadgeServiceMigrations opts config chatStore + runStoreServiceMigrations opts config chatStore -badgePostStartHook :: BadgeServiceOpts -> ServiceState -> ChatController -> IO () -badgePostStartHook BadgeServiceOpts {noAddress, testing} env cc = do +badgePostStartHook :: StoreServiceOpts -> ServiceState -> ChatController -> IO () +badgePostStartHook StoreServiceOpts {noAddress, testing} env cc = do -- Core starts this False and gates service request delivery on it, so the hook must set it. atomically $ writeTVar (processServiceRequests cc) True readTVarIO (currentUser cc) >>= \case @@ -266,11 +266,11 @@ badgePostStartHook BadgeServiceOpts {noAddress, testing} env cc = do handleServiceRequest :: BadgeIssuerKey -> ChatController -> Maybe (TQueue GroupEvent) -> User -> AgentInvId -> Maybe C.PublicKeyEd25519 -> J.Object -> IO () handleServiceRequest key cc trackerQ_ User {userId} reqId sigKey reqData = do let reqIdT = safeDecodeUtf8 (strEncode reqId) - logInfo $ "badge service request " <> reqIdT - resp <- badgeServiceResponse key cc trackerQ_ sigKey reqData + logInfo $ "store service request " <> reqIdT + resp <- storeServiceResponse key cc trackerQ_ sigKey reqData sendChatCmd cc (APISendServiceResponse userId reqId (responseObject resp)) >>= \case Right _ -> pure () - Left e -> logError $ "badge service response failed for " <> reqIdT <> ": " <> tshow e + Left e -> logError $ "store service response failed for " <> reqIdT <> ": " <> tshow e responseObject :: StoreServiceResponse -> J.Object responseObject r = case J.toJSON r of @@ -289,8 +289,8 @@ badgeErrorRetryAfter = \case -- | The agent verified the signature, so sigKey is a key the sender holds; a differing purchaseKey would let a client claim a purchase it cannot sign for. -badgeServiceResponse :: BadgeIssuerKey -> ChatController -> Maybe (TQueue GroupEvent) -> Maybe C.PublicKeyEd25519 -> J.Object -> IO StoreServiceResponse -badgeServiceResponse key cc trackerQ_ sigKey reqData = case J.fromJSON (J.Object reqData) of +storeServiceResponse :: BadgeIssuerKey -> ChatController -> Maybe (TQueue GroupEvent) -> Maybe C.PublicKeyEd25519 -> J.Object -> IO StoreServiceResponse +storeServiceResponse key cc trackerQ_ sigKey reqData = case J.fromJSON (J.Object reqData) of J.Error _ -> pure $ errorResponse STEBadRequest J.Success StoreServiceRequest {version, purchaseKey, request} | not (version `isCompatible` supportedStoreServiceVRange) -> pure $ errorResponse STEUnsupportedVersion @@ -348,7 +348,7 @@ redeemCode key cc trackerQ_ purchaseKey masterKey codeText = case parseBadgeCode case issueEntry now issueUuid granted of Nothing -> pure $ errorResponse STEInternal Just issued -> credentialForEntry key masterKey issued >>= \case - Left e -> logError ("badge service signing failed: " <> T.pack e) $> errorResponse STEInternal + Left e -> logError ("store service signing failed: " <> T.pack e) $> errorResponse STEInternal Right signed -> do -- If the code was revoked or used up while signing, the claim fails. Read the code again to tell the client why. r <- withDB "writeCodeRedemption" cc $ \db -> @@ -356,7 +356,7 @@ redeemCode key cc trackerQ_ purchaseKey masterKey codeText = case parseBadgeCode Nothing -> readCode now code db >>= \case Left resp -> pure (resp, False) - Right _ -> logError "badge service: redeeming a code failed, but the code has uses left and is not revoked" $> (errorResponse STEInternal, False) + Right _ -> logError "store service: redeeming a code failed, but the code has uses left and is not revoked" $> (errorResponse STEInternal, False) Just purchaseId -> liftIO $ do appendLedgerPlan db purchaseId [granted] $ Just $ issuanceAfter granted signed entries_ <- getLedgerEntries db purchaseId 0 @@ -377,7 +377,7 @@ redeemCode key cc trackerQ_ purchaseKey masterKey codeText = case parseBadgeCode <$> getLedgerEntries db badgePurchaseId 0 -- code_used would make the client drop its keys, so the holder could never get the badge back. KeyRedeemedUnreadable -> - logError "badge service: a redeemed code's credential is missing or unreadable" $> Left (errorResponse STEInternal) + logError "store service: a redeemed code's credential is missing or unreadable" $> Left (errorResponse STEInternal) KeyUnredeemed -- Revoked is checked first, so it answers as if the code never existed. | Just _ <- revokedAt -> pure $ Left $ errorResponse STECodeInvalid @@ -406,7 +406,7 @@ issueBadgeCmd key cc purchaseKey BadgeBalance {lastEntry} = do Nothing -> writeIssued badgePurchaseId tip (maybeToList lapsed) now Nothing Just e -> credentialForEntry key masterKey e >>= \case - Left err -> logError ("badge service signing failed: " <> T.pack err) $> errorResponse STEInternal + Left err -> logError ("store service signing failed: " <> T.pack err) $> errorResponse STEInternal Right signed -> writeIssued badgePurchaseId tip (maybeToList lapsed) now $ Just $ issuanceAfter current signed where diff --git a/apps/simplex-badge-service/src/BadgeService/Store.hs b/apps/simplex-store-service/src/StoreService/Store.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Store.hs rename to apps/simplex-store-service/src/StoreService/Store.hs index f455b332bd..0b971e592f 100644 --- a/apps/simplex-badge-service/src/BadgeService/Store.hs +++ b/apps/simplex-store-service/src/StoreService/Store.hs @@ -5,7 +5,7 @@ {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Store +module StoreService.Store ( IssuedCode (..), KeyRedemption (..), KeyPurchase (..), @@ -36,7 +36,7 @@ module BadgeService.Store ) where -import BadgeService.Store.Invoices (executeChanging) +import StoreService.Store.Invoices (executeChanging) import qualified Data.Aeson as J import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Lazy.Char8 as LB diff --git a/apps/simplex-badge-service/src/BadgeService/Store/Invoices.hs b/apps/simplex-store-service/src/StoreService/Store/Invoices.hs similarity index 99% rename from apps/simplex-badge-service/src/BadgeService/Store/Invoices.hs rename to apps/simplex-store-service/src/StoreService/Store/Invoices.hs index 7b31b58b3d..d184614572 100644 --- a/apps/simplex-badge-service/src/BadgeService/Store/Invoices.hs +++ b/apps/simplex-store-service/src/StoreService/Store/Invoices.hs @@ -5,7 +5,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeOperators #-} -module BadgeService.Store.Invoices +module StoreService.Store.Invoices ( InvoiceRow (..), InvoicePayment (..), paymentHolds, @@ -63,12 +63,12 @@ import Simplex.Messaging.Encoding.String (textEncode) import Simplex.Messaging.Util (safeDecodeUtf8, tshow) #if defined(dbPostgres) -import BadgeService.Store.Postgres.Migrations (servicePrefix, withPrefix) +import StoreService.Store.Postgres.Migrations (servicePrefix, withPrefix) import Database.PostgreSQL.Simple (Only (..), Query, ToRow, (:.) (..)) import qualified Database.PostgreSQL.Simple as PSQL import Database.PostgreSQL.Simple.Errors (ConstraintViolation (..), constraintViolation) #else -import BadgeService.Store.SQLite.Migrations (servicePrefix, withPrefix) +import StoreService.Store.SQLite.Migrations (servicePrefix, withPrefix) import Database.SQLite.Simple (Only (..), Query, ToRow, (:.) (..)) import qualified Database.SQLite.Simple as SQL #endif diff --git a/apps/simplex-badge-service/src/BadgeService/Store/Migrate.hs b/apps/simplex-store-service/src/StoreService/Store/Migrate.hs similarity index 67% rename from apps/simplex-badge-service/src/BadgeService/Store/Migrate.hs rename to apps/simplex-store-service/src/StoreService/Store/Migrate.hs index 506043c262..d5dfc9dac2 100644 --- a/apps/simplex-badge-service/src/BadgeService/Store/Migrate.hs +++ b/apps/simplex-store-service/src/StoreService/Store/Migrate.hs @@ -3,12 +3,12 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module BadgeService.Store.Migrate - ( runBadgeServiceMigrations, +module StoreService.Store.Migrate + ( runStoreServiceMigrations, ) where -import BadgeService.Options +import StoreService.Options import Simplex.Chat.Controller (ChatConfig (..)) import Simplex.Chat.Options (CoreChatOpts (..)) import Simplex.Chat.Options.DB @@ -18,22 +18,22 @@ import Simplex.Messaging.Agent.Store.Shared (MigrationConfig (..), MigrationConf import System.Exit (exitFailure) #if defined(dbPostgres) -import BadgeService.Store.Postgres.Migrations +import StoreService.Store.Postgres.Migrations #else -import BadgeService.Store.SQLite.Migrations +import StoreService.Store.SQLite.Migrations #endif -runBadgeServiceMigrations :: BadgeServiceOpts -> ChatConfig -> DBStore -> IO () -runBadgeServiceMigrations opts ChatConfig {confirmMigrations} chatStore = +runStoreServiceMigrations :: StoreServiceOpts -> ChatConfig -> DBStore -> IO () +runStoreServiceMigrations opts ChatConfig {confirmMigrations} chatStore = migrateDBSchema chatStore (toDBOpts dbOptions chatSuffix False []) (Just "sx_badge_service_migrations") - badgeServiceSchemaMigrations + storeServiceSchemaMigrations MigrationConfig {confirm, backupPath = Nothing} - >>= either (exit . ("badge service migrations " <>) . show) pure + >>= either (exit . ("store service migrations " <>) . show) pure where - BadgeServiceOpts {coreOptions = CoreChatOpts {dbOptions, yesToUpMigrations}} = opts + StoreServiceOpts {coreOptions = CoreChatOpts {dbOptions, yesToUpMigrations}} = opts confirm = if confirmMigrations == MCConsole && yesToUpMigrations then MCYesUp else confirmMigrations exit :: String -> IO a diff --git a/apps/simplex-badge-service/src/BadgeService/Store/Postgres/Migrations.hs b/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs similarity index 97% rename from apps/simplex-badge-service/src/BadgeService/Store/Postgres/Migrations.hs rename to apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs index f096d3098d..3e2950fc8d 100644 --- a/apps/simplex-badge-service/src/BadgeService/Store/Postgres/Migrations.hs +++ b/apps/simplex-store-service/src/StoreService/Store/Postgres/Migrations.hs @@ -2,7 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} -module BadgeService.Store.Postgres.Migrations (badgeServiceSchemaMigrations, servicePrefix, withPrefix) where +module StoreService.Store.Postgres.Migrations (storeServiceSchemaMigrations, servicePrefix, withPrefix) where import Data.List (sortOn) import Data.Text (Text) @@ -10,8 +10,8 @@ import Simplex.Chat.Store.Postgres.Migrations.M20260915_user_badges (badgeSchema import Simplex.Messaging.Agent.Store.Shared (Migration (..)) import Text.RawString.QQ (r) -badgeServiceSchemaMigrations :: [Migration] -badgeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations +storeServiceSchemaMigrations :: [Migration] +storeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations where migration (name, up, down) = Migration {name, up, down} diff --git a/apps/simplex-badge-service/src/BadgeService/Store/SQLite/Migrations.hs b/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs similarity index 97% rename from apps/simplex-badge-service/src/BadgeService/Store/SQLite/Migrations.hs rename to apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs index cd89859686..9516adc0b6 100644 --- a/apps/simplex-badge-service/src/BadgeService/Store/SQLite/Migrations.hs +++ b/apps/simplex-store-service/src/StoreService/Store/SQLite/Migrations.hs @@ -2,7 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} -module BadgeService.Store.SQLite.Migrations (badgeServiceSchemaMigrations, servicePrefix, withPrefix) where +module StoreService.Store.SQLite.Migrations (storeServiceSchemaMigrations, servicePrefix, withPrefix) where import Data.List (sortOn) import Data.Text (Text) @@ -11,8 +11,8 @@ import Database.SQLite.Simple.QQ (sql) import Simplex.Chat.Store.SQLite.Migrations.M20260915_user_badges (badgeSchema, badgeSchemaDown, withPrefix) import Simplex.Messaging.Agent.Store.Shared (Migration (..)) -badgeServiceSchemaMigrations :: [Migration] -badgeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations +storeServiceSchemaMigrations :: [Migration] +storeServiceSchemaMigrations = sortOn name $ map migration schemaMigrations where migration (name, up, down) = Migration {name, up = fromQuery up, down = fromQuery <$> down} diff --git a/apps/simplex-badge-service/src/BadgeService/Waiters.hs b/apps/simplex-store-service/src/StoreService/Waiters.hs similarity index 98% rename from apps/simplex-badge-service/src/BadgeService/Waiters.hs rename to apps/simplex-store-service/src/StoreService/Waiters.hs index d074b28185..aeee8152ca 100644 --- a/apps/simplex-badge-service/src/BadgeService/Waiters.hs +++ b/apps/simplex-store-service/src/StoreService/Waiters.hs @@ -1,6 +1,6 @@ {-# LANGUAGE NamedFieldPuns #-} -module BadgeService.Waiters (Waiters, Seen, newWaiters, publish, publishPayment, awaitStatus, waitingCount, waitingCountSTM) where +module StoreService.Waiters (Waiters, Seen, newWaiters, publish, publishPayment, awaitStatus, waitingCount, waitingCountSTM) where import Control.Concurrent.STM import Control.Exception (bracket) diff --git a/apps/simplex-badge-service/src/BadgeService/Web/Server.hs b/apps/simplex-store-service/src/StoreService/Web/Server.hs similarity index 98% rename from apps/simplex-badge-service/src/BadgeService/Web/Server.hs rename to apps/simplex-store-service/src/StoreService/Web/Server.hs index 0c742bccf1..16fa2b7ba5 100644 --- a/apps/simplex-badge-service/src/BadgeService/Web/Server.hs +++ b/apps/simplex-store-service/src/StoreService/Web/Server.hs @@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module BadgeService.Web.Server +module StoreService.Web.Server ( WebEnv (..), Limit (..), newWebEnv, @@ -19,15 +19,15 @@ module BadgeService.Web.Server ) where -import BadgeService.Catalog (PricedOffer (..), priceOffer) -import BadgeService.Config (BTCPayConfig (..), ListenerConfig (..), ServiceConfig (..), SpeedPolicy (..), StripeConfig (..), defaultExpiryMinutes, defaultSessionMinutes) -import BadgeService.Poller (ReadHints, queueReadHint) -import BadgeService.Providers (OrderDraft (..), Provider (..), ProviderError (..), ProviderInvoice (..), WebhookError (..)) -import BadgeService.Store.Invoices (CreateError (..), InvoicePayment (..), InvoiceRow (..), NewInvoice (..), cancelOpenInvoice, codeHashExists, createInvoiceRows, cryptoCurrencyText, getInvoice, getInvoiceByProviderRef, invoiceStatusText, newInvoiceId, paymentHolds, readCatalogRows, textToInvoiceStatus, truncateToSecond) -import BadgeService.Waiters (Seen, Waiters, awaitStatus, publish) +import StoreService.Catalog (PricedOffer (..), priceOffer) +import StoreService.Config (BTCPayConfig (..), ListenerConfig (..), ServiceConfig (..), SpeedPolicy (..), StripeConfig (..), defaultExpiryMinutes, defaultSessionMinutes) +import StoreService.Poller (ReadHints, queueReadHint) +import StoreService.Providers (OrderDraft (..), Provider (..), ProviderError (..), ProviderInvoice (..), WebhookError (..)) +import StoreService.Store.Invoices (CreateError (..), InvoicePayment (..), InvoiceRow (..), NewInvoice (..), cancelOpenInvoice, codeHashExists, createInvoiceRows, cryptoCurrencyText, getInvoice, getInvoiceByProviderRef, invoiceStatusText, newInvoiceId, paymentHolds, readCatalogRows, textToInvoiceStatus, truncateToSecond) +import StoreService.Waiters (Seen, Waiters, awaitStatus, publish) import Control.Concurrent.STM import qualified Control.Exception as E -import BadgeService.Log (logError, logInfo, logWarn) +import StoreService.Log (logError, logInfo, logWarn) import Control.Monad (forM_, when) import Data.Aeson ((.=)) import qualified Data.Aeson as J @@ -336,7 +336,7 @@ exportWebapp lc@ListenerConfig {lStaticDir, lWebappExportDir} stripeCfg = emptyDir out copyTree lStaticDir out prepareShell lc stripeCfg >>= mapM_ (LB.writeFile (out "index.html")) - logInfo ("badge service: exported the webapp to " <> T.pack out) + logInfo ("store service: exported the webapp to " <> T.pack out) -- | Contents only: the directory itself may be a bind or volume mount point that cannot be removed. emptyDir :: FilePath -> IO () @@ -735,7 +735,7 @@ runWebListener env = do warnIfHeaderTrustIsExposed :: ListenerConfig -> IO () warnIfHeaderTrustIsExposed ListenerConfig {lHost, lTrustForwardedFor} = when (lTrustForwardedFor && not (isLoopbackHost lHost)) $ - logWarn ("badge service: trust_forwarded_for is on and the listener binds " <> lHost <> "; every caller can then choose its own rate limit bucket unless a proxy sets the header") + logWarn ("store service: trust_forwarded_for is on and the listener binds " <> lHost <> "; every caller can then choose its own rate limit bucket unless a proxy sets the header") isLoopbackHost :: Text -> Bool isLoopbackHost h = h `elem` ["127.0.0.1", "::1", "localhost"] diff --git a/apps/simplex-badge-service/badge_service.ini.example b/apps/simplex-store-service/store_service.ini.example similarity index 97% rename from apps/simplex-badge-service/badge_service.ini.example rename to apps/simplex-store-service/store_service.ini.example index 00584fed41..47bcc39fa4 100644 --- a/apps/simplex-badge-service/badge_service.ini.example +++ b/apps/simplex-store-service/store_service.ini.example @@ -3,8 +3,8 @@ ; the long poll's `wait`, `seenPaid` and `seenFull` all travel in it host = 127.0.0.1 port = 8080 -; required: the directory `npm run build` writes in apps/simplex-badge-service/web -static_dir = ./apps/simplex-badge-service/web/dist +; required: the directory `npm run build` writes in apps/simplex-store-service/web +static_dir = ./apps/simplex-store-service/web/dist ; serve the webapp over HTTP. On (default) is the all-in-one deployment. Off is a split deployment ; where a reverse proxy serves the exported folder and this service is only the API and webhooks. serve_webapp = on diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-expired.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-expired.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-expired.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-expired.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-invalid.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-invalid.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-invalid.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-invalid.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-alien-method.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-list-alien-method.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-alien-method.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-list-alien-method.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-alien-status.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-list-alien-status.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-alien-status.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-list-alien-status.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-no-id.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-list-no-id.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-no-id.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-list-no-id.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-no-payment-methods.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-list-no-payment-methods.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-list-no-payment-methods.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-list-no-payment-methods.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-list.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-list.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-list.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-list.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-new.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-new.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-new.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-new.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-processing.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-processing.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-processing.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-processing.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/invoice-settled.json b/apps/simplex-store-service/test-fixtures/btcpay/invoice-settled.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/invoice-settled.json rename to apps/simplex-store-service/test-fixtures/btcpay/invoice-settled.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-btc.json b/apps/simplex-store-service/test-fixtures/btcpay/payment-methods-btc.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-btc.json rename to apps/simplex-store-service/test-fixtures/btcpay/payment-methods-btc.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-no-amount.json b/apps/simplex-store-service/test-fixtures/btcpay/payment-methods-no-amount.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-no-amount.json rename to apps/simplex-store-service/test-fixtures/btcpay/payment-methods-no-amount.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-no-destination.json b/apps/simplex-store-service/test-fixtures/btcpay/payment-methods-no-destination.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-no-destination.json rename to apps/simplex-store-service/test-fixtures/btcpay/payment-methods-no-destination.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-xmr.json b/apps/simplex-store-service/test-fixtures/btcpay/payment-methods-xmr.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/payment-methods-xmr.json rename to apps/simplex-store-service/test-fixtures/btcpay/payment-methods-xmr.json diff --git a/apps/simplex-badge-service/test-fixtures/btcpay/store-payment-methods.json b/apps/simplex-store-service/test-fixtures/btcpay/store-payment-methods.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/btcpay/store-payment-methods.json rename to apps/simplex-store-service/test-fixtures/btcpay/store-payment-methods.json diff --git a/apps/simplex-badge-service/test-fixtures/stripe/intent-canceled.json b/apps/simplex-store-service/test-fixtures/stripe/intent-canceled.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/stripe/intent-canceled.json rename to apps/simplex-store-service/test-fixtures/stripe/intent-canceled.json diff --git a/apps/simplex-badge-service/test-fixtures/stripe/intent-list-cursor-gap.json b/apps/simplex-store-service/test-fixtures/stripe/intent-list-cursor-gap.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/stripe/intent-list-cursor-gap.json rename to apps/simplex-store-service/test-fixtures/stripe/intent-list-cursor-gap.json diff --git a/apps/simplex-badge-service/test-fixtures/stripe/intent-list.json b/apps/simplex-store-service/test-fixtures/stripe/intent-list.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/stripe/intent-list.json rename to apps/simplex-store-service/test-fixtures/stripe/intent-list.json diff --git a/apps/simplex-badge-service/test-fixtures/stripe/intent-open.json b/apps/simplex-store-service/test-fixtures/stripe/intent-open.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/stripe/intent-open.json rename to apps/simplex-store-service/test-fixtures/stripe/intent-open.json diff --git a/apps/simplex-badge-service/test-fixtures/stripe/intent-succeeded.json b/apps/simplex-store-service/test-fixtures/stripe/intent-succeeded.json similarity index 100% rename from apps/simplex-badge-service/test-fixtures/stripe/intent-succeeded.json rename to apps/simplex-store-service/test-fixtures/stripe/intent-succeeded.json diff --git a/apps/simplex-badge-service/web/.gitignore b/apps/simplex-store-service/web/.gitignore similarity index 100% rename from apps/simplex-badge-service/web/.gitignore rename to apps/simplex-store-service/web/.gitignore diff --git a/apps/simplex-badge-service/web/README.md b/apps/simplex-store-service/web/README.md similarity index 95% rename from apps/simplex-badge-service/web/README.md rename to apps/simplex-store-service/web/README.md index 0004b44944..5e42486769 100644 --- a/apps/simplex-badge-service/web/README.md +++ b/apps/simplex-store-service/web/README.md @@ -68,23 +68,23 @@ is plain TypeScript, tested directly in Node. ## Running the real service against this build **`mock/server.py` is not the service.** The service is the Haskell -executable `simplex-badge-service`, in `apps/simplex-badge-service/`, and +executable `simplex-store-service`, in `apps/simplex-store-service/`, and `dist/` is the directory its listener serves. Nothing about the page changes between the two — the service matches this build, never the reverse. ``` # 1. build the page. dist/ is the deploy tree: index.html, sw.js, assets// -cd apps/simplex-badge-service/web +cd apps/simplex-store-service/web npm install && npm run build cd ../../.. # 2. configuration, from the committed example. Copy it IN # PLACE, beside the example: that path is the one .gitignore covers, and this # file is about to hold a real api_key and webhook_secret. -cd apps/simplex-badge-service -cp badge_service.ini.example badge_service.ini +cd apps/simplex-store-service +cp store_service.ini.example store_service.ini cd ../.. -# static_dir = ./apps/simplex-badge-service/web/dist <- the build above +# static_dir = ./apps/simplex-store-service/web/dist <- the build above # [btcpay] = a real store's host, api_key, store_id and webhook_secret, # or delete the whole section to disable BTC and XMR (the provider-unavailable screen) # [issuer] = uncomment the section and put a real issuer secret in private_key, @@ -98,28 +98,28 @@ cd ../.. # without a key it could sign a credential with. Put it in the ini's [issuer] # section, or pass --issuer-key-idx and --issuer-secret, which override it. # `simplex-chat badge keygen` prints a pair. -cabal run simplex-badge-service -- \ - --service-config apps/simplex-badge-service/badge_service.ini +cabal run simplex-store-service -- \ + --service-config apps/simplex-store-service/store_service.ini ``` Then open the `[listener]` host and port — `http://127.0.0.1:8080/` as the example ships. `static_dir` is relative to the working directory, so run from the repository root or make it absolute. -**The executable is the whole badge service, not just this listener.** -`badgeService` starts `simplexChatCore` unconditionally and the web listener +**The executable is the whole store service, not just this listener.** +`storeService` starts `simplexChatCore` unconditionally and the web listener is one lane beside the chat one, so a local run opens or creates a chat database (`printDbOpts` names the path at startup) and does agent network work. `--no-address` skips creating the service's contact address on first start, which a run of the web listener alone does not need. *These three steps are read out of `Options.hs`, `Service.hs`, `Config.hs` and -`badge_service.ini.example` rather than from a run — driving them end to end +`store_service.ini.example` rather than from a run — driving them end to end needs a chat database and a real BTCPay store.* What the mock cannot stand in for: -| | `mock/server.py` | `simplex-badge-service` | +| | `mock/server.py` | `simplex-store-service` | |---|---|---| | Invoices | invented in memory | created at BTCPay over Greenfield | | Payment detected by | `POST /control/settle/:id`, an endpoint that exists nowhere else | a poller reading the provider, which is the only thing that carries authority | @@ -129,10 +129,10 @@ What the mock cannot stand in for: The Haskell side's own end-to-end coverage of that lane — checkout, payment, polling, partial payment, expiry, late settlement and replay, all against a -fake Greenfield — is `tests/Bots/BadgeService/WebTests.hs`: +fake Greenfield — is `tests/Bots/StoreService/WebTests.hs`: ``` -cabal test --test-options='-m "/SimpleX badge service/"' +cabal test --test-options='-m "/SimpleX store service/"' ``` ## Running the mock diff --git a/apps/simplex-badge-service/web/build.js b/apps/simplex-store-service/web/build.js similarity index 100% rename from apps/simplex-badge-service/web/build.js rename to apps/simplex-store-service/web/build.js diff --git a/apps/simplex-badge-service/web/check-tests.js b/apps/simplex-store-service/web/check-tests.js similarity index 100% rename from apps/simplex-badge-service/web/check-tests.js rename to apps/simplex-store-service/web/check-tests.js diff --git a/apps/simplex-badge-service/web/mock/server.py b/apps/simplex-store-service/web/mock/server.py similarity index 99% rename from apps/simplex-badge-service/web/mock/server.py rename to apps/simplex-store-service/web/mock/server.py index af7612a084..f550ab1ced 100644 --- a/apps/simplex-badge-service/web/mock/server.py +++ b/apps/simplex-store-service/web/mock/server.py @@ -311,7 +311,7 @@ def main(): # so only a publishable key (pk_) is allowed. sys.exit("mock: STRIPE_PUBLISHABLE_KEY must be a publishable key (pk_...)") server = Server(("127.0.0.1", port), Handler) - print(f"mock badge service on http://localhost:{port}", flush=True) + print(f"mock store service on http://localhost:{port}", flush=True) print("stripe: " + (f"publishable key {STRIPE_PUBLISHABLE_KEY[:11]}… — the real card form" if STRIPE_PUBLISHABLE_KEY else "no STRIPE_PUBLISHABLE_KEY — the card path renders the development stand-in"), diff --git a/apps/simplex-badge-service/web/package-lock.json b/apps/simplex-store-service/web/package-lock.json similarity index 100% rename from apps/simplex-badge-service/web/package-lock.json rename to apps/simplex-store-service/web/package-lock.json diff --git a/apps/simplex-badge-service/web/package.json b/apps/simplex-store-service/web/package.json similarity index 100% rename from apps/simplex-badge-service/web/package.json rename to apps/simplex-store-service/web/package.json diff --git a/apps/simplex-badge-service/web/public/fonts/GT-Walsheim-LC-Bold.woff2 b/apps/simplex-store-service/web/public/fonts/GT-Walsheim-LC-Bold.woff2 similarity index 100% rename from apps/simplex-badge-service/web/public/fonts/GT-Walsheim-LC-Bold.woff2 rename to apps/simplex-store-service/web/public/fonts/GT-Walsheim-LC-Bold.woff2 diff --git a/apps/simplex-badge-service/web/public/fonts/Manrope-Bold.woff2 b/apps/simplex-store-service/web/public/fonts/Manrope-Bold.woff2 similarity index 100% rename from apps/simplex-badge-service/web/public/fonts/Manrope-Bold.woff2 rename to apps/simplex-store-service/web/public/fonts/Manrope-Bold.woff2 diff --git a/apps/simplex-badge-service/web/public/fonts/Manrope-Medium.woff2 b/apps/simplex-store-service/web/public/fonts/Manrope-Medium.woff2 similarity index 100% rename from apps/simplex-badge-service/web/public/fonts/Manrope-Medium.woff2 rename to apps/simplex-store-service/web/public/fonts/Manrope-Medium.woff2 diff --git a/apps/simplex-badge-service/web/public/fonts/Manrope-Regular.woff2 b/apps/simplex-store-service/web/public/fonts/Manrope-Regular.woff2 similarity index 100% rename from apps/simplex-badge-service/web/public/fonts/Manrope-Regular.woff2 rename to apps/simplex-store-service/web/public/fonts/Manrope-Regular.woff2 diff --git a/apps/simplex-badge-service/web/public/fonts/Manrope-SemiBold.woff2 b/apps/simplex-store-service/web/public/fonts/Manrope-SemiBold.woff2 similarity index 100% rename from apps/simplex-badge-service/web/public/fonts/Manrope-SemiBold.woff2 rename to apps/simplex-store-service/web/public/fonts/Manrope-SemiBold.woff2 diff --git a/apps/simplex-badge-service/web/public/img/hero-dark.png b/apps/simplex-store-service/web/public/img/hero-dark.png similarity index 100% rename from apps/simplex-badge-service/web/public/img/hero-dark.png rename to apps/simplex-store-service/web/public/img/hero-dark.png diff --git a/apps/simplex-badge-service/web/public/img/hero-light.png b/apps/simplex-store-service/web/public/img/hero-light.png similarity index 100% rename from apps/simplex-badge-service/web/public/img/hero-light.png rename to apps/simplex-store-service/web/public/img/hero-light.png diff --git a/apps/simplex-badge-service/web/public/img/symbol-dark.svg b/apps/simplex-store-service/web/public/img/symbol-dark.svg similarity index 100% rename from apps/simplex-badge-service/web/public/img/symbol-dark.svg rename to apps/simplex-store-service/web/public/img/symbol-dark.svg diff --git a/apps/simplex-badge-service/web/public/img/symbol-light.svg b/apps/simplex-store-service/web/public/img/symbol-light.svg similarity index 100% rename from apps/simplex-badge-service/web/public/img/symbol-light.svg rename to apps/simplex-store-service/web/public/img/symbol-light.svg diff --git a/apps/simplex-badge-service/web/public/img/wordmark-dark.svg b/apps/simplex-store-service/web/public/img/wordmark-dark.svg similarity index 100% rename from apps/simplex-badge-service/web/public/img/wordmark-dark.svg rename to apps/simplex-store-service/web/public/img/wordmark-dark.svg diff --git a/apps/simplex-badge-service/web/public/img/wordmark-light.svg b/apps/simplex-store-service/web/public/img/wordmark-light.svg similarity index 100% rename from apps/simplex-badge-service/web/public/img/wordmark-light.svg rename to apps/simplex-store-service/web/public/img/wordmark-light.svg diff --git a/apps/simplex-badge-service/web/public/index.html b/apps/simplex-store-service/web/public/index.html similarity index 100% rename from apps/simplex-badge-service/web/public/index.html rename to apps/simplex-store-service/web/public/index.html diff --git a/apps/simplex-badge-service/web/public/styles.css b/apps/simplex-store-service/web/public/styles.css similarity index 100% rename from apps/simplex-badge-service/web/public/styles.css rename to apps/simplex-store-service/web/public/styles.css diff --git a/apps/simplex-badge-service/web/public/sw.js b/apps/simplex-store-service/web/public/sw.js similarity index 100% rename from apps/simplex-badge-service/web/public/sw.js rename to apps/simplex-store-service/web/public/sw.js diff --git a/apps/simplex-badge-service/web/src/api.ts b/apps/simplex-store-service/web/src/api.ts similarity index 100% rename from apps/simplex-badge-service/web/src/api.ts rename to apps/simplex-store-service/web/src/api.ts diff --git a/apps/simplex-badge-service/web/src/catalog.ts b/apps/simplex-store-service/web/src/catalog.ts similarity index 100% rename from apps/simplex-badge-service/web/src/catalog.ts rename to apps/simplex-store-service/web/src/catalog.ts diff --git a/apps/simplex-badge-service/web/src/codes.ts b/apps/simplex-store-service/web/src/codes.ts similarity index 100% rename from apps/simplex-badge-service/web/src/codes.ts rename to apps/simplex-store-service/web/src/codes.ts diff --git a/apps/simplex-badge-service/web/src/crowdfunding.ts b/apps/simplex-store-service/web/src/crowdfunding.ts similarity index 100% rename from apps/simplex-badge-service/web/src/crowdfunding.ts rename to apps/simplex-store-service/web/src/crowdfunding.ts diff --git a/apps/simplex-badge-service/web/src/domain.ts b/apps/simplex-store-service/web/src/domain.ts similarity index 100% rename from apps/simplex-badge-service/web/src/domain.ts rename to apps/simplex-store-service/web/src/domain.ts diff --git a/apps/simplex-badge-service/web/src/embed.ts b/apps/simplex-store-service/web/src/embed.ts similarity index 100% rename from apps/simplex-badge-service/web/src/embed.ts rename to apps/simplex-store-service/web/src/embed.ts diff --git a/apps/simplex-badge-service/web/src/flow.ts b/apps/simplex-store-service/web/src/flow.ts similarity index 100% rename from apps/simplex-badge-service/web/src/flow.ts rename to apps/simplex-store-service/web/src/flow.ts diff --git a/apps/simplex-badge-service/web/src/format.ts b/apps/simplex-store-service/web/src/format.ts similarity index 100% rename from apps/simplex-badge-service/web/src/format.ts rename to apps/simplex-store-service/web/src/format.ts diff --git a/apps/simplex-badge-service/web/src/icons.ts b/apps/simplex-store-service/web/src/icons.ts similarity index 100% rename from apps/simplex-badge-service/web/src/icons.ts rename to apps/simplex-store-service/web/src/icons.ts diff --git a/apps/simplex-badge-service/web/src/main.ts b/apps/simplex-store-service/web/src/main.ts similarity index 100% rename from apps/simplex-badge-service/web/src/main.ts rename to apps/simplex-store-service/web/src/main.ts diff --git a/apps/simplex-badge-service/web/src/order.ts b/apps/simplex-store-service/web/src/order.ts similarity index 100% rename from apps/simplex-badge-service/web/src/order.ts rename to apps/simplex-store-service/web/src/order.ts diff --git a/apps/simplex-badge-service/web/src/parse.ts b/apps/simplex-store-service/web/src/parse.ts similarity index 100% rename from apps/simplex-badge-service/web/src/parse.ts rename to apps/simplex-store-service/web/src/parse.ts diff --git a/apps/simplex-badge-service/web/src/qr.ts b/apps/simplex-store-service/web/src/qr.ts similarity index 100% rename from apps/simplex-badge-service/web/src/qr.ts rename to apps/simplex-store-service/web/src/qr.ts diff --git a/apps/simplex-badge-service/web/src/routing.ts b/apps/simplex-store-service/web/src/routing.ts similarity index 100% rename from apps/simplex-badge-service/web/src/routing.ts rename to apps/simplex-store-service/web/src/routing.ts diff --git a/apps/simplex-badge-service/web/src/screens.ts b/apps/simplex-store-service/web/src/screens.ts similarity index 100% rename from apps/simplex-badge-service/web/src/screens.ts rename to apps/simplex-store-service/web/src/screens.ts diff --git a/apps/simplex-badge-service/web/src/store.ts b/apps/simplex-store-service/web/src/store.ts similarity index 100% rename from apps/simplex-badge-service/web/src/store.ts rename to apps/simplex-store-service/web/src/store.ts diff --git a/apps/simplex-badge-service/web/src/stripe.ts b/apps/simplex-store-service/web/src/stripe.ts similarity index 100% rename from apps/simplex-badge-service/web/src/stripe.ts rename to apps/simplex-store-service/web/src/stripe.ts diff --git a/apps/simplex-badge-service/web/test/boot.ts b/apps/simplex-store-service/web/test/boot.ts similarity index 100% rename from apps/simplex-badge-service/web/test/boot.ts rename to apps/simplex-store-service/web/test/boot.ts diff --git a/apps/simplex-badge-service/web/test/build.test.ts b/apps/simplex-store-service/web/test/build.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/build.test.ts rename to apps/simplex-store-service/web/test/build.test.ts diff --git a/apps/simplex-badge-service/web/test/catalog.test.ts b/apps/simplex-store-service/web/test/catalog.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/catalog.test.ts rename to apps/simplex-store-service/web/test/catalog.test.ts diff --git a/apps/simplex-badge-service/web/test/codes.test.ts b/apps/simplex-store-service/web/test/codes.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/codes.test.ts rename to apps/simplex-store-service/web/test/codes.test.ts diff --git a/apps/simplex-badge-service/web/test/css.ts b/apps/simplex-store-service/web/test/css.ts similarity index 100% rename from apps/simplex-badge-service/web/test/css.ts rename to apps/simplex-store-service/web/test/css.ts diff --git a/apps/simplex-badge-service/web/test/design.test.ts b/apps/simplex-store-service/web/test/design.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/design.test.ts rename to apps/simplex-store-service/web/test/design.test.ts diff --git a/apps/simplex-badge-service/web/test/embed.test.ts b/apps/simplex-store-service/web/test/embed.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/embed.test.ts rename to apps/simplex-store-service/web/test/embed.test.ts diff --git a/apps/simplex-badge-service/web/test/flow-controller.test.ts b/apps/simplex-store-service/web/test/flow-controller.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/flow-controller.test.ts rename to apps/simplex-store-service/web/test/flow-controller.test.ts diff --git a/apps/simplex-badge-service/web/test/flow.test.ts b/apps/simplex-store-service/web/test/flow.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/flow.test.ts rename to apps/simplex-store-service/web/test/flow.test.ts diff --git a/apps/simplex-badge-service/web/test/main-boot.test.ts b/apps/simplex-store-service/web/test/main-boot.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-boot.test.ts rename to apps/simplex-store-service/web/test/main-boot.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel-navigated.test.ts b/apps/simplex-store-service/web/test/main-cancel-navigated.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel-navigated.test.ts rename to apps/simplex-store-service/web/test/main-cancel-navigated.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel-race.test.ts b/apps/simplex-store-service/web/test/main-cancel-race.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel-race.test.ts rename to apps/simplex-store-service/web/test/main-cancel-race.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel-refusal.test.ts b/apps/simplex-store-service/web/test/main-cancel-refusal.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel-refusal.test.ts rename to apps/simplex-store-service/web/test/main-cancel-refusal.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel-refused-navigated.test.ts b/apps/simplex-store-service/web/test/main-cancel-refused-navigated.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel-refused-navigated.test.ts rename to apps/simplex-store-service/web/test/main-cancel-refused-navigated.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel-reopened.test.ts b/apps/simplex-store-service/web/test/main-cancel-reopened.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel-reopened.test.ts rename to apps/simplex-store-service/web/test/main-cancel-reopened.test.ts diff --git a/apps/simplex-badge-service/web/test/main-cancel.test.ts b/apps/simplex-store-service/web/test/main-cancel.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-cancel.test.ts rename to apps/simplex-store-service/web/test/main-cancel.test.ts diff --git a/apps/simplex-badge-service/web/test/main-card-cancel.test.ts b/apps/simplex-store-service/web/test/main-card-cancel.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-card-cancel.test.ts rename to apps/simplex-store-service/web/test/main-card-cancel.test.ts diff --git a/apps/simplex-badge-service/web/test/main-card-full-store.test.ts b/apps/simplex-store-service/web/test/main-card-full-store.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-card-full-store.test.ts rename to apps/simplex-store-service/web/test/main-card-full-store.test.ts diff --git a/apps/simplex-badge-service/web/test/main-card-return.test.ts b/apps/simplex-store-service/web/test/main-card-return.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-card-return.test.ts rename to apps/simplex-store-service/web/test/main-card-return.test.ts diff --git a/apps/simplex-badge-service/web/test/main-forget-race.test.ts b/apps/simplex-store-service/web/test/main-forget-race.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-forget-race.test.ts rename to apps/simplex-store-service/web/test/main-forget-race.test.ts diff --git a/apps/simplex-badge-service/web/test/main-forget-refused.test.ts b/apps/simplex-store-service/web/test/main-forget-refused.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-forget-refused.test.ts rename to apps/simplex-store-service/web/test/main-forget-refused.test.ts diff --git a/apps/simplex-badge-service/web/test/main-nav-race.test.ts b/apps/simplex-store-service/web/test/main-nav-race.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-nav-race.test.ts rename to apps/simplex-store-service/web/test/main-nav-race.test.ts diff --git a/apps/simplex-badge-service/web/test/main-no-storage.test.ts b/apps/simplex-store-service/web/test/main-no-storage.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-no-storage.test.ts rename to apps/simplex-store-service/web/test/main-no-storage.test.ts diff --git a/apps/simplex-badge-service/web/test/main-offline.test.ts b/apps/simplex-store-service/web/test/main-offline.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-offline.test.ts rename to apps/simplex-store-service/web/test/main-offline.test.ts diff --git a/apps/simplex-badge-service/web/test/main-one-month.test.ts b/apps/simplex-store-service/web/test/main-one-month.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-one-month.test.ts rename to apps/simplex-store-service/web/test/main-one-month.test.ts diff --git a/apps/simplex-badge-service/web/test/main-pay-forget.test.ts b/apps/simplex-store-service/web/test/main-pay-forget.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-pay-forget.test.ts rename to apps/simplex-store-service/web/test/main-pay-forget.test.ts diff --git a/apps/simplex-badge-service/web/test/main-pay-navigated.test.ts b/apps/simplex-store-service/web/test/main-pay-navigated.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-pay-navigated.test.ts rename to apps/simplex-store-service/web/test/main-pay-navigated.test.ts diff --git a/apps/simplex-badge-service/web/test/main-pay-rechoice.test.ts b/apps/simplex-store-service/web/test/main-pay-rechoice.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-pay-rechoice.test.ts rename to apps/simplex-store-service/web/test/main-pay-rechoice.test.ts diff --git a/apps/simplex-badge-service/web/test/main-pay-repaint.test.ts b/apps/simplex-store-service/web/test/main-pay-repaint.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-pay-repaint.test.ts rename to apps/simplex-store-service/web/test/main-pay-repaint.test.ts diff --git a/apps/simplex-badge-service/web/test/main-quota-full.test.ts b/apps/simplex-store-service/web/test/main-quota-full.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-quota-full.test.ts rename to apps/simplex-store-service/web/test/main-quota-full.test.ts diff --git a/apps/simplex-badge-service/web/test/main-resume-step.test.ts b/apps/simplex-store-service/web/test/main-resume-step.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-resume-step.test.ts rename to apps/simplex-store-service/web/test/main-resume-step.test.ts diff --git a/apps/simplex-badge-service/web/test/main-resume.test.ts b/apps/simplex-store-service/web/test/main-resume.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-resume.test.ts rename to apps/simplex-store-service/web/test/main-resume.test.ts diff --git a/apps/simplex-badge-service/web/test/main-silent-storage.test.ts b/apps/simplex-store-service/web/test/main-silent-storage.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main-silent-storage.test.ts rename to apps/simplex-store-service/web/test/main-silent-storage.test.ts diff --git a/apps/simplex-badge-service/web/test/main.test.ts b/apps/simplex-store-service/web/test/main.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/main.test.ts rename to apps/simplex-store-service/web/test/main.test.ts diff --git a/apps/simplex-badge-service/web/test/open-order.ts b/apps/simplex-store-service/web/test/open-order.ts similarity index 100% rename from apps/simplex-badge-service/web/test/open-order.ts rename to apps/simplex-store-service/web/test/open-order.ts diff --git a/apps/simplex-badge-service/web/test/qr.test.ts b/apps/simplex-store-service/web/test/qr.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/qr.test.ts rename to apps/simplex-store-service/web/test/qr.test.ts diff --git a/apps/simplex-badge-service/web/test/routing.test.ts b/apps/simplex-store-service/web/test/routing.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/routing.test.ts rename to apps/simplex-store-service/web/test/routing.test.ts diff --git a/apps/simplex-badge-service/web/test/screens.test.ts b/apps/simplex-store-service/web/test/screens.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/screens.test.ts rename to apps/simplex-store-service/web/test/screens.test.ts diff --git a/apps/simplex-badge-service/web/test/smoke.test.ts b/apps/simplex-store-service/web/test/smoke.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/smoke.test.ts rename to apps/simplex-store-service/web/test/smoke.test.ts diff --git a/apps/simplex-badge-service/web/test/store.test.ts b/apps/simplex-store-service/web/test/store.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/store.test.ts rename to apps/simplex-store-service/web/test/store.test.ts diff --git a/apps/simplex-badge-service/web/test/stripe.test.ts b/apps/simplex-store-service/web/test/stripe.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/stripe.test.ts rename to apps/simplex-store-service/web/test/stripe.test.ts diff --git a/apps/simplex-badge-service/web/test/stub-dom.ts b/apps/simplex-store-service/web/test/stub-dom.ts similarity index 100% rename from apps/simplex-badge-service/web/test/stub-dom.ts rename to apps/simplex-store-service/web/test/stub-dom.ts diff --git a/apps/simplex-badge-service/web/test/sw.test.ts b/apps/simplex-store-service/web/test/sw.test.ts similarity index 100% rename from apps/simplex-badge-service/web/test/sw.test.ts rename to apps/simplex-store-service/web/test/sw.test.ts diff --git a/apps/simplex-badge-service/web/tsconfig.json b/apps/simplex-store-service/web/tsconfig.json similarity index 100% rename from apps/simplex-badge-service/web/tsconfig.json rename to apps/simplex-store-service/web/tsconfig.json diff --git a/apps/simplex-badge-service/web/tsconfig.test.json b/apps/simplex-store-service/web/tsconfig.test.json similarity index 100% rename from apps/simplex-badge-service/web/tsconfig.test.json rename to apps/simplex-store-service/web/tsconfig.test.json diff --git a/scripts/badge-service/Dockerfile b/scripts/store-service/Dockerfile similarity index 86% rename from scripts/badge-service/Dockerfile rename to scripts/store-service/Dockerfile index b368aa32ac..a08832e786 100644 --- a/scripts/badge-service/Dockerfile +++ b/scripts/store-service/Dockerfile @@ -12,9 +12,9 @@ ARG NODE=24 FROM node:${NODE}-bookworm-slim AS web WORKDIR /web -COPY apps/simplex-badge-service/web/package.json apps/simplex-badge-service/web/package-lock.json ./ +COPY apps/simplex-store-service/web/package.json apps/simplex-store-service/web/package-lock.json ./ RUN npm ci -COPY apps/simplex-badge-service/web ./ +COPY apps/simplex-store-service/web ./ RUN npm run build FROM ubuntu:${UBUNTU} AS build @@ -44,7 +44,7 @@ COPY scripts/cabal.project.local.linux ./cabal.project.local COPY src ./src # Excluding web/ keeps a webapp edit from invalidating this layer and re-running the cabal build, # and the binary does not depend on it. -COPY --exclude=web apps/simplex-badge-service ./apps/simplex-badge-service +COPY --exclude=web apps/simplex-store-service ./apps/simplex-store-service # The store and build tree are cache mounts rather than layers, so the binary is copied out inside # the same RUN because dist-newstyle does not exist in the resulting layer. @@ -52,10 +52,10 @@ RUN --mount=type=cache,target=/root/.cabal \ --mount=type=cache,target=/src/dist-newstyle \ set -eu; \ cabal update; \ - cabal build --flags="+client_postgres" exe:simplex-badge-service; \ + cabal build --flags="+client_postgres" exe:simplex-store-service; \ mkdir -p /out; \ - cp "$(cabal list-bin --flags="+client_postgres" exe:simplex-badge-service)" /out/simplex-badge-service; \ - strip /out/simplex-badge-service + cp "$(cabal list-bin --flags="+client_postgres" exe:simplex-store-service)" /out/simplex-store-service; \ + strip /out/simplex-store-service FROM ubuntu:${UBUNTU} AS runtime @@ -80,7 +80,7 @@ RUN if existing_user=$(getent passwd ${USER_UID} | cut -d: -f1) && [ -n "${exist groupadd -g ${USER_GID} badge && \ useradd -u ${USER_UID} -g ${USER_GID} -m -d /home/badge badge -COPY --from=build /out/simplex-badge-service /usr/local/bin/simplex-badge-service +COPY --from=build /out/simplex-store-service /usr/local/bin/simplex-store-service COPY --from=web /web/dist /srv/web USER badge @@ -93,7 +93,7 @@ EXPOSE 8080 # The flags live in CMD so `docker compose run` can replace them while dumb-init still forwards # signals. -ENTRYPOINT ["dumb-init", "--", "simplex-badge-service"] +ENTRYPOINT ["dumb-init", "--", "simplex-store-service"] # Without --yes-migrate the service blocks on stdin at every schema change, and a container has no # console to answer. -CMD ["-d", "postgresql://simplex@127.0.0.1:5432/badge_service", "--create-schema", "--yes-migrate", "--service-config", "/etc/simplex-badge-service/badge_service.ini"] +CMD ["-d", "postgresql://simplex@127.0.0.1:5432/badge_service", "--create-schema", "--yes-migrate", "--service-config", "/etc/simplex-store-service/store_service.ini"] diff --git a/scripts/badge-service/Dockerfile.dockerignore b/scripts/store-service/Dockerfile.dockerignore similarity index 76% rename from scripts/badge-service/Dockerfile.dockerignore rename to scripts/store-service/Dockerfile.dockerignore index 915d409570..3e985872de 100644 --- a/scripts/badge-service/Dockerfile.dockerignore +++ b/scripts/store-service/Dockerfile.dockerignore @@ -14,17 +14,17 @@ scripts/* !apps apps/* -!apps/simplex-badge-service +!apps/simplex-store-service # Build output, caches, local state, and anything holding a secret. The ini is # mounted at run time and must never be baked into an image: it holds the issuer # secret, and with [btcpay] the API key and webhook secret too. -badge_service.ini +store_service.ini **/dist **/dist-newstyle **/node_modules **/*.db **/*.db-* -apps/simplex-badge-service/test-fixtures -apps/simplex-badge-service/web-traversal-test -apps/simplex-badge-service/web/build +apps/simplex-store-service/test-fixtures +apps/simplex-store-service/web-traversal-test +apps/simplex-store-service/web/build diff --git a/scripts/badge-service/compose.yml b/scripts/store-service/compose.yml similarity index 68% rename from scripts/badge-service/compose.yml rename to scripts/store-service/compose.yml index 1c7e485e08..25337aa914 100644 --- a/scripts/badge-service/compose.yml +++ b/scripts/store-service/compose.yml @@ -1,9 +1,9 @@ services: - badge-service: - image: simplex-badge-service:latest + store-service: + image: simplex-store-service:latest build: context: ../.. - dockerfile: scripts/badge-service/Dockerfile + dockerfile: scripts/store-service/Dockerfile args: USER_UID: ${USER_UID:-1000} USER_GID: ${USER_GID:-1000} @@ -17,8 +17,8 @@ services: - "--create-schema" - "--yes-migrate" - "--service-config" - - "/etc/simplex-badge-service/badge_service.ini" + - "/etc/simplex-store-service/store_service.ini" volumes: - - ./badge_service.ini:/etc/simplex-badge-service/badge_service.ini:ro + - ./store_service.ini:/etc/simplex-store-service/store_service.ini:ro - ./web:/srv/webapp stop_grace_period: 10s diff --git a/scripts/badge-service/badge_service.ini.example b/scripts/store-service/store_service.ini.example similarity index 100% rename from scripts/badge-service/badge_service.ini.example rename to scripts/store-service/store_service.ini.example diff --git a/simplex-chat.cabal b/simplex-chat.cabal index f78b061101..a4ae682f6b 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -426,34 +426,34 @@ library , template-haskell ==2.16.* , text >=1.2.4.0 && <1.3 -executable simplex-badge-service +executable simplex-store-service if flag(client_library) buildable: False main-is: Main.hs hs-source-dirs: - apps/simplex-badge-service - apps/simplex-badge-service/src + apps/simplex-store-service + apps/simplex-store-service/src default-extensions: StrictData other-modules: - BadgeService.Catalog - BadgeService.Codes - BadgeService.Config - BadgeService.Group - BadgeService.Group.Command - BadgeService.Log - BadgeService.Options - BadgeService.Orders - BadgeService.Poller - BadgeService.Providers - BadgeService.Providers.BTCPay - BadgeService.Providers.Stripe - BadgeService.Service - BadgeService.Store - BadgeService.Store.Invoices - BadgeService.Store.Migrate - BadgeService.Waiters - BadgeService.Web.Server + StoreService.Catalog + StoreService.Codes + StoreService.Config + StoreService.Group + StoreService.Group.Command + StoreService.Log + StoreService.Options + StoreService.Orders + StoreService.Poller + StoreService.Providers + StoreService.Providers.BTCPay + StoreService.Providers.Stripe + StoreService.Service + StoreService.Store + StoreService.Store.Invoices + StoreService.Store.Migrate + StoreService.Waiters + StoreService.Web.Server Paths_simplex_chat ghc-options: -O2 -Weverything -Wno-missing-exported-signatures -Wno-missing-import-lists -Wno-missed-specialisations -Wno-all-missed-specialisations -Wno-unsafe -Wno-safe -Wno-missing-local-signatures -Wno-missing-kind-signatures -Wno-missing-deriving-strategies -Wno-monomorphism-restriction -Wno-prepositive-qualified-module -Wno-unused-packages -Wno-implicit-prelude -Wno-missing-safe-haskell-mode -Wno-missing-export-lists -Wno-partial-fields -Wcompat -Werror=incomplete-record-updates -Werror=incomplete-patterns -Werror=missing-methods -Werror=incomplete-uni-patterns -Werror=tabs -Wredundant-constraints -Wincomplete-record-updates -Wunused-type-patterns -Werror=name-shadowing -threaded -rtsopts build-depends: @@ -484,14 +484,14 @@ executable simplex-badge-service default-language: Haskell2010 if flag(client_postgres) other-modules: - BadgeService.Store.Postgres.Migrations + StoreService.Store.Postgres.Migrations build-depends: postgresql-simple ==0.7.* , raw-strings-qq ==1.1.* cpp-options: -DdbPostgres else other-modules: - BadgeService.Store.SQLite.Migrations + StoreService.Store.SQLite.Migrations build-depends: sqlcipher-simple ==0.4.* if impl(ghc >= 9.6.2) @@ -728,40 +728,20 @@ test-suite simplex-chat-test API.Docs.Syntax.Types API.Docs.Types API.TypeInfo - BadgeService.Catalog - BadgeService.Codes - BadgeService.Config - BadgeService.Group - BadgeService.Group.Command - BadgeService.Log - BadgeService.Names.Chain - BadgeService.Names.Registration - BadgeService.Options - BadgeService.Orders - BadgeService.Poller - BadgeService.Providers - BadgeService.Providers.BTCPay - BadgeService.Providers.Stripe - BadgeService.Service - BadgeService.Store - BadgeService.Store.Invoices - BadgeService.Store.Migrate - BadgeService.Waiters - BadgeService.Web.Server - Bots.BadgeService.BTCPayTests - Bots.BadgeService.BotTests - Bots.BadgeService.CatalogTests - Bots.BadgeService.ConfigTests - Bots.BadgeService.FakeBTCPay - Bots.BadgeService.FakeEthNode - Bots.BadgeService.FakeStripe - Bots.BadgeService.GroupIntegrationTests - Bots.BadgeService.GroupTests - Bots.BadgeService.NameRegistrationTests - Bots.BadgeService.StripeTests - Bots.BadgeService.WaitersTests - Bots.BadgeService.WebTests - Bots.BadgeService.WebUIMock + Bots.StoreService.BTCPayTests + Bots.StoreService.BotTests + Bots.StoreService.CatalogTests + Bots.StoreService.ConfigTests + Bots.StoreService.FakeBTCPay + Bots.StoreService.FakeEthNode + Bots.StoreService.FakeStripe + Bots.StoreService.GroupIntegrationTests + Bots.StoreService.GroupTests + Bots.StoreService.NameRegistrationTests + Bots.StoreService.StripeTests + Bots.StoreService.WaitersTests + Bots.StoreService.WebTests + Bots.StoreService.WebUIMock Broadcast.Bot Broadcast.Options Directory.BlockedWords @@ -773,6 +753,26 @@ test-suite simplex-chat-test Directory.Service Directory.Store Directory.Store.Migrate + StoreService.Catalog + StoreService.Codes + StoreService.Config + StoreService.Group + StoreService.Group.Command + StoreService.Log + StoreService.Names.Chain + StoreService.Names.Registration + StoreService.Options + StoreService.Orders + StoreService.Poller + StoreService.Providers + StoreService.Providers.BTCPay + StoreService.Providers.Stripe + StoreService.Service + StoreService.Store + StoreService.Store.Invoices + StoreService.Store.Migrate + StoreService.Waiters + StoreService.Web.Server Paths_simplex_chat if flag(client_postgres) other-modules: @@ -787,7 +787,7 @@ test-suite simplex-chat-test hs-source-dirs: bots/src tests - apps/simplex-badge-service/src + apps/simplex-store-service/src apps/simplex-broadcast-bot/src apps/simplex-directory-service/src default-extensions: @@ -834,7 +834,7 @@ test-suite simplex-chat-test default-language: Haskell2010 if flag(client_postgres) other-modules: - BadgeService.Store.Postgres.Migrations + StoreService.Store.Postgres.Migrations Directory.Store.Postgres.Migrations build-depends: postgresql-simple ==0.7.* @@ -842,7 +842,7 @@ test-suite simplex-chat-test cpp-options: -DdbPostgres else other-modules: - BadgeService.Store.SQLite.Migrations + StoreService.Store.SQLite.Migrations Directory.Store.SQLite.Migrations build-depends: sqlcipher-simple ==0.4.* diff --git a/tests/BadgeTests.hs b/tests/BadgeTests.hs index d6ba48bac2..19ac4dbe9f 100644 --- a/tests/BadgeTests.hs +++ b/tests/BadgeTests.hs @@ -9,7 +9,7 @@ module BadgeTests (badgeTests) where -import BadgeService.Service (badgeErrorRetryAfter) +import StoreService.Service (badgeErrorRetryAfter) import Control.Concurrent.STM (atomically) import Control.Monad (forM_) import Data.ByteArray.Encoding (Base (Base16), convertToBase) diff --git a/tests/Bots/BadgeService/BTCPayTests.hs b/tests/Bots/StoreService/BTCPayTests.hs similarity index 99% rename from tests/Bots/BadgeService/BTCPayTests.hs rename to tests/Bots/StoreService/BTCPayTests.hs index b2f93250cc..edd164c046 100644 --- a/tests/Bots/BadgeService/BTCPayTests.hs +++ b/tests/Bots/StoreService/BTCPayTests.hs @@ -3,10 +3,10 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module Bots.BadgeService.BTCPayTests (badgeBTCPayTests) where +module Bots.StoreService.BTCPayTests (badgeBTCPayTests) where -import BadgeService.Config (BTCPayConfig (..)) -import BadgeService.Providers +import StoreService.Config (BTCPayConfig (..)) +import StoreService.Providers ( Funded (..), ListPass (..), OrderDraft (..), @@ -18,8 +18,8 @@ import BadgeService.Providers WebhookError (..), settleWindow, ) -import BadgeService.Providers.BTCPay (btcMethodId, btcpayProvider, listSignals, minorToDecimal, paymentMethodsSignal, verifyBTCPaySig, xmrMethodId) -import Bots.BadgeService.FakeBTCPay +import StoreService.Providers.BTCPay (btcMethodId, btcpayProvider, listSignals, minorToDecimal, paymentMethodsSignal, verifyBTCPaySig, xmrMethodId) +import Bots.StoreService.FakeBTCPay import Control.Exception (evaluate) import Control.Monad (join) import Data.Aeson ((.=)) diff --git a/tests/Bots/BadgeService/BotTests.hs b/tests/Bots/StoreService/BotTests.hs similarity index 93% rename from tests/Bots/BadgeService/BotTests.hs rename to tests/Bots/StoreService/BotTests.hs index 4b0c4fc33a..590aebeb33 100644 --- a/tests/Bots/BadgeService/BotTests.hs +++ b/tests/Bots/StoreService/BotTests.hs @@ -8,16 +8,16 @@ {-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -fno-warn-ambiguous-fields #-} -module Bots.BadgeService.BotTests where +module Bots.StoreService.BotTests where -import BadgeService.Codes (issueOneCode) -import BadgeService.Config (BadgeIssuerKey (..), readServiceConfig) -import BadgeService.Group (GroupEvent) -import Bots.BadgeService.ConfigTests (withIssuer) -import BadgeService.Options -import BadgeService.Service -import BadgeService.Store (IssuedCode (..), getBadgeCode) -import BadgeService.Store.Invoices (markCodePaid) +import StoreService.Codes (issueOneCode) +import StoreService.Config (BadgeIssuerKey (..), readServiceConfig) +import StoreService.Group (GroupEvent) +import Bots.StoreService.ConfigTests (withIssuer) +import StoreService.Options +import StoreService.Service +import StoreService.Store (IssuedCode (..), getBadgeCode) +import StoreService.Store.Invoices (markCodePaid) import Simplex.Messaging.Agent.Store.DB (Binary (..)) import qualified Simplex.Messaging.Agent.Store.DB as DB import ChatClient @@ -71,9 +71,9 @@ import Database.SQLite.Simple (Only (..)) #endif import Test.Hspec hiding (it) -badgeServiceTests :: SpecWith TestParams -badgeServiceTests = do - it "should answer unsupported_version to unsupported command" testBadgeServiceUnsupported +storeServiceTests :: SpecWith TestParams +storeServiceTests = do + it "should answer unsupported_version to unsupported command" testStoreServiceUnsupported it "should redeem an issued code into a badge a contact sees" testRedeemBadgeCode it "should return the same badge when the same code is redeemed twice" testRedeemBadgeCodeTwice it "should answer code_invalid to an unknown code, indistinguishably from a malformed one" testRedeemUnknownCode @@ -132,9 +132,9 @@ serviceDbPrefix = "badge_service" testIssuerKeyIdx :: Int testIssuerKeyIdx = 1 -mkBadgeServiceOpts :: TestParams -> BBSSecretKey -> BadgeServiceOpts -mkBadgeServiceOpts ps secretKey = - BadgeServiceOpts +mkStoreServiceOpts :: TestParams -> BBSSecretKey -> StoreServiceOpts +mkStoreServiceOpts ps secretKey = + StoreServiceOpts { coreOptions = coreOpts { dbOptions = @@ -170,7 +170,7 @@ testClockTime (TestClock r) = do setClockAt :: TestClock -> UTCTime -> IO () setClockAt (TestClock r) t = getCurrentTime >>= \real -> writeIORef r (diffUTCTime t real) -data BadgeServiceEnv = BadgeServiceEnv +data StoreServiceEnv = StoreServiceEnv { bsIssuerKey :: BadgeIssuerKey, bsClock :: TestClock, bsClientCfg :: ChatConfig, @@ -180,22 +180,22 @@ data BadgeServiceEnv = BadgeServiceEnv -- | Stop the service for good: requests sent after it go unanswered until they time out. Stopping -- chat unsubscribes its queues, where killing the thread could still let a request arrive mid-teardown. -stopBadgeService :: ChatController -> IO () -stopBadgeService cc = void $ sendChatCmdStr cc "/_stop" +stopStoreService :: ChatController -> IO () +stopStoreService cc = void $ sendChatCmdStr cc "/_stop" -withBadgeService :: HasCallStack => TestParams -> (ChatConfig -> String -> ChatController -> IO ()) -> IO () -withBadgeService ps test = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClientCfg, bsAddress, bsController} -> test bsClientCfg bsAddress bsController +withStoreService :: HasCallStack => TestParams -> (ChatConfig -> String -> ChatController -> IO ()) -> IO () +withStoreService ps test = + withStoreServiceEnv ps $ \StoreServiceEnv {bsClientCfg, bsAddress, bsController} -> test bsClientCfg bsAddress bsController -withBadgeServiceEnv :: HasCallStack => TestParams -> (BadgeServiceEnv -> IO ()) -> IO () -withBadgeServiceEnv ps test = do +withStoreServiceEnv :: HasCallStack => TestParams -> (StoreServiceEnv -> IO ()) -> IO () +withStoreServiceEnv ps test = do Right (pk, sk) <- bbsKeyGen clock <- newTestClock - let opts = mkBadgeServiceOpts ps sk + let opts = mkStoreServiceOpts ps sk svcCfg = testCfg {badgePublicKeys = M.singleton testIssuerKeyIdx pk, badgeCurrentTime = testClockTime clock} withNewTestChatCfg ps testCfg serviceDbPrefix badgeProfile $ \_ -> pure () - -- First start: badge service takes the CreateMyAddress branch. - runBadgeService ps svcCfg opts $ \_ -> pure () + -- First start: store service takes the CreateMyAddress branch. + runStoreService ps svcCfg opts $ \_ -> pure () -- Reopen the DB to read the link the service created. bsLink <- withTestChat ps serviceDbPrefix $ \bs -> do bs <## "subscribed 1 connections on server localhost" @@ -206,11 +206,11 @@ withBadgeServiceEnv ps test = do bs <## "auto_accept off" pure sLink let clientCfg = - svcCfg {storeServiceAddress = Just $ either (error . ("bad badge service address: " <>)) id $ strDecode (B.pack bsLink)} - -- Second start: badge service takes the ShowMyAddress branch, then serves the test body. - runBadgeService ps svcCfg opts $ \env -> do + svcCfg {storeServiceAddress = Just $ either (error . ("bad store service address: " <>)) id $ strDecode (B.pack bsLink)} + -- Second start: store service takes the ShowMyAddress branch, then serves the test body. + runStoreService ps svcCfg opts $ \env -> do cc <- atomically $ readTMVar $ serviceCC env - test BadgeServiceEnv {bsIssuerKey = BadgeIssuerKey {keyIdx = testIssuerKeyIdx, secretKey = sk}, bsClock = clock, bsClientCfg = clientCfg, bsAddress = bsLink, bsController = cc} + test StoreServiceEnv {bsIssuerKey = BadgeIssuerKey {keyIdx = testIssuerKeyIdx, secretKey = sk}, bsClock = clock, bsClientCfg = clientCfg, bsAddress = bsLink, bsController = cc} issueCode :: HasCallStack => ChatController -> BadgeType -> Int -> IO BadgeCode issueCode cc badgeType months = issueCodeAs cc badgeType months "free" @@ -237,20 +237,20 @@ issueCodeAs cc badgeType months status = -- | The post-start hook fills serviceCC once the address exists, so waiting on it is the service -- being ready. A fixed delay here raced with startup and left the address output of one start -- arriving during the next test. -runBadgeService :: TestParams -> ChatConfig -> BadgeServiceOpts -> (ServiceState -> IO ()) -> IO () -runBadgeService ps cfg opts action = do +runStoreService :: TestParams -> ChatConfig -> StoreServiceOpts -> (ServiceState -> IO ()) -> IO () +runStoreService ps cfg opts action = do env <- newServiceState - t <- async $ badgeService opts (fst $ testPortsCfg ps cfg testOpts) env + t <- async $ storeService opts (fst $ testPortsCfg ps cfg testOpts) env ready <- timeout 30000000 $ atomically $ readTMVar $ serviceCC env - when (isNothing ready) $ cancel t >> error "badge service did not start" + when (isNothing ready) $ cancel t >> error "store service did not start" action env `finally` (cancel t >> atomically (readTMVar $ serviceCC env) >>= disposeAgentClient . smpAgent) codeArg :: BadgeCode -> String codeArg = T.unpack . formatBadgeCode -testBadgeServiceUnsupported :: HasCallStack => TestParams -> IO () -testBadgeServiceUnsupported ps = - withBadgeService ps $ \clientCfg bsLink _ -> +testStoreServiceUnsupported :: HasCallStack => TestParams -> IO () +testStoreServiceUnsupported ps = + withStoreService ps $ \clientCfg bsLink _ -> withNewTestChatCfg ps clientCfg "client" bobProfile $ \client -> do let req = "{\"version\":1,\"request\":{\"type\":\"pauseBadge\"}}" client ##> ("/_service_request 1 " <> bsLink <> " " <> req) @@ -258,7 +258,7 @@ testBadgeServiceUnsupported ps = testRedeemBadgeCode :: HasCallStack => TestParams -> IO () testRedeemBadgeCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> withNewTestChatCfg ps clientCfg "bob" bobProfile $ \bob -> do connectUsers alice bob @@ -285,7 +285,7 @@ testRedeemBadgeCode ps = testRedeemBadgeCodeTwice :: HasCallStack => TestParams -> IO () testRedeemBadgeCodeTwice ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 1 alice ##> ("/_redeem_badge_code 1 " <> codeArg code) @@ -300,7 +300,7 @@ testRedeemBadgeCodeTwice ps = testRedeemUnknownCode :: HasCallStack => TestParams -> IO () testRedeemUnknownCode ps = - withBadgeService ps $ \clientCfg bsLink _ -> + withStoreService ps $ \clientCfg bsLink _ -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do g <- C.newRandom unknown <- randomBadgeCode g @@ -332,7 +332,7 @@ testMasterKeyB64 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" testIssueRejectsBadArguments :: HasCallStack => TestParams -> IO () testIssueRejectsBadArguments ps = - withBadgeService ps $ \_ _ cc -> do + withStoreService ps $ \_ _ cc -> do let refuses arg = issueRaw cc arg >>= (`shouldSatisfy` isLeft) refuses "suporter" refuses "supporter 0" @@ -352,7 +352,7 @@ issueRaw cc args = testRedeemSecondCode :: HasCallStack => TestParams -> IO () testRedeemSecondCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do supporter <- issueCode cc BTSupporter 1 legend <- issueCode cc BTLegend 1 @@ -373,7 +373,7 @@ testRedeemSecondCode ps = testRedeemSameCodeOtherProfile :: HasCallStack => TestParams -> IO () testRedeemSameCodeOtherProfile ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 1 alice ##> ("/_redeem_badge_code 1 " <> codeArg code) @@ -389,17 +389,17 @@ testRedeemSameCodeOtherProfile ps = alice ##> "/user alice" showActiveUser alice "alice (Alice, * supporter)" -serviceCmd :: HasCallStack => BadgeServiceEnv -> C.PublicKeyEd25519 -> StoreServiceCommand -> IO StoreServiceResponse -serviceCmd BadgeServiceEnv {bsIssuerKey, bsController} = serviceCmdWith bsIssuerKey bsController Nothing +serviceCmd :: HasCallStack => StoreServiceEnv -> C.PublicKeyEd25519 -> StoreServiceCommand -> IO StoreServiceResponse +serviceCmd StoreServiceEnv {bsIssuerKey, bsController} = serviceCmdWith bsIssuerKey bsController Nothing serviceCmdWith :: HasCallStack => BadgeIssuerKey -> ChatController -> Maybe (TQueue GroupEvent) -> C.PublicKeyEd25519 -> StoreServiceCommand -> IO StoreServiceResponse serviceCmdWith key cc trackerQ_ purchaseKey request = - badgeServiceResponse key cc trackerQ_ (Just purchaseKey) (requestObject purchaseKey request) + storeServiceResponse key cc trackerQ_ (Just purchaseKey) (requestObject purchaseKey request) requestObject :: HasCallStack => C.PublicKeyEd25519 -> StoreServiceCommand -> J.Object requestObject purchaseKey request = case J.toJSON StoreServiceRequest {version = currentStoreServiceVersion, purchaseKey = Just purchaseKey, request} of J.Object o -> o - _ -> error "badge service request must encode as an object" + _ -> error "store service request must encode as an object" entryOf :: StatementEntry -> (Int, Int, UTCTime) entryOf StatementEntry {changeMonths, balanceMonths, balanceStartTs} = (changeMonths, balanceMonths, balanceStartTs) @@ -442,10 +442,10 @@ newPurchaseKeys = do (purchaseKey, _) <- atomically $ C.generateKeyPair g :: IO (C.KeyPair 'C.Ed25519) (purchaseKey,) <$> generateMasterKey g -redeemAsNewPurchase :: HasCallStack => BadgeServiceEnv -> BadgeCode -> IO StoreServiceResponse -redeemAsNewPurchase BadgeServiceEnv {bsIssuerKey, bsController} = redeemWithQueue bsIssuerKey bsController Nothing . badgeCodeText +redeemAsNewPurchase :: HasCallStack => StoreServiceEnv -> BadgeCode -> IO StoreServiceResponse +redeemAsNewPurchase StoreServiceEnv {bsIssuerKey, bsController} = redeemWithQueue bsIssuerKey bsController Nothing . badgeCodeText -redeemWithKeys :: HasCallStack => BadgeServiceEnv -> (C.PublicKeyEd25519, BadgeMasterKey) -> BadgeCode -> IO StoreServiceResponse +redeemWithKeys :: HasCallStack => StoreServiceEnv -> (C.PublicKeyEd25519, BadgeMasterKey) -> BadgeCode -> IO StoreServiceResponse redeemWithKeys env (purchaseKey, masterKey) code = serviceCmd env purchaseKey STCRedeemBadgeCode {masterKey, code = badgeCodeText code} redeemWithQueue :: HasCallStack => BadgeIssuerKey -> ChatController -> Maybe (TQueue GroupEvent) -> Text -> IO StoreServiceResponse @@ -453,7 +453,7 @@ redeemWithQueue key cc trackerQ_ codeText = do (purchaseKey, masterKey) <- newPurchaseKeys serviceCmdWith key cc trackerQ_ purchaseKey STCRedeemBadgeCode {masterKey, code = codeText} -assertBalance :: HasCallStack => BadgeServiceEnv -> C.PublicKeyEd25519 -> StatementEntry -> IO StoreServiceResponse +assertBalance :: HasCallStack => StoreServiceEnv -> C.PublicKeyEd25519 -> StatementEntry -> IO StoreServiceResponse assertBalance env purchaseKey lastEntry = serviceCmd env purchaseKey STCIssueBadge {balance = BadgeBalance {lastEntry}} @@ -468,7 +468,7 @@ masterKeyOf r = (\(BadgeCredential _ mk _ _) -> mk) <$> credentialOf r testCodeMonthsRenew :: HasCallStack => TestParams -> IO () testCodeMonthsRenew ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsController = cc} -> do code <- issueCode cc BTSupporter 3 keys@(purchaseKey, _) <- newPurchaseKeys redeemed <- redeemWithKeys env keys code @@ -493,7 +493,7 @@ testCodeMonthsRenew ps = testRepeatInsideIssuedPeriod :: HasCallStack => TestParams -> IO () testRepeatInsideIssuedPeriod ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsController = cc} -> do code <- issueCode cc BTSupporter 2 keys@(purchaseKey, _) <- newPurchaseKeys redeemed <- redeemWithKeys env keys code @@ -504,7 +504,7 @@ testRepeatInsideIssuedPeriod ps = testMultiUseRepeatAfterExpiry :: HasCallStack => TestParams -> IO () testMultiUseRepeatAfterExpiry ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueMultiUseCode cc BTSupporter 1 2 redeemFirstBadge alice code @@ -529,7 +529,7 @@ testMultiUseRepeatAfterExpiry ps = testMultiUseWithoutGroup :: HasCallStack => TestParams -> IO () testMultiUseWithoutGroup ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsController = cc} -> do code <- issueMultiUseCode cc BTLegend 2 2 forM_ [1 :: Int, 2] $ \claimed -> do keys@(_, masterKey) <- newPurchaseKeys @@ -544,7 +544,7 @@ testMultiUseWithoutGroup ps = testUnreadableCredentialIsInternal :: HasCallStack => TestParams -> IO () testUnreadableCredentialIsInternal ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsController = cc} -> do code <- issueMultiUseCode cc BTSupporter 1 2 let redeem keys = redeemWithKeys env keys code holder <- newPurchaseKeys @@ -567,7 +567,7 @@ issueMultiUseCode cc badgeType months uses = testLapseWhileAway :: HasCallStack => TestParams -> IO () testLapseWhileAway ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsController = cc} -> do code <- issueCode cc BTSupporter 6 keys@(purchaseKey, _) <- newPurchaseKeys redeemed <- redeemWithKeys env keys code @@ -582,7 +582,7 @@ testLapseWhileAway ps = testLastMonthExpiryRounds :: HasCallStack => TestParams -> IO () testLastMonthExpiryRounds ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsController = cc} -> do code <- issueCode cc BTSupporter 2 keys@(purchaseKey, _) <- newPurchaseKeys redeemed <- redeemWithKeys env keys code @@ -596,7 +596,7 @@ testLastMonthExpiryRounds ps = testRenewalSignsWithStoredMasterKey :: HasCallStack => TestParams -> IO () testRenewalSignsWithStoredMasterKey ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsController = cc} -> do code <- issueCode cc BTSupporter 2 keys@(purchaseKey, masterKey) <- newPurchaseKeys redeemed <- redeemWithKeys env keys code @@ -650,7 +650,7 @@ balanceChecks ChatController {chatStore} = testClientReplicatesLedger :: HasCallStack => TestParams -> IO () testClientReplicatesLedger ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 alice ##> ("/_redeem_badge_code 1 " <> codeArg code) @@ -816,7 +816,7 @@ waitWakeArmed ChatController {chatStore} = loop (100 :: Int) testWorkerRenews :: HasCallStack => TestParams -> IO () testWorkerRenews ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -852,7 +852,7 @@ testWorkerRenews ps = testRevokedMultiUseHolderRenews :: HasCallStack => TestParams -> IO () testRevokedMultiUseHolderRenews ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueMultiUseCode cc BTSupporter 3 2 redeemFirstBadge alice code @@ -879,7 +879,7 @@ testRevokedMultiUseHolderRenews ps = testMultiUseHoldersRenewApart :: HasCallStack => TestParams -> IO () testMultiUseHoldersRenewApart ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueMultiUseCode cc BTSupporter 3 2 redeemFirstBadge alice code @@ -924,7 +924,7 @@ codeRedemptionKey ChatController {chatStore} = do testRequestWakeFires :: HasCallStack => TestParams -> IO () testRequestWakeFires ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -938,7 +938,7 @@ testRequestWakeFires ps = testPresentWakeFires :: HasCallStack => TestParams -> IO () testPresentWakeFires ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -955,7 +955,7 @@ testPresentWakeFires ps = testRenewsAfterUnknownEntry :: HasCallStack => TestParams -> IO () testRenewsAfterUnknownEntry ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -973,7 +973,7 @@ testRenewsAfterUnknownEntry ps = testRenewsAfterRestart :: HasCallStack => TestParams -> IO () testRenewsAfterRestart ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do rows <- withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 6 redeemFirstBadge alice code @@ -993,7 +993,7 @@ testRenewsAfterRestart ps = testWorkerRetiresExpired :: HasCallStack => TestParams -> IO () testWorkerRetiresExpired ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> withNewTestChatCfg ps bsClientCfg "bob" bobProfile $ \bob -> do connectUsers alice bob @@ -1039,7 +1039,7 @@ testWorkerRetiresExpired ps = testRetiresWhenEntitlementEnds :: HasCallStack => TestParams -> IO () testRetiresWhenEntitlementEnds ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 1 redeemFirstBadge alice code @@ -1055,7 +1055,7 @@ testRetiresWhenEntitlementEnds ps = testEndedAlert :: HasCallStack => TestParams -> IO () testEndedAlert ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do endsAt <- withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 1 redeemFirstBadge alice code @@ -1088,7 +1088,7 @@ testEndedAlert ps = -- worn and will start showing as expired. testIssueFailedAlert :: HasCallStack => TestParams -> IO () testIssueFailedAlert ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -1098,7 +1098,7 @@ testIssueFailedAlert ps = setClockAt bsClock $ fst $ renewalMoments rows alice ##> "/_app activate" alice <## "ok" - alice <## badgeServiceRefused + alice <## storeServiceRefused alice <##. "badge alert: issue_failed " -- the state reports the failure, when the next attempt is due, and the alert it raised alice <##. "1: supporter" @@ -1112,13 +1112,13 @@ testIssueFailedAlert ps = -- they stop. It is recorded from the first attempt, so the run's start is not lost. testIssueFailedWaitsForExpiry :: HasCallStack => TestParams -> IO () testIssueFailedWaitsForExpiry ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> do -- the redemption runs against the service, so it keeps the ordinary request timeout (requestAt, presentAt) <- withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code renewalMoments <$> ledgerRows (chatController alice) "badge_ledger" - stopBadgeService cc + stopStoreService cc let cfg = failingServiceCfg bsClientCfg -- the request goes unanswered and times out, which is a failure that can clear on its own setClockAt bsClock requestAt @@ -1144,7 +1144,7 @@ testIssueFailedWaitsForExpiry ps = -- screen while the alert goes quiet, and a later run raises it again under a new episode. testIssueFailedAckAndNewRun :: HasCallStack => TestParams -> IO () testIssueFailedAckAndNewRun ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -1155,7 +1155,7 @@ testIssueFailedAckAndNewRun ps = setClockAt bsClock requestAt alice ##> "/_app activate" alice <## "ok" - alice <## badgeServiceRefused + alice <## storeServiceRefused alice <##. "badge alert: issue_failed " alice <##. "1: supporter" alice <##. "renewal failing since " @@ -1166,7 +1166,7 @@ testIssueFailedAckAndNewRun ps = alice <##. "1: supporter" alice <##. "renewal failing since " -- the ack signalled the worker, and the pass it ran failed again and raised nothing - alice <## badgeServiceRefused + alice <## storeServiceRefused alice <##. "1: supporter" alice <##. "renewal failing since " ackedEpisode (chatController alice) `shouldReturn` (Just "issue_failed", Just episode) @@ -1187,7 +1187,7 @@ testIssueFailedAckAndNewRun ps = setClockAt bsClock $ fst $ renewalMoments renewed alice ##> "/_app activate" alice <## "ok" - alice <## badgeServiceRefused + alice <## storeServiceRefused alice <##. "badge alert: issue_failed " alice <##. "1: supporter" alice <##. "renewal failing since " @@ -1202,7 +1202,7 @@ testIssueFailedAckAndNewRun ps = -- credential that was never issued. testNoCredentialMonthsRanOut :: HasCallStack => TestParams -> IO () testNoCredentialMonthsRanOut ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -1225,7 +1225,7 @@ testNoCredentialMonthsRanOut ps = -- resolve, so it is recorded and told at once. testNoCredentialMonthsLeft :: HasCallStack => TestParams -> IO () testNoCredentialMonthsLeft ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -1261,8 +1261,8 @@ zeroServiceLedgerTip ChatController {chatStore} = withTransaction chatStore $ \db -> DB.execute_ db "UPDATE sx_badge_service_badge_ledger SET balance_months = 0 WHERE entry_id = (SELECT MAX(entry_id) FROM sx_badge_service_badge_ledger)" -badgeServiceRefused :: String -badgeServiceRefused = "bad chat command: store service error: unknown_purchase_key" +storeServiceRefused :: String +storeServiceRefused = "bad chat command: store service error: unknown_purchase_key" -- | The alert's episode is the start of the run of failures, as the ack command spells it. episodeOf :: HasCallStack => Maybe UTCTime -> Text @@ -1314,7 +1314,7 @@ waitIssueErrorCleared cc = loop (100 :: Int) testRenewalKeepsActiveProfile :: HasCallStack => TestParams -> IO () testRenewalKeepsActiveProfile ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 3 redeemFirstBadge alice code @@ -1338,7 +1338,7 @@ testRenewalKeepsActiveProfile ps = testSnoozedAlertReturns :: HasCallStack => TestParams -> IO () testSnoozedAlertReturns ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> do code <- issueCode cc BTSupporter 1 redeemFirstBadge alice code @@ -1364,7 +1364,7 @@ testSnoozedAlertReturns ps = testRenewalKeepsProfileEdits :: HasCallStack => TestParams -> IO () testRenewalKeepsProfileEdits ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> withNewTestChatCfg ps bsClientCfg "bob" bobProfile $ \bob -> do connectUsers alice bob @@ -1404,7 +1404,7 @@ testRenewalKeepsProfileEdits ps = testPresentationCatchesUp :: HasCallStack => TestParams -> IO () testPresentationCatchesUp ps = - withBadgeServiceEnv ps $ \BadgeServiceEnv {bsClock, bsClientCfg, bsController = cc} -> + withStoreServiceEnv ps $ \StoreServiceEnv {bsClock, bsClientCfg, bsController = cc} -> withNewTestChatCfg ps bsClientCfg "alice" aliceProfile $ \alice -> withNewTestChatCfg ps bsClientCfg "bob" bobProfile $ \bob -> do connectUsers alice bob @@ -1450,7 +1450,7 @@ waitPeerBadgeExpiry cc expected = loop (100 :: Int) testPurchaseKeyMismatch :: HasCallStack => TestParams -> IO () testPurchaseKeyMismatch ps = - withBadgeService ps $ \clientCfg bsLink _ -> + withStoreService ps $ \clientCfg bsLink _ -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do g <- C.newRandom (_, signPriv) <- atomically $ C.generateKeyPair g :: IO (C.KeyPair 'C.Ed25519) @@ -1465,7 +1465,7 @@ testIssuerKeyMustMatchConfig :: HasCallStack => TestParams -> IO () testIssuerKeyMustMatchConfig ps = do Right (pk, sk) <- bbsKeyGen Right (_, otherSk) <- bbsKeyGen - let optsFor sk' = mkBadgeServiceOpts ps sk' + let optsFor sk' = mkStoreServiceOpts ps sk' cfg = testCfg {badgePublicKeys = M.singleton testIssuerKeyIdx pk} checkIssuerKey (optsFor sk) Nothing cfg >>= (`shouldSatisfy` isRight) checkIssuerKey (optsFor otherSk) Nothing cfg >>= (`shouldSatisfy` isLeft) @@ -1478,7 +1478,7 @@ testIssuerIniKeyMustBeTrusted ps = do Right (pk, sk) <- bbsKeyGen Right (_, untrusted) <- bbsKeyGen let cfg = testCfg {badgePublicKeys = M.singleton testIssuerKeyIdx pk} - fromCli = mkBadgeServiceOpts ps sk + fromCli = mkStoreServiceOpts ps sk fromIni = fromCli {issuerKey = Right Nothing} iniWith idx k = withIssuer ["index = " <> tshow idx, "private_key = " <> safeDecodeUtf8 (strEncode k)] readServiceConfig Right trusted <- iniWith testIssuerKeyIdx sk @@ -1494,7 +1494,7 @@ testIssuerIniKeyMustBeTrusted ps = do testRedeemUnpaidCode :: HasCallStack => TestParams -> IO () testRedeemUnpaidCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do unpaid <- issueCodeAs cc BTSupporter 1 "unpaid" alice ##> ("/_redeem_badge_code 1 " <> codeArg unpaid) @@ -1508,7 +1508,7 @@ testRedeemUnpaidCode ps = -- | A redemption deadline is a year out and cannot be waited for, so the code is issued unpaid and then marked paid with a deadline already in the past. testExpiredCode :: HasCallStack => TestParams -> IO () testExpiredCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do code <- issueCodeAs cc BTSupporter 1 "unpaid" now <- getCurrentTime @@ -1519,7 +1519,7 @@ testExpiredCode ps = testRedeemedBeforeTheDeadline :: HasCallStack => TestParams -> IO () testRedeemedBeforeTheDeadline ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do code <- issueCodeAs cc BTSupporter 1 "unpaid" now <- getCurrentTime @@ -1542,7 +1542,7 @@ testRedeemedBeforeTheDeadline ps = testRevokeRedeemedCode :: HasCallStack => TestParams -> IO () testRevokeRedeemedCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do code <- issueCodeAs cc BTSupporter 1 "paid" alice ##> ("/_redeem_badge_code 1 " <> codeArg code) @@ -1556,7 +1556,7 @@ testRevokeRedeemedCode ps = testRevokeUnknownCode :: HasCallStack => TestParams -> IO () testRevokeUnknownCode ps = - withBadgeService ps $ \_ _ cc -> do + withStoreService ps $ \_ _ cc -> do g <- C.newRandom code <- randomBadgeCode g unknown <- revokeCodeAs cc code @@ -1564,7 +1564,7 @@ testRevokeUnknownCode ps = testRevokedCode :: HasCallStack => TestParams -> IO () testRevokedCode ps = - withBadgeService ps $ \clientCfg _ cc -> + withStoreService ps $ \clientCfg _ cc -> withNewTestChatCfg ps clientCfg "alice" aliceProfile $ \alice -> do paid <- issueCodeAs cc BTSupporter 1 "paid" revokeCodeAs cc paid `shouldReturn` Right "Revoked." @@ -1574,14 +1574,14 @@ testRevokedCode ps = testRevokedUnpaidCode :: HasCallStack => TestParams -> IO () testRevokedUnpaidCode ps = - withBadgeServiceEnv ps $ \env@BadgeServiceEnv {bsController = cc} -> do + withStoreServiceEnv ps $ \env@StoreServiceEnv {bsController = cc} -> do code <- issueCodeAs cc BTSupporter 1 "unpaid" revokeCodeAs cc code `shouldReturn` Right "Revoked." redeemAsNewPurchase env code >>= (`shouldAnswerError` STECodeInvalid) testRevokeRejectsTrailingInput :: HasCallStack => TestParams -> IO () testRevokeRejectsTrailingInput ps = - withBadgeService ps $ \_ _ cc -> do + withStoreService ps $ \_ _ cc -> do code <- issueCodeAs cc BTSupporter 1 "paid" refused <- revokeRaw cc (formatBadgeCode code <> " junk") -- If the refused call revoked the code anyway, this fails with "Already revoked.". diff --git a/tests/Bots/BadgeService/CatalogTests.hs b/tests/Bots/StoreService/CatalogTests.hs similarity index 99% rename from tests/Bots/BadgeService/CatalogTests.hs rename to tests/Bots/StoreService/CatalogTests.hs index 080d366f21..ae853213fe 100644 --- a/tests/Bots/BadgeService/CatalogTests.hs +++ b/tests/Bots/StoreService/CatalogTests.hs @@ -2,9 +2,9 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.CatalogTests where +module Bots.StoreService.CatalogTests where -import BadgeService.Catalog +import StoreService.Catalog import Control.Monad (when) import Data.List (find) import qualified Data.Map.Strict as Map @@ -202,7 +202,7 @@ testPriceOfferAnyPrice = do testNoDriftFromWeb :: IO () testNoDriftFromWeb = do - src <- T.readFile "apps/simplex-badge-service/web/src/catalog.ts" + src <- T.readFile "apps/simplex-store-service/web/src/catalog.ts" case parseCatalogSource src of Nothing -> expectationFailure "could not parse CATALOG out of web/src/catalog.ts -- its shape has changed" Just (webPrices, webOffers) -> do diff --git a/tests/Bots/BadgeService/ConfigTests.hs b/tests/Bots/StoreService/ConfigTests.hs similarity index 98% rename from tests/Bots/BadgeService/ConfigTests.hs rename to tests/Bots/StoreService/ConfigTests.hs index 7d5c5c9a7f..06fbb7cffa 100644 --- a/tests/Bots/BadgeService/ConfigTests.hs +++ b/tests/Bots/StoreService/ConfigTests.hs @@ -1,9 +1,9 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.ConfigTests where +module Bots.StoreService.ConfigTests where -import BadgeService.Config +import StoreService.Config import qualified Data.ByteString.Char8 as B import Data.Either (isLeft) import Data.Ini (readIniFile) @@ -16,7 +16,7 @@ import Test.Hspec import UnliftIO.Temporary (withTempDirectory) badgeConfigTests :: Spec -badgeConfigTests = describe "badge service config" $ do +badgeConfigTests = describe "store service config" $ do it "applies every documented default" testDefaults it "falls back to the default host when the value is blank" testBlankHost it "disables a provider whose section is absent" testAbsentSection @@ -69,7 +69,7 @@ withIni :: T.Text -> (FilePath -> IO a) -> IO a withIni t f = do createDirectoryIfMissing True "tests/tmp" withTempDirectory "tests/tmp" "badge-ini" $ \d -> do - let p = d "badge_service.ini" + let p = d "store_service.ini" T.writeFile p t f p @@ -273,10 +273,10 @@ testTrailingCommentIsAccepted = do -- would put it in the line twice. testMissingFileIsReported :: IO () testMissingFileIsReported = - readServiceConfig "tests/tmp/no-such-badge_service.ini" >>= \r -> case r of + readServiceConfig "tests/tmp/no-such-store_service.ini" >>= \r -> case r of Left e -> do e `shouldContain` "does not exist" - e `shouldNotContain` "no-such-badge_service.ini" + e `shouldNotContain` "no-such-store_service.ini" Right _ -> expectationFailure "a file that is not there cannot be read" testPaymentTolerance :: IO () diff --git a/tests/Bots/BadgeService/FakeBTCPay.hs b/tests/Bots/StoreService/FakeBTCPay.hs similarity index 99% rename from tests/Bots/BadgeService/FakeBTCPay.hs rename to tests/Bots/StoreService/FakeBTCPay.hs index a35b7bd8c8..b9bf45d954 100644 --- a/tests/Bots/BadgeService/FakeBTCPay.hs +++ b/tests/Bots/StoreService/FakeBTCPay.hs @@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module Bots.BadgeService.FakeBTCPay +module Bots.StoreService.FakeBTCPay ( FakeBTCPay (..), FakeRequest (..), withFakeBTCPay, @@ -26,7 +26,7 @@ module Bots.BadgeService.FakeBTCPay ) where -import BadgeService.Config (BTCPayConfig (..), SpeedPolicy (..)) +import StoreService.Config (BTCPayConfig (..), SpeedPolicy (..)) import Control.Applicative ((<|>)) import Control.Concurrent.STM import Control.Monad (join) @@ -75,7 +75,7 @@ import System.FilePath (()) import Text.Read (readMaybe) fixtureDir :: FilePath -fixtureDir = "apps" "simplex-badge-service" "test-fixtures" "btcpay" +fixtureDir = "apps" "simplex-store-service" "test-fixtures" "btcpay" fakeApiKey :: Text fakeApiKey = "7f3c1d9a2e5b48c6905ad1e2f3b4c5d6e7f80912" diff --git a/tests/Bots/BadgeService/FakeEthNode.hs b/tests/Bots/StoreService/FakeEthNode.hs similarity index 98% rename from tests/Bots/BadgeService/FakeEthNode.hs rename to tests/Bots/StoreService/FakeEthNode.hs index 6d9f9350a2..bec267bd31 100644 --- a/tests/Bots/BadgeService/FakeEthNode.hs +++ b/tests/Bots/StoreService/FakeEthNode.hs @@ -1,7 +1,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.FakeEthNode +module Bots.StoreService.FakeEthNode ( FakeEthNode (..), withFakeEthNode, revertCalls, diff --git a/tests/Bots/BadgeService/FakeStripe.hs b/tests/Bots/StoreService/FakeStripe.hs similarity index 99% rename from tests/Bots/BadgeService/FakeStripe.hs rename to tests/Bots/StoreService/FakeStripe.hs index db4845c16f..e4fe3f86f7 100644 --- a/tests/Bots/BadgeService/FakeStripe.hs +++ b/tests/Bots/StoreService/FakeStripe.hs @@ -3,7 +3,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module Bots.BadgeService.FakeStripe +module Bots.StoreService.FakeStripe ( FakeStripe (..), FakeRequest (..), withFakeStripe, @@ -21,7 +21,7 @@ module Bots.BadgeService.FakeStripe ) where -import BadgeService.Config (StripeConfig (..)) +import StoreService.Config (StripeConfig (..)) import Control.Concurrent.STM import Crypto.Hash (Digest, SHA256) import Crypto.MAC.HMAC (HMAC, hmac, hmacGetDigest) @@ -67,7 +67,7 @@ import System.FilePath (()) import Text.Read (readMaybe) fixtureDir :: FilePath -fixtureDir = "apps" "simplex-badge-service" "test-fixtures" "stripe" +fixtureDir = "apps" "simplex-store-service" "test-fixtures" "stripe" -- | A restricted `rk_` key shaped like Stripe's, the kind the service is configured with and never a live one. fakeSecretKey :: Text diff --git a/tests/Bots/BadgeService/GroupIntegrationTests.hs b/tests/Bots/StoreService/GroupIntegrationTests.hs similarity index 98% rename from tests/Bots/BadgeService/GroupIntegrationTests.hs rename to tests/Bots/StoreService/GroupIntegrationTests.hs index 6919be7d47..46b4c7b967 100644 --- a/tests/Bots/BadgeService/GroupIntegrationTests.hs +++ b/tests/Bots/StoreService/GroupIntegrationTests.hs @@ -7,15 +7,15 @@ {-# LANGUAGE ScopedTypeVariables #-} -- Members' messages reach a console over separate connections in no fixed order, so gating is asserted from the bot's store. -module Bots.BadgeService.GroupIntegrationTests (badgeGroupIntegrationTests) where +module Bots.StoreService.GroupIntegrationTests (badgeGroupIntegrationTests) where -import BadgeService.Config (BadgeIssuerKey (..), GroupConfig (..)) -import BadgeService.Group (GroupAction (..), GroupEvent (..), codeInTracker, ensureManagedGroup) -import BadgeService.Group.Command (maxUses) -import BadgeService.Options (BadgeServiceOpts (..)) -import BadgeService.Service (ServiceState (..), badgeService, newServiceState) -import BadgeService.Store (ManagedGroup (..), getManagedGroup) -import Bots.BadgeService.BotTests (badgeBotName, badgeProfile, badgeTypeOf, credentialOf, entryOf, issueCode, issueRaw, mkBadgeServiceOpts, newPurchaseKeys, redeemWithQueue, requestObject, revokeRaw, serviceDbPrefix, shouldAnswerError, statementOf, stopBadgeService, testIssuerKeyIdx) +import StoreService.Config (BadgeIssuerKey (..), GroupConfig (..)) +import StoreService.Group (GroupAction (..), GroupEvent (..), codeInTracker, ensureManagedGroup) +import StoreService.Group.Command (maxUses) +import StoreService.Options (StoreServiceOpts (..)) +import StoreService.Service (ServiceState (..), storeService, newServiceState) +import StoreService.Store (ManagedGroup (..), getManagedGroup) +import Bots.StoreService.BotTests (badgeBotName, badgeProfile, badgeTypeOf, credentialOf, entryOf, issueCode, issueRaw, mkStoreServiceOpts, newPurchaseKeys, redeemWithQueue, requestObject, revokeRaw, serviceDbPrefix, shouldAnswerError, statementOf, stopStoreService, testIssuerKeyIdx) import ChatClient import ChatTests.DBUtils import ChatTests.Utils @@ -181,13 +181,13 @@ startGroupService :: HasCallStack => GroupSvc -> Maybe GroupConfig -> IO (Async startGroupService svc@GroupSvc {gsCfg} groupCfg = do (opts, port) <- groupServiceOpts svc groupCfg env <- newServiceState - t <- async $ badgeService opts gsCfg env + t <- async $ storeService opts gsCfg env -- A service that ends before it is ready fails the test with its own error, not the timeout. cc <- timeout waitLimit (atomically $ (Right <$> readTMVar (serviceCC env)) `orElse` (Left <$> waitCatchSTM t)) >>= \case Just (Right cc) -> pure cc - Just (Left ended) -> either throwIO (\_ -> error "badge service ended before it started") ended - Nothing -> cancel t >> error "badge service did not start" + Just (Left ended) -> either throwIO (\_ -> error "store service ended before it started") ended + Nothing -> cancel t >> error "store service did not start" pure (t, cc, env, port) -- Cancelling ends the service lanes while chat still runs; stopping chat first would leave them running. @@ -200,10 +200,10 @@ stopGroupService t cc = do forM_ ended $ either throwIO pure stopChat :: ChatController -> IO () -stopChat cc = stopBadgeService cc >> disposeAgentClient (smpAgent cc) +stopChat cc = stopStoreService cc >> disposeAgentClient (smpAgent cc) -- It writes the service's ini on a free port; Nothing omits the [group] section. -groupServiceOpts :: GroupSvc -> Maybe GroupConfig -> IO (BadgeServiceOpts, Int) +groupServiceOpts :: GroupSvc -> Maybe GroupConfig -> IO (StoreServiceOpts, Int) groupServiceOpts GroupSvc {gsKey = BadgeIssuerKey {secretKey}, gsStaticDir, gsPs = ps@TestParams {tmpPath}} groupCfg = do (port, sock) <- openFreePort close sock @@ -216,7 +216,7 @@ groupServiceOpts GroupSvc {gsKey = BadgeIssuerKey {secretKey}, gsStaticDir, gsPs "static_dir = " <> gsStaticDir ] <> maybe [] groupSection groupCfg - pure ((mkBadgeServiceOpts ps secretKey) {serviceConfigFile = Just iniPath, noAddress = True}, port) + pure ((mkStoreServiceOpts ps secretKey) {serviceConfigFile = Just iniPath, noAddress = True}, port) where groupSection GroupConfig {gDisplayName, gDescription} = ["", "[group]", "display_name = " <> T.unpack gDisplayName] @@ -381,7 +381,7 @@ testGroupLookupFailureStops ps = do (opts, _) <- groupServiceOpts svc (Just testGroupConfig) env <- newServiceState -- Falling through to create would keep the service running, so the timeout would fire instead. - ended <- timeout waitLimit (try $ badgeService opts gsCfg env) + ended <- timeout waitLimit (try $ storeService opts gsCfg env) atomically (tryReadTMVar (serviceCC env)) >>= mapM_ stopChat ended `shouldBe` Just (Left (ExitFailure 1)) diff --git a/tests/Bots/BadgeService/GroupTests.hs b/tests/Bots/StoreService/GroupTests.hs similarity index 98% rename from tests/Bots/BadgeService/GroupTests.hs rename to tests/Bots/StoreService/GroupTests.hs index c592178a91..12e3487513 100644 --- a/tests/Bots/BadgeService/GroupTests.hs +++ b/tests/Bots/StoreService/GroupTests.hs @@ -1,10 +1,10 @@ {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.GroupTests where +module Bots.StoreService.GroupTests where -import BadgeService.Config (GroupConfig (..)) -import BadgeService.Group (GroupAction (..), GroupEvent (..), TrackerAction (..), coalesceTrackerRefreshes, inertGroupConfig, noOwnerHint, orphanHint, trackerDecision) -import BadgeService.Group.Command +import StoreService.Config (GroupConfig (..)) +import StoreService.Group (GroupAction (..), GroupEvent (..), TrackerAction (..), coalesceTrackerRefreshes, inertGroupConfig, noOwnerHint, orphanHint, trackerDecision) +import StoreService.Group.Command import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) import Data.Time.Calendar (fromGregorian) diff --git a/tests/Bots/BadgeService/NameRegistrationTests.hs b/tests/Bots/StoreService/NameRegistrationTests.hs similarity index 97% rename from tests/Bots/BadgeService/NameRegistrationTests.hs rename to tests/Bots/StoreService/NameRegistrationTests.hs index 79989c576f..fa5e096c4d 100644 --- a/tests/Bots/BadgeService/NameRegistrationTests.hs +++ b/tests/Bots/StoreService/NameRegistrationTests.hs @@ -1,12 +1,12 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.NameRegistrationTests (badgeNameRegistrationTests) where +module Bots.StoreService.NameRegistrationTests (badgeNameRegistrationTests) where -import BadgeService.Names.Chain -import BadgeService.Names.Registration -import Bots.BadgeService.FakeEthNode -import Bots.BadgeService.WebUIMock +import StoreService.Names.Chain +import StoreService.Names.Registration +import Bots.StoreService.FakeEthNode +import Bots.StoreService.WebUIMock import Control.Concurrent.STM (TVar) import Crypto.Random (ChaChaDRG) import qualified Data.ByteArray as BA @@ -25,7 +25,7 @@ import Simplex.Messaging.SimplexName (SimplexTLD (..)) import Test.Hspec badgeNameRegistrationTests :: Spec -badgeNameRegistrationTests = describe "badge service name registration" $ do +badgeNameRegistrationTests = describe "store service name registration" $ do g <- runIO C.newRandom -- expected encodings and signatures are viem's, against the SimplexController, SimplexSponsor and SimplexResolver ABIs describe "encoding" $ do diff --git a/tests/Bots/BadgeService/StripeTests.hs b/tests/Bots/StoreService/StripeTests.hs similarity index 98% rename from tests/Bots/BadgeService/StripeTests.hs rename to tests/Bots/StoreService/StripeTests.hs index 6ab5c58486..773df83c05 100644 --- a/tests/Bots/BadgeService/StripeTests.hs +++ b/tests/Bots/StoreService/StripeTests.hs @@ -2,10 +2,10 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.StripeTests (badgeStripeTests) where +module Bots.StoreService.StripeTests (badgeStripeTests) where -import BadgeService.Config (StripeConfig (..)) -import BadgeService.Providers +import StoreService.Config (StripeConfig (..)) +import StoreService.Providers ( ListPass (..), OrderDraft (..), PaymentSignal (..), @@ -16,8 +16,8 @@ import BadgeService.Providers settleWindow, WebhookError (..), ) -import BadgeService.Providers.Stripe (IntentRead (..), signalOf, stripeProvider) -import Bots.BadgeService.FakeStripe +import StoreService.Providers.Stripe (IntentRead (..), signalOf, stripeProvider) +import Bots.StoreService.FakeStripe import Control.Monad (join) import Data.Aeson ((.=)) import qualified Data.ByteString.Char8 as B8 diff --git a/tests/Bots/BadgeService/WaitersTests.hs b/tests/Bots/StoreService/WaitersTests.hs similarity index 97% rename from tests/Bots/BadgeService/WaitersTests.hs rename to tests/Bots/StoreService/WaitersTests.hs index 8e5b5a180d..1bdafc76b9 100644 --- a/tests/Bots/BadgeService/WaitersTests.hs +++ b/tests/Bots/StoreService/WaitersTests.hs @@ -3,9 +3,9 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} -module Bots.BadgeService.WaitersTests (badgeWaitersTests) where +module Bots.StoreService.WaitersTests (badgeWaitersTests) where -import BadgeService.Waiters +import StoreService.Waiters import Control.Concurrent.Async (wait, withAsync) import Control.Concurrent.STM import Control.Exception (Exception, SomeException, throwIO, try) @@ -16,7 +16,7 @@ import System.Timeout (timeout) import Test.Hspec badgeWaitersTests :: Spec -badgeWaitersTests = describe "badge service waiters" $ do +badgeWaitersTests = describe "store service waiters" $ do it "wakes on a status published between subscribe and the database read" testSubscribeBeforeRead it "answers a payment whose publish landed before this request subscribed" testPaymentPublishedBeforeSubscribe it "is not woken by a publish for a different invoice" testDifferentInvoiceNoWake diff --git a/tests/Bots/BadgeService/WebTests.hs b/tests/Bots/StoreService/WebTests.hs similarity index 98% rename from tests/Bots/BadgeService/WebTests.hs rename to tests/Bots/StoreService/WebTests.hs index 577d54c313..6391ad5cac 100644 --- a/tests/Bots/BadgeService/WebTests.hs +++ b/tests/Bots/StoreService/WebTests.hs @@ -5,23 +5,23 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} -module Bots.BadgeService.WebTests (badgeWebTests) where +module Bots.StoreService.WebTests (badgeWebTests) where -import BadgeService.Catalog (catalogCurrency, defaultCatalog) -import BadgeService.Config (BTCPayConfig (..), ListenerConfig (..), PollConfig (..), ServiceConfig (..), SpeedPolicy (..), StripeConfig (..)) -import BadgeService.Orders (codeLifetime, settleOrder) -import BadgeService.Poller -import BadgeService.Providers -import BadgeService.Providers.BTCPay (btcpayProvider, listPageSize, maxListPages) -import BadgeService.Providers.Stripe (stripeProvider) -import BadgeService.Store (KeyPurchase (..), KeyRedemption (..), ManagedGroup (..), NewCodePurchase (..), RevokeResult (..), createCodePurchase, getCodePurchaseForKey, getManagedGroup, insertBadgeCode, insertManagedGroup, markOwnerBootstrapped, revokeCode) -import BadgeService.Store.Invoices -import BadgeService.Waiters (awaitStatus, newWaiters, publish, waitingCount) -import BadgeService.Web.Server -import Bots.BadgeService.BotTests (codeCounts, newPurchaseKeys) -import Bots.BadgeService.CatalogTests (WebOffer (..), WebPrice (..), parseCatalogSource) -import Bots.BadgeService.FakeBTCPay -import Bots.BadgeService.FakeStripe (FakeStripe (..), fakeIntentStatus, setIntentState, stripeEvent, stripeSigHeader, withFakeStripe) +import StoreService.Catalog (catalogCurrency, defaultCatalog) +import StoreService.Config (BTCPayConfig (..), ListenerConfig (..), PollConfig (..), ServiceConfig (..), SpeedPolicy (..), StripeConfig (..)) +import StoreService.Orders (codeLifetime, settleOrder) +import StoreService.Poller +import StoreService.Providers +import StoreService.Providers.BTCPay (btcpayProvider, listPageSize, maxListPages) +import StoreService.Providers.Stripe (stripeProvider) +import StoreService.Store (KeyPurchase (..), KeyRedemption (..), ManagedGroup (..), NewCodePurchase (..), RevokeResult (..), createCodePurchase, getCodePurchaseForKey, getManagedGroup, insertBadgeCode, insertManagedGroup, markOwnerBootstrapped, revokeCode) +import StoreService.Store.Invoices +import StoreService.Waiters (awaitStatus, newWaiters, publish, waitingCount) +import StoreService.Web.Server +import Bots.StoreService.BotTests (codeCounts, newPurchaseKeys) +import Bots.StoreService.CatalogTests (WebOffer (..), WebPrice (..), parseCatalogSource) +import Bots.StoreService.FakeBTCPay +import Bots.StoreService.FakeStripe (FakeStripe (..), fakeIntentStatus, setIntentState, stripeEvent, stripeSigHeader, withFakeStripe) import Control.Concurrent (forkIO, threadDelay) import Control.Concurrent.Async (async, wait) import qualified Control.Concurrent.Async as Async @@ -80,12 +80,12 @@ import Text.Read (readMaybe) import UnliftIO.Temporary (withTempDirectory) #if defined(dbPostgres) -import BadgeService.Store.Postgres.Migrations (badgeServiceSchemaMigrations) +import StoreService.Store.Postgres.Migrations (storeServiceSchemaMigrations) import ChatClient (testDBConnstr) import Database.PostgreSQL.Simple (Only (..)) import qualified Simplex.Messaging.Agent.Store.Postgres.Migrations as Migrations #else -import BadgeService.Store.SQLite.Migrations (badgeServiceSchemaMigrations) +import StoreService.Store.SQLite.Migrations (storeServiceSchemaMigrations) import Data.String (fromString) import Database.SQLite.Simple (Only (..)) import qualified Database.SQLite.Simple as SQL @@ -97,7 +97,7 @@ import qualified Simplex.Messaging.Agent.Store.SQLite.Migrations as Migrations withServiceStore :: (DBStore -> IO a) -> IO a withServiceStore action = do n <- atomicModifyIORef' serviceSchemaCounter (\i -> (i + 1, i)) - Right st <- createDBStore (serviceDBOpts n) badgeServiceSchemaMigrations (MigrationConfig MCError Nothing) + Right st <- createDBStore (serviceDBOpts n) storeServiceSchemaMigrations (MigrationConfig MCError Nothing) action st `E.finally` closeDBStore st where serviceDBOpts :: Int -> DBOpts @@ -117,7 +117,7 @@ withServiceStore :: (DBStore -> IO a) -> IO a withServiceStore action = do createDirectoryIfMissing True "tests/tmp" withTempDirectory "tests/tmp" "badge-web" $ \dir -> do - Right st <- createDBStore (DBOpts (dir "badge_service_test.db") [] "" False True TQOff) badgeServiceSchemaMigrations (MigrationConfig MCError Nothing) + Right st <- createDBStore (DBOpts (dir "badge_service_test.db") [] "" False True TQOff) storeServiceSchemaMigrations (MigrationConfig MCError Nothing) action st `E.finally` closeDBStore st #endif @@ -136,14 +136,14 @@ columnsOf st table = withConnection st $ \db -> badgeWebTests :: Spec badgeWebTests = do - describe "badge service schema" $ do + describe "store service schema" $ do it "carries the five service-only columns" testServiceColumns it "refuses a duplicate provider_ref" testProviderRefUnique it "M20260918 adds the multi-use columns and the group table" testGroupOpsColumns it "M20260918 defaults a fresh code to one use with none spent" testGroupOpsRedeemCounts it "migrates all the way down and up again" testSchemaDownUpCycle it "rolls back only the group migration and re-applies it, keeping a code redeemed twice spent" testGroupOpsDownUp - describe "badge service store" $ do + describe "store service store" $ do it "writes the invoice, its code and their link atomically" testCreationIsAtomic it "newInvoiceId is 128 CSPRNG bits, base64url, and two calls differ" testNewInvoiceIdRandom it "codeHashExists is true for a hash already written" testCodeHashExists @@ -162,17 +162,17 @@ badgeWebTests = do it "finds a key's own purchase with its newest credential, and none for another key" testKeyPurchaseLookup it "gives concurrent claims exactly the code's uses" testMultiUseConcurrentClaimsUpToLimit it "refuses a second claim by the same key without using up a use" testSameKeyClaimsOnce - describe "badge service catalog seed" $ do + describe "store service catalog seed" $ do it "writes the compiled-in catalog into an empty database" testSeedWritesTheCatalog it "leaves exactly one row per id when the service starts twice" testSeedIsIdempotent it "leaves a price and an offer an operator withdrew withdrawn" testSeedNeverResurrectsAWithdrawnRow it "seeds exactly what web/src/catalog.ts compiles into the page" testSeedMatchesWebCatalog it "prices a btc checkout, and answers card provider_unavailable" testSeededCatalogSellsSomething - describe "BadgeService.Providers stub" $ do + describe "StoreService.Providers stub" $ do it "constructs a Provider record and records every call, in order" testStubProviderRecordsCalls it "makes pCreateInvoice fail on demand, so provider_unavailable is exercisable" testStubProviderCreateFailsOnDemand it "records nothing when the caller never reaches the provider" testStubProviderNotCalledWhenSkipped - describe "badge service web" $ do + describe "store service web" $ do it "serves the shell at / and a hashed asset under /assets" testServesTheBuild it "fills the shell's publishable key from the ini at boot" testShellCarriesPublishableKey it "caches by where the file is, not by how the request spelled it" testCachingFollowsTheResolvedPath @@ -203,7 +203,7 @@ badgeWebTests = do it "answers a hold from the row it read, not from the status it woke on" testHoldReportsTheRowNotTheWake it "answers a hold that timed out with a change nothing published" testHoldTimeoutReportsAnUnpublishedChange it "answers a handler exception with 500 internal, and keeps serving" testHandlerExceptionIsContained - describe "badge service settlement" $ do + describe "store service settlement" $ do it "settles an open invoice: paid, a settled payment row, and the code" testSettlesAnOpenInvoice it "settles an expired invoice, because late settlement is routine" testLateSettlementIsLegal it "records what arrived without moving an unsettled invoice" testFundedRecordsWithoutMoving @@ -223,7 +223,7 @@ badgeWebTests = do it "reports settledAt from the payment row, not from the invoice" testSettledAtIsThePaymentRow it "refuses a settlement instant the provider cannot have meant" testAbsurdSettledInstantIsRefused it "refuses a settlement instant in the future, as a millisecond clock gives" testFutureSettledInstantIsRefused - describe "badge service poller" $ do + describe "store service poller" $ do it "settles a payment with no webhook delivered anywhere" testSettlesWithNoWebhookAtAll it "reads only the invoices it is waiting on, and lists on the stray cadence" testPassReadsWhatItAwaits it "asks the provider nothing when it is waiting on nothing" testIdlePassAsksNothing @@ -260,7 +260,7 @@ badgeWebTests = do it "settles the rest of the pass around an invoice that throws" testOneBadInvoiceDoesNotStopThePass it "pages past a hundred open invoices, a request per hundred" testListPaginates it "stops paging at its ceiling rather than looping on a server that ignores take" testPagingStopsAtTheCeiling - describe "badge service webhook" $ do + describe "store service webhook" $ do it "verifies a real BTCPay signature over the bytes as received, and queues" testWebhookVerifiesARealSignature it "hands the adapter the raw body, byte for byte" testWebhookPassesTheRawBytes it "queues a read and answers 200 empty, reaching no provider" testWebhookQueuesARead @@ -272,7 +272,7 @@ badgeWebTests = do it "queues a read of an order once, however often it is hinted before being served" testReadHintQueuedOnce it "drops a hint rather than blocking when the queue is full" testWebhookDropsAHintWhenFull it "answers 200 rather than any 5xx when the adapter or the store throws" testWebhookNeverAnswers5xx - describe "badge service checkout" $ do + describe "store service checkout" $ do it "answers the checkout fields and writes the three rows" testCreateInvoice it "carries no code and no code hash, over the raw bytes" testCreateCarriesNoCode it "tells the provider xmr rather than the chain another request used" testXmrReachesTheProviderAsXmr @@ -286,12 +286,12 @@ badgeWebTests = do it "answers method card with provider_unavailable when no Stripe provider is configured" testCardUnconfigured503 it "answers a provider that failed to create with provider_unavailable, writing nothing" testProviderFailureWritesNothing it "refuses the sixth create in a minute, without reaching the provider" testCreateRateLimit - describe "badge service card" $ do + describe "store service card" $ do it "creates a Stripe PaymentIntent, carrying its clientSecret and a stripe invoice row" testCardCreatesSession it "cancels an overdue card order's intent at Stripe before expiring it" testCardSweepCancelsTheIntent it "derives the shown expiry from stripe.session_minutes, not the btcpay window" testCardExpiryFollowsSessionMinutes it "settles a card invoice from a signed payment_intent.succeeded and a pass" testCardWebhookSettles - describe "badge service cancel" $ do + describe "store service cancel" $ do it "expires the invoice here and invalidates it at the provider" testCancelClosesTheInvoiceAtBothEnds it "wakes a hold another tab is sitting on" testCancelWakesAHeldRequest it "refuses to cancel an invoice that is no longer open" testCancelIsRefusedOnceItIsNotOpen @@ -300,7 +300,7 @@ badgeWebTests = do it "expires an invoice a payment landed on while the provider was being told" testCancelExpiresAFundedInvoice it "answers an unknown id with the same 404 the read does" testCancelIsOpaqueForAnUnknownInvoice it "answers GET with 405 and Allow: POST" testCancelRefusesOtherMethods - describe "badge service scenarios" $ do + describe "store service scenarios" $ do it "buys a code: create, pay at BTCPay, one pass, paid" scenarioPaidPurchase it "wakes a wait held from before the settlement, within a second of it" scenarioHeldWaitWakes it "reports a partial payment and leaves the invoice open" scenarioPartPaymentIsReported @@ -338,12 +338,12 @@ runMigrations st = Migrations.run st Nothing True testSchemaDownUpCycle :: IO () testSchemaDownUpCycle = withServiceStore $ \st -> do - let downMigrations = mapMaybe toDownMigration badgeServiceSchemaMigrations - length downMigrations `shouldBe` length badgeServiceSchemaMigrations + let downMigrations = mapMaybe toDownMigration storeServiceSchemaMigrations + length downMigrations `shouldBe` length storeServiceSchemaMigrations runMigrations st $ MTRDown downMigrations columnsOf st "sx_badge_service_badge_codes" `shouldReturn` [] columnsOf st "sx_badge_service_group" `shouldReturn` [] - runMigrations st $ MTRUp badgeServiceSchemaMigrations + runMigrations st $ MTRUp storeServiceSchemaMigrations assertGroupOpsColumns st testGroupOpsDownUp :: IO () @@ -351,7 +351,7 @@ testGroupOpsDownUp = withServiceStore $ \st -> do now <- truncateToSecond <$> getCurrentTime let redeemedHash = digestFixture 44 unredeemedHash = digestFixture 45 - groupOps = [m | m@Migration {name = "20260918_badge_group_ops"} <- badgeServiceSchemaMigrations] + groupOps = [m | m@Migration {name = "20260918_badge_group_ops"} <- storeServiceSchemaMigrations] redeemed <- insertCode st redeemedHash CPSPaid 2 now void $ insertCode st unredeemedHash CPSPaid 1 now -- Two purchases of one code would break a down migration that restored the unique index. @@ -648,7 +648,7 @@ testSeedNeverResurrectsAWithdrawnRow = withServiceStore $ \st -> do testSeedMatchesWebCatalog :: IO () testSeedMatchesWebCatalog = withServiceStore $ \st -> do - src <- T.readFile "apps/simplex-badge-service/web/src/catalog.ts" + src <- T.readFile "apps/simplex-store-service/web/src/catalog.ts" (webPrices, webOffers) <- case parseCatalogSource src of Nothing -> failWith "could not parse CATALOG out of web/src/catalog.ts -- its shape has changed" Just parsed -> pure parsed @@ -1184,13 +1184,13 @@ testServesTheBuild = bounded "serves the build" $ withWebApp $ \_ client -> do statusOf missing `shouldBe` 404 builtSiteDir :: FilePath -builtSiteDir = "apps" "simplex-badge-service" "web" "dist" +builtSiteDir = "apps" "simplex-store-service" "web" "dist" testServesBuiltWebApp :: IO () testServesBuiltWebApp = bounded "built web app" $ withServiceStore $ \st -> do built <- doesFileExist (builtSiteDir "index.html") if not built - then pendingWith ("no web build at " <> builtSiteDir <> ": run `npm run build` in apps/simplex-badge-service/web") + then pendingWith ("no web build at " <> builtSiteDir <> ": run `npm run build` in apps/simplex-store-service/web") else withListener [] True holdMicros st (testServiceConfig builtSiteDir False) $ \_ client -> do shell <- webGet client "/" statusOf shell `shouldBe` 200 diff --git a/tests/Bots/BadgeService/WebUIMock.hs b/tests/Bots/StoreService/WebUIMock.hs similarity index 95% rename from tests/Bots/BadgeService/WebUIMock.hs rename to tests/Bots/StoreService/WebUIMock.hs index a401fd59b3..0d684bb826 100644 --- a/tests/Bots/BadgeService/WebUIMock.hs +++ b/tests/Bots/StoreService/WebUIMock.hs @@ -1,7 +1,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -module Bots.BadgeService.WebUIMock +module Bots.StoreService.WebUIMock ( EphemeralWallet (..), newEphemeralWallet, redemptionCode, @@ -10,7 +10,7 @@ module Bots.BadgeService.WebUIMock ) where -import BadgeService.Names.Registration (RegisterIntent (..), Registration, registerIntentDigest) +import StoreService.Names.Registration (RegisterIntent (..), Registration, registerIntentDigest) import Control.Concurrent.STM (TVar) import Crypto.Random (ChaChaDRG) import Data.Text (Text) diff --git a/tests/Test.hs b/tests/Test.hs index 3a67120ba9..1a1fcab74a 100644 --- a/tests/Test.hs +++ b/tests/Test.hs @@ -3,16 +3,16 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE TupleSections #-} -import Bots.BadgeService.BTCPayTests -import Bots.BadgeService.BotTests -import Bots.BadgeService.CatalogTests -import Bots.BadgeService.ConfigTests -import Bots.BadgeService.GroupIntegrationTests -import Bots.BadgeService.GroupTests -import Bots.BadgeService.NameRegistrationTests -import Bots.BadgeService.StripeTests -import Bots.BadgeService.WaitersTests -import Bots.BadgeService.WebTests +import Bots.StoreService.BTCPayTests +import Bots.StoreService.BotTests +import Bots.StoreService.CatalogTests +import Bots.StoreService.ConfigTests +import Bots.StoreService.GroupIntegrationTests +import Bots.StoreService.GroupTests +import Bots.StoreService.NameRegistrationTests +import Bots.StoreService.StripeTests +import Bots.StoreService.WaitersTests +import Bots.StoreService.WebTests import Bots.BroadcastTests import Bots.DirectoryTests import ChatClient @@ -77,7 +77,7 @@ main = do around tmpBracket $ describe "WebRTC encryption" webRTCTests #endif describe "Supporter badges" badgeTests - describe "SimpleX badge service" $ do + describe "SimpleX store service" $ do badgeConfigTests badgeWebTests badgeCatalogTests @@ -113,8 +113,8 @@ main = do describe "Wallet" walletTests xdescribe'' "SimpleX Broadcast bot" broadcastBotTests describe "SimpleX Directory service bot" directoryServiceTests - describe "SimpleX badge service e2e" $ do - badgeServiceTests + describe "SimpleX store service e2e" $ do + storeServiceTests describe "managed group" badgeGroupIntegrationTests describe "Remote session" remoteTests #if !defined(dbPostgres)