@openora/core 0.4.0 → 0.4.1-canary.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-COMMERCIAL.md +2 -2
- package/README.md +18 -12
- package/bin/migrate.mjs +55 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/admin-console/__tests__/backoffice.router.test.js +82 -51
- package/dist/admin-console/__tests__/backoffice.router.test.js.map +1 -1
- package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts +2 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts.map +1 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.js +333 -0
- package/dist/admin-console/__tests__/backoffice.service.int.test.js.map +1 -0
- package/dist/admin-console/contract/index.d.ts +286 -30
- package/dist/admin-console/contract/index.d.ts.map +1 -1
- package/dist/admin-console/contract/index.js +81 -13
- package/dist/admin-console/contract/index.js.map +1 -1
- package/dist/admin-console/plugin.d.ts +137 -1
- package/dist/admin-console/plugin.d.ts.map +1 -1
- package/dist/admin-console/plugin.js +6 -6
- package/dist/admin-console/plugin.js.map +1 -1
- package/dist/admin-console/router/index.d.ts +127 -19
- package/dist/admin-console/router/index.d.ts.map +1 -1
- package/dist/admin-console/router/index.js +18 -2
- package/dist/admin-console/router/index.js.map +1 -1
- package/dist/admin-console/service/backoffice.service.d.ts +66 -40
- package/dist/admin-console/service/backoffice.service.d.ts.map +1 -1
- package/dist/admin-console/service/backoffice.service.js +80 -39
- package/dist/admin-console/service/backoffice.service.js.map +1 -1
- package/dist/analytics/__tests__/analytics.contract.test.d.ts +2 -0
- package/dist/analytics/__tests__/analytics.contract.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/analytics.contract.test.js +36 -0
- package/dist/analytics/__tests__/analytics.contract.test.js.map +1 -0
- package/dist/analytics/__tests__/analytics.router.test.d.ts +2 -0
- package/dist/analytics/__tests__/analytics.router.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/analytics.router.test.js +56 -0
- package/dist/analytics/__tests__/analytics.router.test.js.map +1 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.d.ts +2 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.js +87 -0
- package/dist/analytics/__tests__/financial-analytics.service.test.js.map +1 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts +2 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts.map +1 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.js +42 -0
- package/dist/analytics/__tests__/funnel-analytics.service.test.js.map +1 -0
- package/dist/analytics/contract/financial.d.ts +121 -0
- package/dist/analytics/contract/financial.d.ts.map +1 -0
- package/dist/analytics/contract/financial.js +45 -0
- package/dist/analytics/contract/financial.js.map +1 -0
- package/dist/analytics/contract/funnel.d.ts +52 -0
- package/dist/analytics/contract/funnel.d.ts.map +1 -0
- package/dist/analytics/contract/funnel.js +24 -0
- package/dist/analytics/contract/funnel.js.map +1 -0
- package/dist/analytics/contract/index.d.ts +68 -0
- package/dist/analytics/contract/index.d.ts.map +1 -0
- package/dist/analytics/contract/index.js +9 -0
- package/dist/analytics/contract/index.js.map +1 -0
- package/dist/analytics/index.d.ts +2 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +2 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/plugin.d.ts +139 -0
- package/dist/analytics/plugin.d.ts.map +1 -0
- package/dist/analytics/plugin.js +13 -0
- package/dist/analytics/plugin.js.map +1 -0
- package/dist/analytics/router/index.d.ts +69 -0
- package/dist/analytics/router/index.d.ts.map +1 -0
- package/dist/analytics/router/index.js +24 -0
- package/dist/analytics/router/index.js.map +1 -0
- package/dist/analytics/server.d.ts +5 -0
- package/dist/analytics/server.d.ts.map +1 -0
- package/dist/analytics/server.js +5 -0
- package/dist/analytics/server.js.map +1 -0
- package/dist/analytics/service/financial-analytics.service.d.ts +14 -0
- package/dist/analytics/service/financial-analytics.service.d.ts.map +1 -0
- package/dist/analytics/service/financial-analytics.service.js +145 -0
- package/dist/analytics/service/financial-analytics.service.js.map +1 -0
- package/dist/analytics/service/funnel-analytics.service.d.ts +11 -0
- package/dist/analytics/service/funnel-analytics.service.d.ts.map +1 -0
- package/dist/analytics/service/funnel-analytics.service.js +83 -0
- package/dist/analytics/service/funnel-analytics.service.js.map +1 -0
- package/dist/audit/__tests__/audit.service.int.test.d.ts +2 -0
- package/dist/audit/__tests__/audit.service.int.test.d.ts.map +1 -0
- package/dist/audit/__tests__/audit.service.int.test.js +633 -0
- package/dist/audit/__tests__/audit.service.int.test.js.map +1 -0
- package/dist/audit/__tests__/map-event.test.d.ts +2 -0
- package/dist/audit/__tests__/map-event.test.d.ts.map +1 -0
- package/dist/audit/__tests__/map-event.test.js +27 -0
- package/dist/audit/__tests__/map-event.test.js.map +1 -0
- package/dist/audit/contract/index.d.ts +68 -10
- package/dist/audit/contract/index.d.ts.map +1 -1
- package/dist/audit/contract/index.js +24 -4
- package/dist/audit/contract/index.js.map +1 -1
- package/dist/audit/plugin.d.ts +138 -1
- package/dist/audit/plugin.d.ts.map +1 -1
- package/dist/audit/plugin.js +398 -31
- package/dist/audit/plugin.js.map +1 -1
- package/dist/audit/router/index.d.ts +29 -5
- package/dist/audit/router/index.d.ts.map +1 -1
- package/dist/audit/router/index.js +1 -5
- package/dist/audit/router/index.js.map +1 -1
- package/dist/audit/service/audit.service.d.ts +10 -6
- package/dist/audit/service/audit.service.d.ts.map +1 -1
- package/dist/audit/service/audit.service.js +87 -34
- package/dist/audit/service/audit.service.js.map +1 -1
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.js +126 -0
- package/dist/casino/gaming/__tests__/admin-reporting.int.test.js.map +1 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts +2 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts.map +1 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.js +181 -0
- package/dist/casino/gaming/__tests__/gaming.service.int.test.js.map +1 -0
- package/dist/casino/gaming/admin-reporting.d.ts +9 -0
- package/dist/casino/gaming/admin-reporting.d.ts.map +1 -0
- package/dist/casino/gaming/admin-reporting.js +79 -0
- package/dist/casino/gaming/admin-reporting.js.map +1 -0
- package/dist/casino/gaming/contract/index.d.ts +19 -0
- package/dist/casino/gaming/contract/index.d.ts.map +1 -1
- package/dist/casino/gaming/contract/index.js +9 -3
- package/dist/casino/gaming/contract/index.js.map +1 -1
- package/dist/casino/gaming/drizzle/migrations/0001_easy_ben_grimm.sql +4 -0
- package/dist/casino/gaming/drizzle/migrations/0002_yummy_lifeguard.sql +4 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0001_snapshot.json +188 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0002_snapshot.json +237 -0
- package/dist/casino/gaming/drizzle/migrations/meta/_journal.json +14 -0
- package/dist/casino/gaming/plugin.d.ts +138 -1
- package/dist/casino/gaming/plugin.d.ts.map +1 -1
- package/dist/casino/gaming/plugin.js +9 -5
- package/dist/casino/gaming/plugin.js.map +1 -1
- package/dist/casino/gaming/router/index.d.ts +11 -0
- package/dist/casino/gaming/router/index.d.ts.map +1 -1
- package/dist/casino/gaming/router/index.js +6 -2
- package/dist/casino/gaming/router/index.js.map +1 -1
- package/dist/casino/gaming/schema/index.d.ts +18 -0
- package/dist/casino/gaming/schema/index.d.ts.map +1 -1
- package/dist/casino/gaming/schema/index.js +13 -3
- package/dist/casino/gaming/schema/index.js.map +1 -1
- package/dist/casino/gaming/service/gaming.service.d.ts +19 -12
- package/dist/casino/gaming/service/gaming.service.d.ts.map +1 -1
- package/dist/casino/gaming/service/gaming.service.js +51 -24
- package/dist/casino/gaming/service/gaming.service.js.map +1 -1
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts +2 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts.map +1 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.js +56 -0
- package/dist/casino/lobby/__tests__/lobby.cache.int.test.js.map +1 -0
- package/dist/casino/lobby/plugin.d.ts +136 -1
- package/dist/casino/lobby/plugin.d.ts.map +1 -1
- package/dist/casino/lobby/plugin.js +3 -3
- package/dist/casino/lobby/plugin.js.map +1 -1
- package/dist/casino/server.d.ts +1 -0
- package/dist/casino/server.d.ts.map +1 -1
- package/dist/casino/server.js +1 -0
- package/dist/casino/server.js.map +1 -1
- package/dist/cms/__tests__/cms.reads.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.reads.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.reads.int.test.js +66 -0
- package/dist/cms/__tests__/cms.reads.int.test.js.map +1 -0
- package/dist/cms/__tests__/cms.router.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.router.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.router.int.test.js +96 -0
- package/dist/cms/__tests__/cms.router.int.test.js.map +1 -0
- package/dist/cms/__tests__/cms.service.int.test.d.ts +2 -0
- package/dist/cms/__tests__/cms.service.int.test.d.ts.map +1 -0
- package/dist/cms/__tests__/cms.service.int.test.js +119 -0
- package/dist/cms/__tests__/cms.service.int.test.js.map +1 -0
- package/dist/cms/plugin.d.ts +136 -1
- package/dist/cms/plugin.d.ts.map +1 -1
- package/dist/cms/plugin.js +3 -3
- package/dist/cms/plugin.js.map +1 -1
- package/dist/cms/router/index.d.ts.map +1 -1
- package/dist/cms/router/index.js +12 -12
- package/dist/cms/router/index.js.map +1 -1
- package/dist/cms/service/cms.service.d.ts +7 -7
- package/dist/cms/service/cms.service.d.ts.map +1 -1
- package/dist/cms/service/cms.service.js +81 -25
- package/dist/cms/service/cms.service.js.map +1 -1
- package/dist/common/errors/__tests__/errors.mapper.test.d.ts +2 -0
- package/dist/common/errors/__tests__/errors.mapper.test.d.ts.map +1 -0
- package/dist/common/errors/__tests__/errors.mapper.test.js +59 -0
- package/dist/common/errors/__tests__/errors.mapper.test.js.map +1 -0
- package/dist/common/errors/errors.classes.js +3 -3
- package/dist/common/errors/errors.classes.js.map +1 -1
- package/dist/common/errors/errors.mapper.js +1 -1
- package/dist/common/errors/errors.mapper.js.map +1 -1
- package/dist/compliance/__tests__/assert.test.d.ts +2 -0
- package/dist/compliance/__tests__/assert.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/assert.test.js +34 -0
- package/dist/compliance/__tests__/assert.test.js.map +1 -0
- package/dist/compliance/__tests__/compliance.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/compliance.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/compliance.service.int.test.js +162 -0
- package/dist/compliance/__tests__/compliance.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js +82 -0
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.js +192 -0
- package/dist/compliance/__tests__/kyc-admin.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.js +173 -0
- package/dist/compliance/__tests__/kyc-webhook.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/kyc.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/kyc.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/kyc.service.int.test.js +275 -0
- package/dist/compliance/__tests__/kyc.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/limits.contract.test.d.ts +2 -0
- package/dist/compliance/__tests__/limits.contract.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/limits.contract.test.js +43 -0
- package/dist/compliance/__tests__/limits.contract.test.js.map +1 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.js +271 -0
- package/dist/compliance/__tests__/rg-monitoring.service.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg.contract.test.js +32 -14
- package/dist/compliance/__tests__/rg.contract.test.js.map +1 -1
- package/dist/compliance/__tests__/rg.router.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg.router.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg.router.int.test.js +158 -0
- package/dist/compliance/__tests__/rg.router.int.test.js.map +1 -0
- package/dist/compliance/__tests__/rg.service.int.test.d.ts +2 -0
- package/dist/compliance/__tests__/rg.service.int.test.d.ts.map +1 -0
- package/dist/compliance/__tests__/rg.service.int.test.js +356 -0
- package/dist/compliance/__tests__/rg.service.int.test.js.map +1 -0
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts +18 -5
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts.map +1 -1
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js +58 -7
- package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js.map +1 -1
- package/dist/compliance/contract/index.d.ts +428 -20
- package/dist/compliance/contract/index.d.ts.map +1 -1
- package/dist/compliance/contract/index.js +63 -4
- package/dist/compliance/contract/index.js.map +1 -1
- package/dist/compliance/contract/limits.d.ts +9 -2
- package/dist/compliance/contract/limits.d.ts.map +1 -1
- package/dist/compliance/contract/limits.js +21 -3
- package/dist/compliance/contract/limits.js.map +1 -1
- package/dist/compliance/contract/rg.d.ts +104 -34
- package/dist/compliance/contract/rg.d.ts.map +1 -1
- package/dist/compliance/contract/rg.js +37 -11
- package/dist/compliance/contract/rg.js.map +1 -1
- package/dist/compliance/drizzle/migrations/0001_funny_vance_astro.sql +5 -0
- package/dist/compliance/drizzle/migrations/0002_condemned_monster_badoon.sql +3 -0
- package/dist/compliance/drizzle/migrations/0003_public_spirit.sql +1 -0
- package/dist/compliance/drizzle/migrations/0004_military_silk_fever.sql +2 -0
- package/dist/compliance/drizzle/migrations/meta/0001_snapshot.json +660 -0
- package/dist/compliance/drizzle/migrations/meta/0002_snapshot.json +673 -0
- package/dist/compliance/drizzle/migrations/meta/0003_snapshot.json +679 -0
- package/dist/compliance/drizzle/migrations/meta/0004_snapshot.json +679 -0
- package/dist/compliance/drizzle/migrations/meta/_journal.json +28 -0
- package/dist/compliance/plugin.d.ts +139 -1
- package/dist/compliance/plugin.d.ts.map +1 -1
- package/dist/compliance/plugin.js +72 -20
- package/dist/compliance/plugin.js.map +1 -1
- package/dist/compliance/router/index.d.ts +262 -22
- package/dist/compliance/router/index.d.ts.map +1 -1
- package/dist/compliance/router/index.js +85 -25
- package/dist/compliance/router/index.js.map +1 -1
- package/dist/compliance/schema/index.d.ts +97 -18
- package/dist/compliance/schema/index.d.ts.map +1 -1
- package/dist/compliance/schema/index.js +19 -8
- package/dist/compliance/schema/index.js.map +1 -1
- package/dist/compliance/service/compliance.service.d.ts +39 -26
- package/dist/compliance/service/compliance.service.d.ts.map +1 -1
- package/dist/compliance/service/compliance.service.js +45 -38
- package/dist/compliance/service/compliance.service.js.map +1 -1
- package/dist/compliance/service/kyc.service.d.ts +167 -19
- package/dist/compliance/service/kyc.service.d.ts.map +1 -1
- package/dist/compliance/service/kyc.service.js +300 -55
- package/dist/compliance/service/kyc.service.js.map +1 -1
- package/dist/compliance/service/re-kyc-trigger.d.ts +4 -4
- package/dist/compliance/service/re-kyc-trigger.d.ts.map +1 -1
- package/dist/compliance/service/re-kyc-trigger.js +10 -6
- package/dist/compliance/service/re-kyc-trigger.js.map +1 -1
- package/dist/compliance/service/rg-eval.d.ts.map +1 -1
- package/dist/compliance/service/rg-eval.js +4 -2
- package/dist/compliance/service/rg-eval.js.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.d.ts +7 -6
- package/dist/compliance/service/rg-monitoring.service.d.ts.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.js +83 -40
- package/dist/compliance/service/rg-monitoring.service.js.map +1 -1
- package/dist/compliance/service/rg.service.d.ts +40 -7
- package/dist/compliance/service/rg.service.d.ts.map +1 -1
- package/dist/compliance/service/rg.service.js +163 -51
- package/dist/compliance/service/rg.service.js.map +1 -1
- package/dist/contracts/__tests__/compose-contract.test.d.ts +2 -0
- package/dist/contracts/__tests__/compose-contract.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/compose-contract.test.js +27 -0
- package/dist/contracts/__tests__/compose-contract.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.js +13 -0
- package/dist/contracts/adapters/__tests__/rate-limit.test.js.map +1 -0
- package/dist/contracts/adapters/__tests__/token.test.d.ts +2 -0
- package/dist/contracts/adapters/__tests__/token.test.d.ts.map +1 -0
- package/dist/contracts/adapters/__tests__/token.test.js +14 -0
- package/dist/contracts/adapters/__tests__/token.test.js.map +1 -0
- package/dist/contracts/adapters/admin-game-reporting.d.ts +43 -0
- package/dist/contracts/adapters/admin-game-reporting.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-game-reporting.js +17 -0
- package/dist/contracts/adapters/admin-game-reporting.js.map +1 -0
- package/dist/contracts/adapters/admin-permission.d.ts +10 -0
- package/dist/contracts/adapters/admin-permission.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-permission.js +6 -4
- package/dist/contracts/adapters/admin-permission.js.map +1 -1
- package/dist/contracts/adapters/admin-player-activity.d.ts +51 -0
- package/dist/contracts/adapters/admin-player-activity.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-player-activity.js +3 -0
- package/dist/contracts/adapters/admin-player-activity.js.map +1 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.d.ts +12 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.d.ts.map +1 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.js +3 -0
- package/dist/contracts/adapters/admin-role-assignment-directory.js.map +1 -0
- package/dist/contracts/adapters/admin-user-directory.d.ts +45 -4
- package/dist/contracts/adapters/admin-user-directory.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-user-directory.js +8 -0
- package/dist/contracts/adapters/admin-user-directory.js.map +1 -1
- package/dist/contracts/adapters/admin-wallet-reporting.d.ts +16 -5
- package/dist/contracts/adapters/admin-wallet-reporting.d.ts.map +1 -1
- package/dist/contracts/adapters/admin-wallet-reporting.js +9 -0
- package/dist/contracts/adapters/admin-wallet-reporting.js.map +1 -1
- package/dist/contracts/adapters/aggregator.d.ts +12 -0
- package/dist/contracts/adapters/aggregator.d.ts.map +1 -1
- package/dist/contracts/adapters/aggregator.js +5 -3
- package/dist/contracts/adapters/aggregator.js.map +1 -1
- package/dist/contracts/adapters/audit.d.ts +30 -4
- package/dist/contracts/adapters/audit.d.ts.map +1 -1
- package/dist/contracts/adapters/audit.js.map +1 -1
- package/dist/contracts/adapters/broker.d.ts +23 -0
- package/dist/contracts/adapters/broker.d.ts.map +1 -1
- package/dist/contracts/adapters/broker.js +8 -6
- package/dist/contracts/adapters/broker.js.map +1 -1
- package/dist/contracts/adapters/cache.d.ts +11 -0
- package/dist/contracts/adapters/cache.d.ts.map +1 -1
- package/dist/contracts/adapters/cache.js +8 -6
- package/dist/contracts/adapters/cache.js.map +1 -1
- package/dist/contracts/adapters/chat-block-writer.d.ts +18 -0
- package/dist/contracts/adapters/chat-block-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-block-writer.js +7 -0
- package/dist/contracts/adapters/chat-block-writer.js.map +1 -0
- package/dist/contracts/adapters/chat-moderation.d.ts +75 -0
- package/dist/contracts/adapters/chat-moderation.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-moderation.js +3 -0
- package/dist/contracts/adapters/chat-moderation.js.map +1 -0
- package/dist/contracts/adapters/chat-room-access.d.ts +6 -0
- package/dist/contracts/adapters/chat-room-access.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-room-access.js +3 -0
- package/dist/contracts/adapters/chat-room-access.js.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts +19 -0
- package/dist/contracts/adapters/chat-system-writer.d.ts.map +1 -0
- package/dist/contracts/adapters/chat-system-writer.js +3 -0
- package/dist/contracts/adapters/chat-system-writer.js.map +1 -0
- package/dist/contracts/adapters/email-template.d.ts +51 -0
- package/dist/contracts/adapters/email-template.d.ts.map +1 -0
- package/dist/contracts/adapters/email-template.js +50 -0
- package/dist/contracts/adapters/email-template.js.map +1 -0
- package/dist/contracts/adapters/email.d.ts +7 -0
- package/dist/contracts/adapters/email.d.ts.map +1 -1
- package/dist/contracts/adapters/email.js +7 -5
- package/dist/contracts/adapters/email.js.map +1 -1
- package/dist/contracts/adapters/error-tracking.d.ts +12 -0
- package/dist/contracts/adapters/error-tracking.d.ts.map +1 -0
- package/dist/contracts/adapters/error-tracking.js +3 -0
- package/dist/contracts/adapters/error-tracking.js.map +1 -0
- package/dist/contracts/adapters/game.d.ts +4 -0
- package/dist/contracts/adapters/game.d.ts.map +1 -1
- package/dist/contracts/adapters/game.js +4 -2
- package/dist/contracts/adapters/game.js.map +1 -1
- package/dist/contracts/adapters/geo-check-commands.d.ts +8 -0
- package/dist/contracts/adapters/geo-check-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/geo-check-commands.js +3 -0
- package/dist/contracts/adapters/geo-check-commands.js.map +1 -0
- package/dist/contracts/adapters/geo-ip.d.ts +4 -0
- package/dist/contracts/adapters/geo-ip.d.ts.map +1 -1
- package/dist/contracts/adapters/geo-ip.js +4 -2
- package/dist/contracts/adapters/geo-ip.js.map +1 -1
- package/dist/contracts/adapters/gift-commands.d.ts +58 -0
- package/dist/contracts/adapters/gift-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/gift-commands.js +11 -0
- package/dist/contracts/adapters/gift-commands.js.map +1 -0
- package/dist/contracts/adapters/identity-reader.d.ts +14 -4
- package/dist/contracts/adapters/identity-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/identity-reader.js.map +1 -1
- package/dist/contracts/adapters/identity.d.ts +15 -0
- package/dist/contracts/adapters/identity.d.ts.map +1 -1
- package/dist/contracts/adapters/identity.js +5 -2
- package/dist/contracts/adapters/identity.js.map +1 -1
- package/dist/contracts/adapters/index.d.ts +58 -13
- package/dist/contracts/adapters/index.d.ts.map +1 -1
- package/dist/contracts/adapters/index.js +32 -11
- package/dist/contracts/adapters/index.js.map +1 -1
- package/dist/contracts/adapters/job-queue.d.ts +55 -0
- package/dist/contracts/adapters/job-queue.d.ts.map +1 -1
- package/dist/contracts/adapters/job-queue.js +11 -9
- package/dist/contracts/adapters/job-queue.js.map +1 -1
- package/dist/contracts/adapters/kyc.d.ts +121 -4
- package/dist/contracts/adapters/kyc.d.ts.map +1 -1
- package/dist/contracts/adapters/kyc.js +30 -5
- package/dist/contracts/adapters/kyc.js.map +1 -1
- package/dist/contracts/adapters/login-enforcement.d.ts +8 -0
- package/dist/contracts/adapters/login-enforcement.d.ts.map +1 -1
- package/dist/contracts/adapters/login-enforcement.js +8 -6
- package/dist/contracts/adapters/login-enforcement.js.map +1 -1
- package/dist/contracts/adapters/notification.d.ts +7 -0
- package/dist/contracts/adapters/notification.d.ts.map +1 -1
- package/dist/contracts/adapters/notification.js +7 -5
- package/dist/contracts/adapters/notification.js.map +1 -1
- package/dist/contracts/adapters/outbox.d.ts +14 -0
- package/dist/contracts/adapters/outbox.d.ts.map +1 -1
- package/dist/contracts/adapters/outbox.js +14 -12
- package/dist/contracts/adapters/outbox.js.map +1 -1
- package/dist/contracts/adapters/payment.d.ts +191 -2
- package/dist/contracts/adapters/payment.d.ts.map +1 -1
- package/dist/contracts/adapters/payment.js +12 -2
- package/dist/contracts/adapters/payment.js.map +1 -1
- package/dist/contracts/adapters/play-eligibility.d.ts +15 -0
- package/dist/contracts/adapters/play-eligibility.d.ts.map +1 -0
- package/dist/contracts/adapters/play-eligibility.js +3 -0
- package/dist/contracts/adapters/play-eligibility.js.map +1 -0
- package/dist/contracts/adapters/player-activity.d.ts +6 -0
- package/dist/contracts/adapters/player-activity.d.ts.map +1 -0
- package/dist/contracts/adapters/player-activity.js +3 -0
- package/dist/contracts/adapters/player-activity.js.map +1 -0
- package/dist/contracts/adapters/player-provisioning.d.ts +21 -0
- package/dist/contracts/adapters/player-provisioning.d.ts.map +1 -0
- package/dist/contracts/adapters/player-provisioning.js +3 -0
- package/dist/contracts/adapters/player-provisioning.js.map +1 -0
- package/dist/contracts/adapters/player-tags.d.ts +4 -0
- package/dist/contracts/adapters/player-tags.d.ts.map +1 -1
- package/dist/contracts/adapters/player-tags.js.map +1 -1
- package/dist/contracts/adapters/rain-commands.d.ts +27 -0
- package/dist/contracts/adapters/rain-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/rain-commands.js +12 -0
- package/dist/contracts/adapters/rain-commands.js.map +1 -0
- package/dist/contracts/adapters/rate-limit.d.ts +41 -3
- package/dist/contracts/adapters/rate-limit.d.ts.map +1 -1
- package/dist/contracts/adapters/rate-limit.js +29 -6
- package/dist/contracts/adapters/rate-limit.js.map +1 -1
- package/dist/contracts/adapters/realtime.d.ts +106 -7
- package/dist/contracts/adapters/realtime.d.ts.map +1 -1
- package/dist/contracts/adapters/realtime.js +26 -10
- package/dist/contracts/adapters/realtime.js.map +1 -1
- package/dist/contracts/adapters/rng.d.ts +11 -0
- package/dist/contracts/adapters/rng.d.ts.map +1 -1
- package/dist/contracts/adapters/rng.js +11 -9
- package/dist/contracts/adapters/rng.js.map +1 -1
- package/dist/contracts/adapters/sms.d.ts +15 -0
- package/dist/contracts/adapters/sms.d.ts.map +1 -0
- package/dist/contracts/adapters/sms.js +9 -0
- package/dist/contracts/adapters/sms.js.map +1 -0
- package/dist/contracts/adapters/social-commands.d.ts +12 -0
- package/dist/contracts/adapters/social-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/social-commands.js +7 -0
- package/dist/contracts/adapters/social-commands.js.map +1 -0
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts +20 -0
- package/dist/contracts/adapters/tag-evaluation-commands.d.ts.map +1 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js +13 -0
- package/dist/contracts/adapters/tag-evaluation-commands.js.map +1 -0
- package/dist/contracts/adapters/token.d.ts +28 -5
- package/dist/contracts/adapters/token.d.ts.map +1 -1
- package/dist/contracts/adapters/token.js +10 -8
- package/dist/contracts/adapters/token.js.map +1 -1
- package/dist/contracts/adapters/wallet-asset-catalog.d.ts +34 -0
- package/dist/contracts/adapters/wallet-asset-catalog.d.ts.map +1 -0
- package/dist/contracts/adapters/wallet-asset-catalog.js +3 -0
- package/dist/contracts/adapters/wallet-asset-catalog.js.map +1 -0
- package/dist/contracts/adapters/wallet-commands.d.ts +16 -5
- package/dist/contracts/adapters/wallet-commands.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-commands.js.map +1 -1
- package/dist/contracts/adapters/wallet-reader.d.ts +11 -3
- package/dist/contracts/adapters/wallet-reader.d.ts.map +1 -1
- package/dist/contracts/adapters/wallet-reader.js.map +1 -1
- package/dist/contracts/kit.d.ts +15 -0
- package/dist/contracts/kit.d.ts.map +1 -1
- package/dist/contracts/kit.js +1 -0
- package/dist/contracts/kit.js.map +1 -1
- package/dist/contracts/schemas/__tests__/common-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/common-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/common-schemas.test.js +21 -0
- package/dist/contracts/schemas/__tests__/common-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/events.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/events.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/events.test.js +51 -0
- package/dist/contracts/schemas/__tests__/events.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.js +38 -0
- package/dist/contracts/schemas/__tests__/igaming-config.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.js +30 -0
- package/dist/contracts/schemas/__tests__/player-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts +2 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts.map +1 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.js +42 -0
- package/dist/contracts/schemas/__tests__/tag-schemas.test.js.map +1 -0
- package/dist/contracts/schemas/chat-command-metadata.d.ts +73 -0
- package/dist/contracts/schemas/chat-command-metadata.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command-metadata.js +67 -0
- package/dist/contracts/schemas/chat-command-metadata.js.map +1 -0
- package/dist/contracts/schemas/chat-command.d.ts +213 -0
- package/dist/contracts/schemas/chat-command.d.ts.map +1 -0
- package/dist/contracts/schemas/chat-command.js +44 -0
- package/dist/contracts/schemas/chat-command.js.map +1 -0
- package/dist/contracts/schemas/common.d.ts +19 -5
- package/dist/contracts/schemas/common.d.ts.map +1 -1
- package/dist/contracts/schemas/common.js +29 -4
- package/dist/contracts/schemas/common.js.map +1 -1
- package/dist/contracts/schemas/compliance.d.ts +1 -1
- package/dist/contracts/schemas/events.d.ts +549 -10
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +401 -64
- package/dist/contracts/schemas/events.js.map +1 -1
- package/dist/contracts/schemas/game.d.ts +9 -0
- package/dist/contracts/schemas/game.d.ts.map +1 -0
- package/dist/contracts/schemas/game.js +4 -0
- package/dist/contracts/schemas/game.js.map +1 -0
- package/dist/contracts/schemas/identity.d.ts +65 -2
- package/dist/contracts/schemas/identity.d.ts.map +1 -1
- package/dist/contracts/schemas/identity.js +51 -3
- package/dist/contracts/schemas/identity.js.map +1 -1
- package/dist/contracts/schemas/igaming-config.d.ts +25 -1
- package/dist/contracts/schemas/igaming-config.d.ts.map +1 -1
- package/dist/contracts/schemas/igaming-config.js +2 -1
- package/dist/contracts/schemas/igaming-config.js.map +1 -1
- package/dist/contracts/schemas/index.d.ts +4 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -1
- package/dist/contracts/schemas/index.js +4 -0
- package/dist/contracts/schemas/index.js.map +1 -1
- package/dist/contracts/schemas/platform-config.d.ts +74 -35
- package/dist/contracts/schemas/platform-config.d.ts.map +1 -1
- package/dist/contracts/schemas/platform-config.js +75 -9
- package/dist/contracts/schemas/platform-config.js.map +1 -1
- package/dist/contracts/schemas/player.d.ts +63 -5
- package/dist/contracts/schemas/player.d.ts.map +1 -1
- package/dist/contracts/schemas/player.js +32 -6
- package/dist/contracts/schemas/player.js.map +1 -1
- package/dist/contracts/schemas/reporting.d.ts +20 -0
- package/dist/contracts/schemas/reporting.d.ts.map +1 -0
- package/dist/contracts/schemas/reporting.js +13 -0
- package/dist/contracts/schemas/reporting.js.map +1 -0
- package/dist/contracts/schemas/tag.d.ts +88 -4
- package/dist/contracts/schemas/tag.d.ts.map +1 -1
- package/dist/contracts/schemas/tag.js +16 -4
- package/dist/contracts/schemas/tag.js.map +1 -1
- package/dist/contracts/schemas/wallet-tx.d.ts +40 -1
- package/dist/contracts/schemas/wallet-tx.d.ts.map +1 -1
- package/dist/contracts/schemas/wallet-tx.js +34 -3
- package/dist/contracts/schemas/wallet-tx.js.map +1 -1
- package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.js +1430 -0
- package/dist/engagement/chat/__tests__/chat.service.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts +2 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts.map +1 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.js +91 -0
- package/dist/engagement/chat/__tests__/global-chat-room.int.test.js.map +1 -0
- package/dist/engagement/chat/__tests__/moderation.test.js +2 -0
- package/dist/engagement/chat/__tests__/moderation.test.js.map +1 -1
- package/dist/engagement/chat/contract/constants.d.ts +11 -0
- package/dist/engagement/chat/contract/constants.d.ts.map +1 -0
- package/dist/engagement/chat/contract/constants.js +11 -0
- package/dist/engagement/chat/contract/constants.js.map +1 -0
- package/dist/engagement/chat/contract/index.d.ts +1948 -17
- package/dist/engagement/chat/contract/index.d.ts.map +1 -1
- package/dist/engagement/chat/contract/index.js +407 -11
- package/dist/engagement/chat/contract/index.js.map +1 -1
- package/dist/engagement/chat/drizzle/migrations/0001_cloudy_groot.sql +32 -0
- package/dist/engagement/chat/drizzle/migrations/0002_steep_zodiak.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0003_stormy_king_bedlam.sql +9 -0
- package/dist/engagement/chat/drizzle/migrations/0004_panoramic_robin_chapel.sql +6 -0
- package/dist/engagement/chat/drizzle/migrations/0005_tranquil_gwen_stacy.sql +100 -0
- package/dist/engagement/chat/drizzle/migrations/0006_tiny_ultron.sql +3 -0
- package/dist/engagement/chat/drizzle/migrations/0007_seed_global_chat_room.sql +8 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0001_snapshot.json +557 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0002_snapshot.json +576 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0003_snapshot.json +652 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0004_snapshot.json +666 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0005_snapshot.json +1422 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0006_snapshot.json +1456 -0
- package/dist/engagement/chat/drizzle/migrations/meta/0007_snapshot.json +1456 -0
- package/dist/engagement/chat/drizzle/migrations/meta/_journal.json +49 -0
- package/dist/engagement/chat/index.d.ts +1 -2
- package/dist/engagement/chat/index.d.ts.map +1 -1
- package/dist/engagement/chat/index.js +1 -2
- package/dist/engagement/chat/index.js.map +1 -1
- package/dist/engagement/chat/moderation/moderate.d.ts.map +1 -1
- package/dist/engagement/chat/moderation/moderate.js +2 -1
- package/dist/engagement/chat/moderation/moderate.js.map +1 -1
- package/dist/engagement/chat/moderation/profanity.d.ts.map +1 -1
- package/dist/engagement/chat/moderation/profanity.js +2 -0
- package/dist/engagement/chat/moderation/profanity.js.map +1 -1
- package/dist/engagement/chat/plugin.d.ts +137 -1
- package/dist/engagement/chat/plugin.d.ts.map +1 -1
- package/dist/engagement/chat/plugin.js +34 -5
- package/dist/engagement/chat/plugin.js.map +1 -1
- package/dist/engagement/chat/router/index.d.ts +1515 -17
- package/dist/engagement/chat/router/index.d.ts.map +1 -1
- package/dist/engagement/chat/router/index.js +269 -28
- package/dist/engagement/chat/router/index.js.map +1 -1
- package/dist/engagement/chat/schema/index.d.ts +1508 -0
- package/dist/engagement/chat/schema/index.d.ts.map +1 -1
- package/dist/engagement/chat/schema/index.js +175 -3
- package/dist/engagement/chat/schema/index.js.map +1 -1
- package/dist/engagement/chat/service/chat-ban.service.d.ts +26 -0
- package/dist/engagement/chat/service/chat-ban.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-ban.service.js +139 -0
- package/dist/engagement/chat/service/chat-ban.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.d.ts +14 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.js +48 -0
- package/dist/engagement/chat/service/chat-message-moderation.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-moderation.service.d.ts +30 -0
- package/dist/engagement/chat/service/chat-moderation.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-moderation.service.js +40 -0
- package/dist/engagement/chat/service/chat-moderation.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-mute.service.d.ts +26 -0
- package/dist/engagement/chat/service/chat-mute.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-mute.service.js +151 -0
- package/dist/engagement/chat/service/chat-mute.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-ban.service.d.ts +29 -0
- package/dist/engagement/chat/service/chat-room-ban.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-ban.service.js +105 -0
- package/dist/engagement/chat/service/chat-room-ban.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-membership.service.d.ts +72 -0
- package/dist/engagement/chat/service/chat-room-membership.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-membership.service.js +176 -0
- package/dist/engagement/chat/service/chat-room-membership.service.js.map +1 -0
- package/dist/engagement/chat/service/chat-room-mute.service.d.ts +25 -0
- package/dist/engagement/chat/service/chat-room-mute.service.d.ts.map +1 -0
- package/dist/engagement/chat/service/chat-room-mute.service.js +89 -0
- package/dist/engagement/chat/service/chat-room-mute.service.js.map +1 -0
- package/dist/engagement/chat/service/chat.service.d.ts +1030 -32
- package/dist/engagement/chat/service/chat.service.d.ts.map +1 -1
- package/dist/engagement/chat/service/chat.service.js +1079 -76
- package/dist/engagement/chat/service/chat.service.js.map +1 -1
- package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts +21 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts.map +1 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.js +31 -0
- package/dist/engagement/chat/service/errors/chat-moderation.errors.js.map +1 -0
- package/dist/engagement/chat-commands/contract/index.d.ts +361 -0
- package/dist/engagement/chat-commands/contract/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/contract/index.js +117 -0
- package/dist/engagement/chat-commands/contract/index.js.map +1 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0000_daffy_lady_bullseye.sql +24 -0
- package/dist/engagement/chat-commands/drizzle/migrations/0001_sturdy_barracuda.sql +1 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0000_snapshot.json +164 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/0001_snapshot.json +83 -0
- package/dist/engagement/chat-commands/drizzle/migrations/meta/_journal.json +20 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts +4 -0
- package/dist/engagement/chat-commands/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/chat-commands/drizzle.config.js +21 -0
- package/dist/engagement/chat-commands/drizzle.config.js.map +1 -0
- package/dist/engagement/chat-commands/migrate.d.ts +3 -0
- package/dist/engagement/chat-commands/migrate.d.ts.map +1 -0
- package/dist/engagement/chat-commands/migrate.js +15 -0
- package/dist/engagement/chat-commands/migrate.js.map +1 -0
- package/dist/engagement/chat-commands/plugin.d.ts +139 -0
- package/dist/engagement/chat-commands/plugin.d.ts.map +1 -0
- package/dist/engagement/chat-commands/plugin.js +15 -0
- package/dist/engagement/chat-commands/plugin.js.map +1 -0
- package/dist/engagement/chat-commands/router/index.d.ts +276 -0
- package/dist/engagement/chat-commands/router/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/router/index.js +76 -0
- package/dist/engagement/chat-commands/router/index.js.map +1 -0
- package/dist/engagement/chat-commands/schema/index.d.ts +138 -0
- package/dist/engagement/chat-commands/schema/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/schema/index.js +11 -0
- package/dist/engagement/chat-commands/schema/index.js.map +1 -0
- package/dist/engagement/chat-commands/seed/index.d.ts +3 -0
- package/dist/engagement/chat-commands/seed/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/seed/index.js +66 -0
- package/dist/engagement/chat-commands/seed/index.js.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts +2 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js +431 -0
- package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts +73 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.d.ts.map +1 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js +258 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js.map +1 -0
- package/dist/engagement/contracts.d.ts +3 -0
- package/dist/engagement/contracts.d.ts.map +1 -1
- package/dist/engagement/contracts.js +3 -0
- package/dist/engagement/contracts.js.map +1 -1
- package/dist/engagement/index.d.ts +3 -0
- package/dist/engagement/index.d.ts.map +1 -1
- package/dist/engagement/index.js +3 -0
- package/dist/engagement/index.js.map +1 -1
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts +2 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts.map +1 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.js +192 -0
- package/dist/engagement/notifications/__tests__/notifications.service.int.test.js.map +1 -0
- package/dist/engagement/notifications/contract/index.d.ts +40 -2
- package/dist/engagement/notifications/contract/index.d.ts.map +1 -1
- package/dist/engagement/notifications/contract/index.js +17 -1
- package/dist/engagement/notifications/contract/index.js.map +1 -1
- package/dist/engagement/notifications/index.d.ts +1 -1
- package/dist/engagement/notifications/index.d.ts.map +1 -1
- package/dist/engagement/notifications/plugin.d.ts +138 -1
- package/dist/engagement/notifications/plugin.d.ts.map +1 -1
- package/dist/engagement/notifications/plugin.js +88 -9
- package/dist/engagement/notifications/plugin.js.map +1 -1
- package/dist/engagement/notifications/router/index.d.ts +8 -1
- package/dist/engagement/notifications/router/index.d.ts.map +1 -1
- package/dist/engagement/notifications/router/index.js +15 -6
- package/dist/engagement/notifications/router/index.js.map +1 -1
- package/dist/engagement/notifications/service/notifications.service.d.ts +6 -13
- package/dist/engagement/notifications/service/notifications.service.d.ts.map +1 -1
- package/dist/engagement/notifications/service/notifications.service.js +6 -14
- package/dist/engagement/notifications/service/notifications.service.js.map +1 -1
- package/dist/engagement/server.d.ts +3 -0
- package/dist/engagement/server.d.ts.map +1 -1
- package/dist/engagement/server.js +3 -0
- package/dist/engagement/server.js.map +1 -1
- package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.js +100 -0
- package/dist/engagement/social/__tests__/social.plugin.int.test.js.map +1 -0
- package/dist/engagement/social/__tests__/social.router.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.router.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.router.int.test.js +215 -0
- package/dist/engagement/social/__tests__/social.router.int.test.js.map +1 -0
- package/dist/engagement/social/__tests__/social.service.int.test.d.ts +2 -0
- package/dist/engagement/social/__tests__/social.service.int.test.d.ts.map +1 -0
- package/dist/engagement/social/__tests__/social.service.int.test.js +810 -0
- package/dist/engagement/social/__tests__/social.service.int.test.js.map +1 -0
- package/dist/engagement/social/contract/index.d.ts +187 -0
- package/dist/engagement/social/contract/index.d.ts.map +1 -0
- package/dist/engagement/social/contract/index.js +107 -0
- package/dist/engagement/social/contract/index.js.map +1 -0
- package/dist/engagement/social/drizzle/migrations/0000_fine_jamie_braddock.sql +24 -0
- package/dist/engagement/social/drizzle/migrations/0001_lame_eddie_brock.sql +10 -0
- package/dist/engagement/social/drizzle/migrations/0002_foamy_saracen.sql +1 -0
- package/dist/engagement/social/drizzle/migrations/0003_fuzzy_shadow_king.sql +4 -0
- package/dist/engagement/social/drizzle/migrations/0004_friendship-cancel-constraint.sql +2 -0
- package/dist/engagement/social/drizzle/migrations/meta/0000_snapshot.json +232 -0
- package/dist/engagement/social/drizzle/migrations/meta/0001_snapshot.json +129 -0
- package/dist/engagement/social/drizzle/migrations/meta/0002_snapshot.json +134 -0
- package/dist/engagement/social/drizzle/migrations/meta/0003_snapshot.json +145 -0
- package/dist/engagement/social/drizzle/migrations/meta/0004_snapshot.json +145 -0
- package/dist/engagement/social/drizzle/migrations/meta/_journal.json +41 -0
- package/dist/engagement/social/drizzle.config.d.ts +4 -0
- package/dist/engagement/social/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/social/drizzle.config.js +21 -0
- package/dist/engagement/social/drizzle.config.js.map +1 -0
- package/dist/engagement/social/index.d.ts +3 -0
- package/dist/engagement/social/index.d.ts.map +1 -0
- package/dist/engagement/social/index.js +6 -0
- package/dist/engagement/social/index.js.map +1 -0
- package/dist/engagement/social/migrate.d.ts +5 -0
- package/dist/engagement/social/migrate.d.ts.map +1 -0
- package/dist/engagement/social/migrate.js +17 -0
- package/dist/engagement/social/migrate.js.map +1 -0
- package/dist/engagement/social/plugin.d.ts +139 -0
- package/dist/engagement/social/plugin.d.ts.map +1 -0
- package/dist/engagement/social/plugin.js +17 -0
- package/dist/engagement/social/plugin.js.map +1 -0
- package/dist/engagement/social/router/index.d.ts +98 -0
- package/dist/engagement/social/router/index.d.ts.map +1 -0
- package/dist/engagement/social/router/index.js +68 -0
- package/dist/engagement/social/router/index.js.map +1 -0
- package/dist/engagement/social/schema/index.d.ts +145 -0
- package/dist/engagement/social/schema/index.d.ts.map +1 -0
- package/dist/engagement/social/schema/index.js +24 -0
- package/dist/engagement/social/schema/index.js.map +1 -0
- package/dist/engagement/social/service/social.service.d.ts +55 -0
- package/dist/engagement/social/service/social.service.d.ts.map +1 -0
- package/dist/engagement/social/service/social.service.js +479 -0
- package/dist/engagement/social/service/social.service.js.map +1 -0
- package/dist/engagement/social-transfers/contract/index.d.ts +85 -0
- package/dist/engagement/social-transfers/contract/index.d.ts.map +1 -0
- package/dist/engagement/social-transfers/contract/index.js +21 -0
- package/dist/engagement/social-transfers/contract/index.js.map +1 -0
- package/dist/engagement/social-transfers/drizzle/migrations/0000_clammy_rattler.sql +46 -0
- package/dist/engagement/social-transfers/drizzle/migrations/0001_fearless_molecule_man.sql +5 -0
- package/dist/engagement/social-transfers/drizzle/migrations/meta/0000_snapshot.json +287 -0
- package/dist/engagement/social-transfers/drizzle/migrations/meta/0001_snapshot.json +287 -0
- package/dist/engagement/social-transfers/drizzle/migrations/meta/_journal.json +20 -0
- package/dist/engagement/social-transfers/drizzle.config.d.ts +4 -0
- package/dist/engagement/social-transfers/drizzle.config.d.ts.map +1 -0
- package/dist/engagement/social-transfers/drizzle.config.js +21 -0
- package/dist/engagement/social-transfers/drizzle.config.js.map +1 -0
- package/dist/engagement/social-transfers/index.d.ts +3 -0
- package/dist/engagement/social-transfers/index.d.ts.map +1 -0
- package/dist/engagement/social-transfers/index.js +6 -0
- package/dist/engagement/social-transfers/index.js.map +1 -0
- package/dist/engagement/social-transfers/migrate.d.ts +5 -0
- package/dist/engagement/social-transfers/migrate.d.ts.map +1 -0
- package/dist/engagement/social-transfers/migrate.js +17 -0
- package/dist/engagement/social-transfers/migrate.js.map +1 -0
- package/dist/engagement/social-transfers/plugin.d.ts +139 -0
- package/dist/engagement/social-transfers/plugin.d.ts.map +1 -0
- package/dist/engagement/social-transfers/plugin.js +24 -0
- package/dist/engagement/social-transfers/plugin.js.map +1 -0
- package/dist/engagement/social-transfers/router/index.d.ts +77 -0
- package/dist/engagement/social-transfers/router/index.d.ts.map +1 -0
- package/dist/engagement/social-transfers/router/index.js +26 -0
- package/dist/engagement/social-transfers/router/index.js.map +1 -0
- package/dist/engagement/social-transfers/schema/index.d.ts +608 -0
- package/dist/engagement/social-transfers/schema/index.d.ts.map +1 -0
- package/dist/engagement/social-transfers/schema/index.js +61 -0
- package/dist/engagement/social-transfers/schema/index.js.map +1 -0
- package/dist/engagement/social-transfers/service/__tests__/rain-split.int.test.d.ts +2 -0
- package/dist/engagement/social-transfers/service/__tests__/rain-split.int.test.d.ts.map +1 -0
- package/dist/engagement/social-transfers/service/__tests__/rain-split.int.test.js +31 -0
- package/dist/engagement/social-transfers/service/__tests__/rain-split.int.test.js.map +1 -0
- package/dist/engagement/social-transfers/service/__tests__/social-transfers.service.test.d.ts +2 -0
- package/dist/engagement/social-transfers/service/__tests__/social-transfers.service.test.d.ts.map +1 -0
- package/dist/engagement/social-transfers/service/__tests__/social-transfers.service.test.js +936 -0
- package/dist/engagement/social-transfers/service/__tests__/social-transfers.service.test.js.map +1 -0
- package/dist/engagement/social-transfers/service/social-transfers.service.d.ts +81 -0
- package/dist/engagement/social-transfers/service/social-transfers.service.d.ts.map +1 -0
- package/dist/engagement/social-transfers/service/social-transfers.service.js +807 -0
- package/dist/engagement/social-transfers/service/social-transfers.service.js.map +1 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.d.ts +2 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.d.ts.map +1 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.js +119 -0
- package/dist/iam/__tests__/admin-player-activity.int.test.js.map +1 -0
- package/dist/iam/__tests__/iam.service.int.test.d.ts +2 -0
- package/dist/iam/__tests__/iam.service.int.test.d.ts.map +1 -0
- package/dist/iam/__tests__/iam.service.int.test.js +573 -0
- package/dist/iam/__tests__/iam.service.int.test.js.map +1 -0
- package/dist/iam/adapters/admin-player-activity.d.ts +10 -0
- package/dist/iam/adapters/admin-player-activity.d.ts.map +1 -0
- package/dist/iam/adapters/admin-player-activity.js +106 -0
- package/dist/iam/adapters/admin-player-activity.js.map +1 -0
- package/dist/iam/adapters/admin-role-assignment-directory.d.ts +8 -0
- package/dist/iam/adapters/admin-role-assignment-directory.d.ts.map +1 -0
- package/dist/iam/adapters/admin-role-assignment-directory.js +23 -0
- package/dist/iam/adapters/admin-role-assignment-directory.js.map +1 -0
- package/dist/iam/contract/index.d.ts +58 -0
- package/dist/iam/contract/index.d.ts.map +1 -1
- package/dist/iam/contract/index.js +30 -4
- package/dist/iam/contract/index.js.map +1 -1
- package/dist/iam/plugin.d.ts +137 -1
- package/dist/iam/plugin.d.ts.map +1 -1
- package/dist/iam/plugin.js +13 -7
- package/dist/iam/plugin.js.map +1 -1
- package/dist/iam/router/index.d.ts +37 -0
- package/dist/iam/router/index.d.ts.map +1 -1
- package/dist/iam/router/index.js +7 -1
- package/dist/iam/router/index.js.map +1 -1
- package/dist/iam/seed/data/default-admin-roles.d.ts.map +1 -1
- package/dist/iam/seed/data/default-admin-roles.js +3 -0
- package/dist/iam/seed/data/default-admin-roles.js.map +1 -1
- package/dist/iam/seed/seed-default-roles.d.ts.map +1 -1
- package/dist/iam/seed/seed-default-roles.js +2 -1
- package/dist/iam/seed/seed-default-roles.js.map +1 -1
- package/dist/iam/service/iam.service.d.ts +40 -31
- package/dist/iam/service/iam.service.d.ts.map +1 -1
- package/dist/iam/service/iam.service.js +166 -43
- package/dist/iam/service/iam.service.js.map +1 -1
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.js +217 -0
- package/dist/pam/identity/__tests__/admin-user-directory.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js +194 -0
- package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js +94 -0
- package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.js +551 -0
- package/dist/pam/identity/__tests__/identity.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js +99 -0
- package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.js +371 -0
- package/dist/pam/identity/__tests__/phone-login.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.js +30 -0
- package/dist/pam/identity/__tests__/play-eligibility.test.js.map +1 -0
- package/dist/pam/identity/__tests__/rg-guard.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/rg-guard.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/rg-guard.test.js +21 -0
- package/dist/pam/identity/__tests__/rg-guard.test.js.map +1 -0
- package/dist/pam/identity/__tests__/session.service.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/session.service.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/session.service.int.test.js +85 -0
- package/dist/pam/identity/__tests__/session.service.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.js +39 -0
- package/dist/pam/identity/__tests__/user-commands.int.test.js.map +1 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts +2 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts.map +1 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.js +103 -0
- package/dist/pam/identity/__tests__/username-backfill.int.test.js.map +1 -0
- package/dist/pam/identity/adapters/__tests__/default-email-template-renderer.test.d.ts +2 -0
- package/dist/pam/identity/adapters/__tests__/default-email-template-renderer.test.d.ts.map +1 -0
- package/dist/pam/identity/adapters/__tests__/default-email-template-renderer.test.js +25 -0
- package/dist/pam/identity/adapters/__tests__/default-email-template-renderer.test.js.map +1 -0
- package/dist/pam/identity/adapters/default-email-template-renderer.d.ts +8 -0
- package/dist/pam/identity/adapters/default-email-template-renderer.d.ts.map +1 -0
- package/dist/pam/identity/adapters/default-email-template-renderer.js +7 -0
- package/dist/pam/identity/adapters/default-email-template-renderer.js.map +1 -0
- package/dist/pam/identity/adapters/identity-reader.service.d.ts +8 -4
- package/dist/pam/identity/adapters/identity-reader.service.d.ts.map +1 -1
- package/dist/pam/identity/adapters/identity-reader.service.js +53 -2
- package/dist/pam/identity/adapters/identity-reader.service.js.map +1 -1
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts +8 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts.map +1 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.js +7 -0
- package/dist/pam/identity/adapters/mock/mock-sms-adapter.js.map +1 -0
- package/dist/pam/identity/admin-user-directory.d.ts +36 -8
- package/dist/pam/identity/admin-user-directory.d.ts.map +1 -1
- package/dist/pam/identity/admin-user-directory.js +103 -41
- package/dist/pam/identity/admin-user-directory.js.map +1 -1
- package/dist/pam/identity/contract/index.d.ts +128 -12
- package/dist/pam/identity/contract/index.d.ts.map +1 -1
- package/dist/pam/identity/contract/index.js +54 -6
- package/dist/pam/identity/contract/index.js.map +1 -1
- package/dist/pam/identity/drizzle/migrations/0001_rainy_peter_quill.sql +18 -0
- package/dist/pam/identity/drizzle/migrations/0002_outstanding_patriot.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0003_open_shotgun.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0004_round_giant_girl.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0005_daily_black_tom.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0006_brave_sabra.sql +1 -0
- package/dist/pam/identity/drizzle/migrations/0007_fuzzy_barracuda.sql +44 -0
- package/dist/pam/identity/drizzle/migrations/meta/0001_snapshot.json +684 -0
- package/dist/pam/identity/drizzle/migrations/meta/0002_snapshot.json +690 -0
- package/dist/pam/identity/drizzle/migrations/meta/0003_snapshot.json +695 -0
- package/dist/pam/identity/drizzle/migrations/meta/0004_snapshot.json +680 -0
- package/dist/pam/identity/drizzle/migrations/meta/0005_snapshot.json +695 -0
- package/dist/pam/identity/drizzle/migrations/meta/0006_snapshot.json +701 -0
- package/dist/pam/identity/drizzle/migrations/meta/0007_snapshot.json +737 -0
- package/dist/pam/identity/drizzle/migrations/meta/_journal.json +49 -0
- package/dist/pam/identity/plugin.d.ts +136 -1
- package/dist/pam/identity/plugin.d.ts.map +1 -1
- package/dist/pam/identity/plugin.js +43 -7
- package/dist/pam/identity/plugin.js.map +1 -1
- package/dist/pam/identity/react/account.d.ts +20 -8
- package/dist/pam/identity/react/account.d.ts.map +1 -1
- package/dist/pam/identity/react/account.js +13 -1
- package/dist/pam/identity/react/account.js.map +1 -1
- package/dist/pam/identity/react/auth.d.ts +17 -13
- package/dist/pam/identity/react/auth.d.ts.map +1 -1
- package/dist/pam/identity/router/index.d.ts +117 -13
- package/dist/pam/identity/router/index.d.ts.map +1 -1
- package/dist/pam/identity/router/index.js +65 -9
- package/dist/pam/identity/router/index.js.map +1 -1
- package/dist/pam/identity/schema/index.d.ts +246 -0
- package/dist/pam/identity/schema/index.d.ts.map +1 -1
- package/dist/pam/identity/schema/index.js +32 -2
- package/dist/pam/identity/schema/index.js.map +1 -1
- package/dist/pam/identity/service/identity.service.d.ts +80 -30
- package/dist/pam/identity/service/identity.service.d.ts.map +1 -1
- package/dist/pam/identity/service/identity.service.js +621 -105
- package/dist/pam/identity/service/identity.service.js.map +1 -1
- package/dist/pam/identity/service/lockout-policy.service.d.ts +30 -0
- package/dist/pam/identity/service/lockout-policy.service.d.ts.map +1 -0
- package/dist/pam/identity/service/lockout-policy.service.js +40 -0
- package/dist/pam/identity/service/lockout-policy.service.js.map +1 -0
- package/dist/pam/identity/service/login-enforcement.service.d.ts +3 -3
- package/dist/pam/identity/service/login-enforcement.service.d.ts.map +1 -1
- package/dist/pam/identity/service/login-enforcement.service.js.map +1 -1
- package/dist/pam/identity/service/phone-login.service.d.ts +62 -0
- package/dist/pam/identity/service/phone-login.service.d.ts.map +1 -0
- package/dist/pam/identity/service/phone-login.service.js +401 -0
- package/dist/pam/identity/service/phone-login.service.js.map +1 -0
- package/dist/pam/identity/service/play-eligibility.service.d.ts +8 -0
- package/dist/pam/identity/service/play-eligibility.service.d.ts.map +1 -0
- package/dist/pam/identity/service/play-eligibility.service.js +21 -0
- package/dist/pam/identity/service/play-eligibility.service.js.map +1 -0
- package/dist/pam/identity/service/rg-guard.service.d.ts +5 -0
- package/dist/pam/identity/service/rg-guard.service.d.ts.map +1 -0
- package/dist/pam/identity/service/rg-guard.service.js +4 -0
- package/dist/pam/identity/service/rg-guard.service.js.map +1 -0
- package/dist/pam/identity/service/session.service.d.ts +15 -4
- package/dist/pam/identity/service/session.service.d.ts.map +1 -1
- package/dist/pam/identity/service/session.service.js +38 -15
- package/dist/pam/identity/service/session.service.js.map +1 -1
- package/dist/pam/identity/service/user-commands.service.d.ts +11 -0
- package/dist/pam/identity/service/user-commands.service.d.ts.map +1 -0
- package/dist/pam/identity/service/user-commands.service.js +32 -0
- package/dist/pam/identity/service/user-commands.service.js.map +1 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js +89 -0
- package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js.map +1 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.js +107 -0
- package/dist/pam/player-management/__tests__/player.router.int.test.js.map +1 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.d.ts +2 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.d.ts.map +1 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.js +429 -0
- package/dist/pam/player-management/__tests__/player.service.int.test.js.map +1 -0
- package/dist/pam/player-management/contract/index.d.ts +105 -25
- package/dist/pam/player-management/contract/index.d.ts.map +1 -1
- package/dist/pam/player-management/contract/index.js +35 -5
- package/dist/pam/player-management/contract/index.js.map +1 -1
- package/dist/pam/player-management/plugin.d.ts +137 -1
- package/dist/pam/player-management/plugin.d.ts.map +1 -1
- package/dist/pam/player-management/plugin.js +10 -7
- package/dist/pam/player-management/plugin.js.map +1 -1
- package/dist/pam/player-management/router/index.d.ts +79 -23
- package/dist/pam/player-management/router/index.d.ts.map +1 -1
- package/dist/pam/player-management/router/index.js +54 -17
- package/dist/pam/player-management/router/index.js.map +1 -1
- package/dist/pam/player-management/service/kyc-status-writer.d.ts +3 -2
- package/dist/pam/player-management/service/kyc-status-writer.d.ts.map +1 -1
- package/dist/pam/player-management/service/kyc-status-writer.js +26 -10
- package/dist/pam/player-management/service/kyc-status-writer.js.map +1 -1
- package/dist/pam/player-management/service/player.service.d.ts +45 -34
- package/dist/pam/player-management/service/player.service.d.ts.map +1 -1
- package/dist/pam/player-management/service/player.service.js +139 -50
- package/dist/pam/player-management/service/player.service.js.map +1 -1
- package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts +2 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts.map +1 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.js +52 -0
- package/dist/pam/player-note/__tests__/player-note.router.int.test.js.map +1 -0
- package/dist/pam/player-note/contract/index.d.ts +14 -0
- package/dist/pam/player-note/contract/index.d.ts.map +1 -1
- package/dist/pam/player-note/contract/index.js +8 -2
- package/dist/pam/player-note/contract/index.js.map +1 -1
- package/dist/pam/player-note/plugin.d.ts +137 -1
- package/dist/pam/player-note/plugin.d.ts.map +1 -1
- package/dist/pam/player-note/plugin.js +6 -4
- package/dist/pam/player-note/plugin.js.map +1 -1
- package/dist/pam/player-note/router/index.d.ts +10 -1
- package/dist/pam/player-note/router/index.d.ts.map +1 -1
- package/dist/pam/player-note/router/index.js +20 -3
- package/dist/pam/player-note/router/index.js.map +1 -1
- package/dist/pam/player-note/schema/index.d.ts +4 -4
- package/dist/pam/player-note/schema/index.js +6 -6
- package/dist/pam/player-note/schema/index.js.map +1 -1
- package/dist/pam/player-note/service/player-note.service.d.ts +13 -3
- package/dist/pam/player-note/service/player-note.service.d.ts.map +1 -1
- package/dist/pam/player-note/service/player-note.service.js +6 -4
- package/dist/pam/player-note/service/player-note.service.js.map +1 -1
- package/dist/pam/profile/__tests__/profile.service.int.test.d.ts +2 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.d.ts.map +1 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.js +88 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.js.map +1 -0
- package/dist/pam/profile/contract/index.d.ts +8 -7
- package/dist/pam/profile/contract/index.d.ts.map +1 -1
- package/dist/pam/profile/drizzle/migrations/0001_powerful_tiger_shark.sql +1 -0
- package/dist/pam/profile/drizzle/migrations/0002_sour_alex_wilder.sql +7 -0
- package/dist/pam/profile/drizzle/migrations/meta/0001_snapshot.json +191 -0
- package/dist/pam/profile/drizzle/migrations/meta/0002_snapshot.json +200 -0
- package/dist/pam/profile/drizzle/migrations/meta/_journal.json +14 -0
- package/dist/pam/profile/migrate.d.ts.map +1 -1
- package/dist/pam/profile/migrate.js +3 -1
- package/dist/pam/profile/migrate.js.map +1 -1
- package/dist/pam/profile/plugin.d.ts +136 -1
- package/dist/pam/profile/plugin.d.ts.map +1 -1
- package/dist/pam/profile/plugin.js +7 -4
- package/dist/pam/profile/plugin.js.map +1 -1
- package/dist/pam/profile/react/profile.d.ts +10 -12
- package/dist/pam/profile/react/profile.d.ts.map +1 -1
- package/dist/pam/profile/react/profile.js.map +1 -1
- package/dist/pam/profile/router/index.d.ts +8 -7
- package/dist/pam/profile/router/index.d.ts.map +1 -1
- package/dist/pam/profile/schema/index.d.ts +88 -20
- package/dist/pam/profile/schema/index.d.ts.map +1 -1
- package/dist/pam/profile/schema/index.js +6 -9
- package/dist/pam/profile/schema/index.js.map +1 -1
- package/dist/pam/profile/service/profile.service.d.ts +24 -10
- package/dist/pam/profile/service/profile.service.d.ts.map +1 -1
- package/dist/pam/profile/service/profile.service.js +28 -17
- package/dist/pam/profile/service/profile.service.js.map +1 -1
- package/dist/pam/react.d.ts +1 -1
- package/dist/pam/react.d.ts.map +1 -1
- package/dist/pam/react.js +1 -1
- package/dist/pam/react.js.map +1 -1
- package/dist/pam/shared/__tests__/shared-mappers.test.d.ts +2 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.d.ts.map +1 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.js +55 -0
- package/dist/pam/shared/__tests__/shared-mappers.test.js.map +1 -0
- package/dist/pam/shared/headers-mapper.d.ts.map +1 -1
- package/dist/pam/shared/headers-mapper.js +2 -1
- package/dist/pam/shared/headers-mapper.js.map +1 -1
- package/dist/pam/shared/player-mapper.d.ts +22 -3
- package/dist/pam/shared/player-mapper.d.ts.map +1 -1
- package/dist/pam/shared/player-mapper.js +8 -7
- package/dist/pam/shared/player-mapper.js.map +1 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js +77 -0
- package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js +980 -0
- package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag-mappers.test.js +31 -6
- package/dist/pam/tag/__tests__/tag-mappers.test.js.map +1 -1
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.js +145 -0
- package/dist/pam/tag/__tests__/tag-rule.service.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.js +222 -0
- package/dist/pam/tag/__tests__/tag.router.int.test.js.map +1 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.d.ts +2 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.d.ts.map +1 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.js +571 -0
- package/dist/pam/tag/__tests__/tag.service.int.test.js.map +1 -0
- package/dist/pam/tag/contract/index.d.ts +142 -4
- package/dist/pam/tag/contract/index.d.ts.map +1 -1
- package/dist/pam/tag/contract/index.js +12 -2
- package/dist/pam/tag/contract/index.js.map +1 -1
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts +37 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts.map +1 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js +20 -0
- package/dist/pam/tag/contract/player-tag-assign-metadata.js.map +1 -0
- package/dist/pam/tag/drizzle/migrations/0001_neat_iron_monger.sql +2 -0
- package/dist/pam/tag/drizzle/migrations/0002_silent_skaar.sql +4 -0
- package/dist/pam/tag/drizzle/migrations/0003_overconfident_guardian.sql +3 -0
- package/dist/pam/tag/drizzle/migrations/0004_curvy_wither.sql +2 -0
- package/dist/pam/tag/drizzle/migrations/meta/0001_snapshot.json +295 -0
- package/dist/pam/tag/drizzle/migrations/meta/0002_snapshot.json +335 -0
- package/dist/pam/tag/drizzle/migrations/meta/0003_snapshot.json +343 -0
- package/dist/pam/tag/drizzle/migrations/meta/0004_snapshot.json +345 -0
- package/dist/pam/tag/drizzle/migrations/meta/_journal.json +28 -0
- package/dist/pam/tag/migrate.d.ts.map +1 -1
- package/dist/pam/tag/migrate.js +34 -0
- package/dist/pam/tag/migrate.js.map +1 -1
- package/dist/pam/tag/plugin.d.ts +137 -1
- package/dist/pam/tag/plugin.d.ts.map +1 -1
- package/dist/pam/tag/plugin.js +46 -19
- package/dist/pam/tag/plugin.js.map +1 -1
- package/dist/pam/tag/router/index.d.ts +117 -4
- package/dist/pam/tag/router/index.d.ts.map +1 -1
- package/dist/pam/tag/router/index.js +38 -9
- package/dist/pam/tag/router/index.js.map +1 -1
- package/dist/pam/tag/schema/index.d.ts +58 -19
- package/dist/pam/tag/schema/index.d.ts.map +1 -1
- package/dist/pam/tag/schema/index.js +32 -21
- package/dist/pam/tag/schema/index.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tag-rules.js +48 -6
- package/dist/pam/tag/seed/data/default-tag-rules.js.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.d.ts.map +1 -1
- package/dist/pam/tag/seed/data/default-tags.js +6 -0
- package/dist/pam/tag/seed/data/default-tags.js.map +1 -1
- package/dist/pam/tag/seed/seed-default-tag-rules.d.ts.map +1 -1
- package/dist/pam/tag/seed/seed-default-tag-rules.js +5 -3
- package/dist/pam/tag/seed/seed-default-tag-rules.js.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.d.ts +141 -17
- package/dist/pam/tag/service/tag-evaluation.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-evaluation.service.js +501 -62
- package/dist/pam/tag/service/tag-evaluation.service.js.map +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts +8 -2
- package/dist/pam/tag/service/tag-mappers.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-mappers.js +4 -8
- package/dist/pam/tag/service/tag-mappers.js.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.d.ts +34 -4
- package/dist/pam/tag/service/tag-rule.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.js +17 -17
- package/dist/pam/tag/service/tag-rule.service.js.map +1 -1
- package/dist/pam/tag/service/tag.service.d.ts +188 -11
- package/dist/pam/tag/service/tag.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag.service.js +302 -40
- package/dist/pam/tag/service/tag.service.js.map +1 -1
- package/dist/react/context/api-client.d.ts.map +1 -1
- package/dist/react/context/api-client.js +14 -7
- package/dist/react/context/api-client.js.map +1 -1
- package/dist/react/context/realtime-client.d.ts +1 -0
- package/dist/react/context/realtime-client.d.ts.map +1 -1
- package/dist/react/context/realtime-client.js.map +1 -1
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts +2 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.d.ts.map +1 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js +153 -0
- package/dist/react/hooks/__tests__/use-event-stream.test.js.map +1 -0
- package/dist/react/hooks/use-event-stream.d.ts +3 -3
- package/dist/react/hooks/use-event-stream.d.ts.map +1 -1
- package/dist/react/hooks/use-event-stream.js +63 -28
- package/dist/react/hooks/use-event-stream.js.map +1 -1
- package/dist/react/hooks/use-paginated-list.js +3 -3
- package/dist/react/hooks/use-paginated-list.js.map +1 -1
- package/dist/server/auth/__tests__/admin-guard.int.test.d.ts +2 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.js +123 -0
- package/dist/server/auth/__tests__/admin-guard.int.test.js.map +1 -0
- package/dist/server/auth/__tests__/auth.test.d.ts +2 -0
- package/dist/server/auth/__tests__/auth.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/auth.test.js +96 -0
- package/dist/server/auth/__tests__/auth.test.js.map +1 -0
- package/dist/server/auth/__tests__/permission-levels.test.d.ts +2 -0
- package/dist/server/auth/__tests__/permission-levels.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/permission-levels.test.js +89 -0
- package/dist/server/auth/__tests__/permission-levels.test.js.map +1 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.d.ts +2 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.js +59 -0
- package/dist/server/auth/__tests__/session-resolver.int.test.js.map +1 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts +2 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.js +59 -0
- package/dist/server/auth/__tests__/sign-session-cookie.test.js.map +1 -0
- package/dist/server/auth/admin-guard.d.ts +23 -10
- package/dist/server/auth/admin-guard.d.ts.map +1 -1
- package/dist/server/auth/admin-guard.js +90 -44
- package/dist/server/auth/admin-guard.js.map +1 -1
- package/dist/server/auth/auth.d.ts +27 -0
- package/dist/server/auth/auth.d.ts.map +1 -1
- package/dist/server/auth/auth.js +70 -16
- package/dist/server/auth/auth.js.map +1 -1
- package/dist/server/auth/index.d.ts +2 -0
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1 -0
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/auth/permission-levels.d.ts.map +1 -1
- package/dist/server/auth/permission-levels.js +12 -6
- package/dist/server/auth/permission-levels.js.map +1 -1
- package/dist/server/auth/permissions.d.ts +108 -0
- package/dist/server/auth/permissions.d.ts.map +1 -1
- package/dist/server/auth/permissions.js +18 -0
- package/dist/server/auth/permissions.js.map +1 -1
- package/dist/server/auth/session-resolver.d.ts +4 -0
- package/dist/server/auth/session-resolver.d.ts.map +1 -1
- package/dist/server/auth/session-resolver.js +9 -2
- package/dist/server/auth/session-resolver.js.map +1 -1
- package/dist/server/auth/sign-session-cookie.d.ts +18 -0
- package/dist/server/auth/sign-session-cookie.d.ts.map +1 -0
- package/dist/server/auth/sign-session-cookie.js +15 -0
- package/dist/server/auth/sign-session-cookie.js.map +1 -0
- package/dist/server/db/__tests__/migrate.test.d.ts +2 -0
- package/dist/server/db/__tests__/migrate.test.d.ts.map +1 -0
- package/dist/server/db/__tests__/migrate.test.js +127 -0
- package/dist/server/db/__tests__/migrate.test.js.map +1 -0
- package/dist/server/db/__tests__/query-helpers.test.js +120 -1
- package/dist/server/db/__tests__/query-helpers.test.js.map +1 -1
- package/dist/server/db/drizzle.d.ts.map +1 -1
- package/dist/server/db/drizzle.js +2 -1
- package/dist/server/db/drizzle.js.map +1 -1
- package/dist/server/db/drizzle.service.d.ts.map +1 -1
- package/dist/server/db/drizzle.service.js +10 -1
- package/dist/server/db/drizzle.service.js.map +1 -1
- package/dist/server/db/index.d.ts +1 -1
- package/dist/server/db/index.d.ts.map +1 -1
- package/dist/server/db/index.js +1 -1
- package/dist/server/db/index.js.map +1 -1
- package/dist/server/db/migrate.d.ts +25 -0
- package/dist/server/db/migrate.d.ts.map +1 -1
- package/dist/server/db/migrate.js +75 -13
- package/dist/server/db/migrate.js.map +1 -1
- package/dist/server/db/outbox/__tests__/relay.int.test.d.ts +2 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.d.ts.map +1 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.js +117 -0
- package/dist/server/db/outbox/__tests__/relay.int.test.js.map +1 -0
- package/dist/server/db/outbox/relay.d.ts +15 -0
- package/dist/server/db/outbox/relay.d.ts.map +1 -1
- package/dist/server/db/outbox/relay.js +21 -14
- package/dist/server/db/outbox/relay.js.map +1 -1
- package/dist/server/db/query-helpers.d.ts +7 -0
- package/dist/server/db/query-helpers.d.ts.map +1 -1
- package/dist/server/db/query-helpers.js +71 -1
- package/dist/server/db/query-helpers.js.map +1 -1
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js +240 -0
- package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/cache.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/cache.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/cache.int.test.js +52 -0
- package/dist/server/kernel/__tests__/cache.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/domain-error.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/domain-error.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/domain-error.test.js +35 -0
- package/dist/server/kernel/__tests__/domain-error.test.js.map +1 -0
- package/dist/server/kernel/__tests__/error-reporter.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/error-reporter.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/error-reporter.test.js +52 -0
- package/dist/server/kernel/__tests__/error-reporter.test.js.map +1 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.js +173 -0
- package/dist/server/kernel/__tests__/event-bus.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/helpers.test.js +26 -0
- package/dist/server/kernel/__tests__/helpers.test.js.map +1 -1
- package/dist/server/kernel/__tests__/logger.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/logger.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/logger.test.js +44 -0
- package/dist/server/kernel/__tests__/logger.test.js.map +1 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.js +54 -0
- package/dist/server/kernel/__tests__/orpc-error-map.test.js.map +1 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.js +112 -0
- package/dist/server/kernel/__tests__/platform-config-loader.test.js.map +1 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.js +41 -0
- package/dist/server/kernel/__tests__/rate-limiter.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/realtime-transport.test.js +24 -4
- package/dist/server/kernel/__tests__/realtime-transport.test.js.map +1 -1
- package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.js +49 -0
- package/dist/server/kernel/__tests__/redis-cache.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js +61 -0
- package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js +172 -0
- package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js.map +1 -0
- package/dist/server/kernel/__tests__/request-context.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/request-context.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/request-context.test.js +64 -0
- package/dist/server/kernel/__tests__/request-context.test.js.map +1 -0
- package/dist/server/kernel/__tests__/router-utils.test.d.ts +2 -0
- package/dist/server/kernel/__tests__/router-utils.test.d.ts.map +1 -0
- package/dist/server/kernel/__tests__/router-utils.test.js +87 -0
- package/dist/server/kernel/__tests__/router-utils.test.js.map +1 -0
- package/dist/server/kernel/bullmq-job-queue.d.ts +12 -0
- package/dist/server/kernel/bullmq-job-queue.d.ts.map +1 -1
- package/dist/server/kernel/bullmq-job-queue.js +48 -8
- package/dist/server/kernel/bullmq-job-queue.js.map +1 -1
- package/dist/server/kernel/cache.d.ts +0 -12
- package/dist/server/kernel/cache.d.ts.map +1 -1
- package/dist/server/kernel/cache.js +6 -54
- package/dist/server/kernel/cache.js.map +1 -1
- package/dist/server/kernel/container.d.ts +17 -6
- package/dist/server/kernel/container.d.ts.map +1 -1
- package/dist/server/kernel/container.js +15 -1
- package/dist/server/kernel/container.js.map +1 -1
- package/dist/server/kernel/error-reporter.d.ts +5 -0
- package/dist/server/kernel/error-reporter.d.ts.map +1 -0
- package/dist/server/kernel/error-reporter.js +20 -0
- package/dist/server/kernel/error-reporter.js.map +1 -0
- package/dist/server/kernel/event-bus.d.ts +2 -9
- package/dist/server/kernel/event-bus.d.ts.map +1 -1
- package/dist/server/kernel/event-bus.js +11 -26
- package/dist/server/kernel/event-bus.js.map +1 -1
- package/dist/server/kernel/event-stream.d.ts.map +1 -1
- package/dist/server/kernel/event-stream.js +21 -5
- package/dist/server/kernel/event-stream.js.map +1 -1
- package/dist/server/kernel/index.d.ts +9 -7
- package/dist/server/kernel/index.d.ts.map +1 -1
- package/dist/server/kernel/index.js +7 -6
- package/dist/server/kernel/index.js.map +1 -1
- package/dist/server/kernel/logger.d.ts +7 -0
- package/dist/server/kernel/logger.d.ts.map +1 -1
- package/dist/server/kernel/logger.js +36 -2
- package/dist/server/kernel/logger.js.map +1 -1
- package/dist/server/kernel/orpc-error-map.d.ts.map +1 -1
- package/dist/server/kernel/orpc-error-map.js +4 -1
- package/dist/server/kernel/orpc-error-map.js.map +1 -1
- package/dist/server/kernel/ownership.d.ts.map +1 -1
- package/dist/server/kernel/ownership.js +2 -1
- package/dist/server/kernel/ownership.js.map +1 -1
- package/dist/server/kernel/platform-config-loader.d.ts.map +1 -1
- package/dist/server/kernel/platform-config-loader.js +34 -16
- package/dist/server/kernel/platform-config-loader.js.map +1 -1
- package/dist/server/kernel/rate-limiter.d.ts +2 -10
- package/dist/server/kernel/rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/rate-limiter.js +4 -35
- package/dist/server/kernel/rate-limiter.js.map +1 -1
- package/dist/server/kernel/realtime-authorizer.d.ts +2 -4
- package/dist/server/kernel/realtime-authorizer.d.ts.map +1 -1
- package/dist/server/kernel/realtime-authorizer.js +3 -2
- package/dist/server/kernel/realtime-authorizer.js.map +1 -1
- package/dist/server/kernel/realtime-transport.d.ts +7 -2
- package/dist/server/kernel/realtime-transport.d.ts.map +1 -1
- package/dist/server/kernel/realtime-transport.js +63 -22
- package/dist/server/kernel/realtime-transport.js.map +1 -1
- package/dist/server/kernel/redis-cache.d.ts +3 -0
- package/dist/server/kernel/redis-cache.d.ts.map +1 -1
- package/dist/server/kernel/redis-cache.js +20 -5
- package/dist/server/kernel/redis-cache.js.map +1 -1
- package/dist/server/kernel/redis-client.d.ts.map +1 -1
- package/dist/server/kernel/redis-client.js +5 -1
- package/dist/server/kernel/redis-client.js.map +1 -1
- package/dist/server/kernel/redis-rate-limiter.d.ts +12 -0
- package/dist/server/kernel/redis-rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/redis-rate-limiter.js +24 -1
- package/dist/server/kernel/redis-rate-limiter.js.map +1 -1
- package/dist/server/kernel/redis-streams-broker.d.ts +65 -0
- package/dist/server/kernel/redis-streams-broker.d.ts.map +1 -0
- package/dist/server/kernel/redis-streams-broker.js +208 -0
- package/dist/server/kernel/redis-streams-broker.js.map +1 -0
- package/dist/server/kernel/request-context.d.ts +4 -0
- package/dist/server/kernel/request-context.d.ts.map +1 -1
- package/dist/server/kernel/request-context.js +4 -0
- package/dist/server/kernel/request-context.js.map +1 -1
- package/dist/server/kernel/router-utils.d.ts +7 -0
- package/dist/server/kernel/router-utils.d.ts.map +1 -1
- package/dist/server/kernel/router-utils.js +31 -2
- package/dist/server/kernel/router-utils.js.map +1 -1
- package/dist/server/kernel/serialize-row.d.ts.map +1 -1
- package/dist/server/kernel/serialize-row.js +4 -2
- package/dist/server/kernel/serialize-row.js.map +1 -1
- package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.js +27 -0
- package/dist/server/plugin-host/__tests__/core-plugins.test.js.map +1 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.js +31 -0
- package/dist/server/plugin-host/__tests__/load-plugins.test.js.map +1 -0
- package/dist/server/plugin-host/__tests__/module-registry.test.js.map +1 -1
- package/dist/server/plugin-host/__tests__/required-ports.test.js +1 -0
- package/dist/server/plugin-host/__tests__/required-ports.test.js.map +1 -1
- package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts +2 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts.map +1 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.js +82 -0
- package/dist/server/plugin-host/__tests__/typed-plugin.test.js.map +1 -0
- package/dist/server/plugin-host/core-plugins.d.ts +16 -0
- package/dist/server/plugin-host/core-plugins.d.ts.map +1 -0
- package/dist/server/plugin-host/core-plugins.js +40 -0
- package/dist/server/plugin-host/core-plugins.js.map +1 -0
- package/dist/server/plugin-host/define-plugin.d.ts +24 -24
- package/dist/server/plugin-host/define-plugin.d.ts.map +1 -1
- package/dist/server/plugin-host/define-plugin.js +1 -3
- package/dist/server/plugin-host/define-plugin.js.map +1 -1
- package/dist/server/plugin-host/index.d.ts +3 -3
- package/dist/server/plugin-host/index.d.ts.map +1 -1
- package/dist/server/plugin-host/index.js +2 -2
- package/dist/server/plugin-host/index.js.map +1 -1
- package/dist/server/plugin-host/load-extensions.d.ts +2 -2
- package/dist/server/plugin-host/load-extensions.js +4 -3
- package/dist/server/plugin-host/load-extensions.js.map +1 -1
- package/dist/server/plugin-host/load-plugins.d.ts +7 -3
- package/dist/server/plugin-host/load-plugins.d.ts.map +1 -1
- package/dist/server/plugin-host/load-plugins.js +14 -4
- package/dist/server/plugin-host/load-plugins.js.map +1 -1
- package/dist/server/plugin-host/module-registry.d.ts +9 -14
- package/dist/server/plugin-host/module-registry.d.ts.map +1 -1
- package/dist/server/plugin-host/module-registry.js +2 -9
- package/dist/server/plugin-host/module-registry.js.map +1 -1
- package/dist/server/plugin-host/service-manifest.d.ts.map +1 -1
- package/dist/server/plugin-host/service-manifest.js +4 -2
- package/dist/server/plugin-host/service-manifest.js.map +1 -1
- package/dist/server/runtime/__tests__/create-app.test.d.ts +2 -0
- package/dist/server/runtime/__tests__/create-app.test.d.ts.map +1 -0
- package/dist/server/runtime/__tests__/create-app.test.js +73 -0
- package/dist/server/runtime/__tests__/create-app.test.js.map +1 -0
- package/dist/server/runtime/assert-durable-seams.d.ts +19 -0
- package/dist/server/runtime/assert-durable-seams.d.ts.map +1 -0
- package/dist/server/runtime/assert-durable-seams.js +32 -0
- package/dist/server/runtime/assert-durable-seams.js.map +1 -0
- package/dist/server/runtime/core-token-catalog.d.ts +136 -0
- package/dist/server/runtime/core-token-catalog.d.ts.map +1 -0
- package/dist/server/runtime/core-token-catalog.js +64 -0
- package/dist/server/runtime/core-token-catalog.js.map +1 -0
- package/dist/server/runtime/create-app.d.ts +20 -14
- package/dist/server/runtime/create-app.d.ts.map +1 -1
- package/dist/server/runtime/create-app.js +132 -68
- package/dist/server/runtime/create-app.js.map +1 -1
- package/dist/server/runtime/index.d.ts +2 -3
- package/dist/server/runtime/index.d.ts.map +1 -1
- package/dist/server/runtime/index.js +0 -2
- package/dist/server/runtime/index.js.map +1 -1
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock.d.ts +49 -15
- package/dist/testing/mock.d.ts.map +1 -1
- package/dist/testing/mock.js +111 -39
- package/dist/testing/mock.js.map +1 -1
- package/dist/testing/real-infra.d.ts +47 -0
- package/dist/testing/real-infra.d.ts.map +1 -0
- package/dist/testing/real-infra.js +125 -0
- package/dist/testing/real-infra.js.map +1 -0
- package/dist/testing/realtime-transport-conformance.d.ts +35 -0
- package/dist/testing/realtime-transport-conformance.d.ts.map +1 -0
- package/dist/testing/realtime-transport-conformance.js +81 -0
- package/dist/testing/realtime-transport-conformance.js.map +1 -0
- package/dist/testing/seed-player.d.ts +88 -0
- package/dist/testing/seed-player.d.ts.map +1 -0
- package/dist/testing/seed-player.js +43 -0
- package/dist/testing/seed-player.js.map +1 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.js +236 -0
- package/dist/wallet/__tests__/admin-reporting.int.test.js.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js +163 -0
- package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.js +444 -0
- package/dist/wallet/__tests__/bonus-rollover.int.test.js.map +1 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js +70 -0
- package/dist/wallet/__tests__/custody-sweep-gate.test.js.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js +246 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/hmac-payment-webhook-verifier.test.d.ts +2 -0
- package/dist/wallet/__tests__/hmac-payment-webhook-verifier.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/hmac-payment-webhook-verifier.test.js +25 -0
- package/dist/wallet/__tests__/hmac-payment-webhook-verifier.test.js.map +1 -0
- package/dist/wallet/__tests__/rail-for.test.d.ts +2 -0
- package/dist/wallet/__tests__/rail-for.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/rail-for.test.js +29 -0
- package/dist/wallet/__tests__/rail-for.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js +49 -0
- package/dist/wallet/__tests__/reconciliation-diff.test.js.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js +395 -0
- package/dist/wallet/__tests__/reconciliation.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/settlement-network.test.d.ts +2 -0
- package/dist/wallet/__tests__/settlement-network.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/settlement-network.test.js +54 -0
- package/dist/wallet/__tests__/settlement-network.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js +244 -0
- package/dist/wallet/__tests__/wallet-asset.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js +136 -0
- package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js +204 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js +775 -0
- package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js +113 -0
- package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.js +194 -0
- package/dist/wallet/__tests__/wallet-commands.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.js +43 -0
- package/dist/wallet/__tests__/wallet-currency-code.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js +128 -0
- package/dist/wallet/__tests__/wallet-custody-routes.router.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js +104 -0
- package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js +309 -0
- package/dist/wallet/__tests__/wallet-webhook.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js +170 -0
- package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.js +117 -0
- package/dist/wallet/__tests__/wallet.rate-limit.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.router.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.router.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.router.int.test.js +103 -0
- package/dist/wallet/__tests__/wallet.router.int.test.js.map +1 -0
- package/dist/wallet/__tests__/wallet.service.int.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet.service.int.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet.service.int.test.js +1355 -0
- package/dist/wallet/__tests__/wallet.service.int.test.js.map +1 -0
- package/dist/wallet/adapters/hmac-payment-webhook-verifier.d.ts +7 -0
- package/dist/wallet/adapters/hmac-payment-webhook-verifier.d.ts.map +1 -0
- package/dist/wallet/adapters/hmac-payment-webhook-verifier.js +30 -0
- package/dist/wallet/adapters/hmac-payment-webhook-verifier.js.map +1 -0
- package/dist/wallet/adapters/mock/mock-payment-adapter.d.ts +2 -2
- package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts +14 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts.map +1 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.js +37 -0
- package/dist/wallet/adapters/wallet-asset-catalog.service.js.map +1 -0
- package/dist/wallet/adapters/wallet-reader.service.d.ts +2 -1
- package/dist/wallet/adapters/wallet-reader.service.d.ts.map +1 -1
- package/dist/wallet/adapters/wallet-reader.service.js +19 -2
- package/dist/wallet/adapters/wallet-reader.service.js.map +1 -1
- package/dist/wallet/admin-reporting.d.ts +7 -7
- package/dist/wallet/admin-reporting.d.ts.map +1 -1
- package/dist/wallet/admin-reporting.js +19 -11
- package/dist/wallet/admin-reporting.js.map +1 -1
- package/dist/wallet/contract/index.d.ts +887 -28
- package/dist/wallet/contract/index.d.ts.map +1 -1
- package/dist/wallet/contract/index.js +418 -20
- package/dist/wallet/contract/index.js.map +1 -1
- package/dist/wallet/drizzle/migrations/0001_redundant_micromacro.sql +4 -0
- package/dist/wallet/drizzle/migrations/0002_aromatic_archangel.sql +20 -0
- package/dist/wallet/drizzle/migrations/0003_certain_ogun.sql +2 -0
- package/dist/wallet/drizzle/migrations/0004_reflective_shriek.sql +2 -0
- package/dist/wallet/drizzle/migrations/0005_gigantic_dust.sql +10 -0
- package/dist/wallet/drizzle/migrations/0006_lush_morg.sql +1 -0
- package/dist/wallet/drizzle/migrations/0007_bouncy_swordsman.sql +17 -0
- package/dist/wallet/drizzle/migrations/0008_gorgeous_colonel_america.sql +1 -0
- package/dist/wallet/drizzle/migrations/0009_smooth_sue_storm.sql +17 -0
- package/dist/wallet/drizzle/migrations/0010_worthless_quasimodo.sql +84 -0
- package/dist/wallet/drizzle/migrations/0011_premium_natasha_romanoff.sql +30 -0
- package/dist/wallet/drizzle/migrations/0012_long_wong.sql +15 -0
- package/dist/wallet/drizzle/migrations/meta/0001_snapshot.json +397 -0
- package/dist/wallet/drizzle/migrations/meta/0002_snapshot.json +513 -0
- package/dist/wallet/drizzle/migrations/meta/0003_snapshot.json +567 -0
- package/dist/wallet/drizzle/migrations/meta/0004_snapshot.json +631 -0
- package/dist/wallet/drizzle/migrations/meta/0006_snapshot.json +638 -0
- package/dist/wallet/drizzle/migrations/meta/0007_snapshot.json +723 -0
- package/dist/wallet/drizzle/migrations/meta/0008_snapshot.json +716 -0
- package/dist/wallet/drizzle/migrations/meta/0009_snapshot.json +895 -0
- package/dist/wallet/drizzle/migrations/meta/0010_snapshot.json +1565 -0
- package/dist/wallet/drizzle/migrations/meta/0011_snapshot.json +1777 -0
- package/dist/wallet/drizzle/migrations/meta/0012_snapshot.json +1907 -0
- package/dist/wallet/drizzle/migrations/meta/_journal.json +84 -0
- package/dist/wallet/index.d.ts.map +1 -1
- package/dist/wallet/index.js +0 -2
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/migrate.d.ts +0 -1
- package/dist/wallet/migrate.d.ts.map +1 -1
- package/dist/wallet/migrate.js +0 -4
- package/dist/wallet/migrate.js.map +1 -1
- package/dist/wallet/plugin.d.ts +137 -1
- package/dist/wallet/plugin.d.ts.map +1 -1
- package/dist/wallet/plugin.js +125 -16
- package/dist/wallet/plugin.js.map +1 -1
- package/dist/wallet/router/index.d.ts +481 -16
- package/dist/wallet/router/index.d.ts.map +1 -1
- package/dist/wallet/router/index.js +207 -21
- package/dist/wallet/router/index.js.map +1 -1
- package/dist/wallet/schema/index.d.ts +2029 -9
- package/dist/wallet/schema/index.d.ts.map +1 -1
- package/dist/wallet/schema/index.js +277 -6
- package/dist/wallet/schema/index.js.map +1 -1
- package/dist/wallet/seed/index.d.ts +3 -0
- package/dist/wallet/seed/index.d.ts.map +1 -0
- package/dist/wallet/seed/index.js +3 -0
- package/dist/wallet/seed/index.js.map +1 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts +11 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts.map +1 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.js +16 -0
- package/dist/wallet/seed/seed-auto-withdrawal-config.js.map +1 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.d.ts +3 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.d.ts.map +1 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.js +8 -0
- package/dist/wallet/seed/seed-bonus-rollover-config.js.map +1 -0
- package/dist/wallet/service/custody-sweep.service.d.ts +77 -0
- package/dist/wallet/service/custody-sweep.service.d.ts.map +1 -0
- package/dist/wallet/service/custody-sweep.service.js +354 -0
- package/dist/wallet/service/custody-sweep.service.js.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts +39 -0
- package/dist/wallet/service/reconciliation-finding.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation-finding.service.js +36 -0
- package/dist/wallet/service/reconciliation-finding.service.js.map +1 -0
- package/dist/wallet/service/reconciliation.service.d.ts +112 -0
- package/dist/wallet/service/reconciliation.service.d.ts.map +1 -0
- package/dist/wallet/service/reconciliation.service.js +509 -0
- package/dist/wallet/service/reconciliation.service.js.map +1 -0
- package/dist/wallet/service/wallet-commands.service.d.ts +11 -2
- package/dist/wallet/service/wallet-commands.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet-commands.service.js +176 -34
- package/dist/wallet/service/wallet-commands.service.js.map +1 -1
- package/dist/wallet/service/wallet.service.d.ts +604 -29
- package/dist/wallet/service/wallet.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet.service.js +1295 -149
- package/dist/wallet/service/wallet.service.js.map +1 -1
- package/generators/src/config.ts +548 -0
- package/generators/src/templates/adapter.hbs +19 -0
- package/generators/src/templates/contract.hbs +19 -0
- package/generators/src/templates/job-worker.hbs +34 -0
- package/generators/src/templates/module/drizzle.config.hbs +22 -0
- package/generators/src/templates/module/index.hbs +5 -0
- package/generators/src/templates/module/migrate.hbs +17 -0
- package/generators/src/templates/module/plugin.hbs +19 -0
- package/generators/src/templates/module/router.hbs +19 -0
- package/generators/src/templates/module/schema.hbs +14 -0
- package/generators/src/templates/module/service.hbs +26 -0
- package/generators/src/templates/plugin.hbs +20 -0
- package/oxlint/oxlintrc.json +19 -3
- package/package.json +128 -16
- package/dist/admin-console/__tests__/backoffice.service.test.d.ts +0 -2
- package/dist/admin-console/__tests__/backoffice.service.test.d.ts.map +0 -1
- package/dist/admin-console/__tests__/backoffice.service.test.js +0 -156
- package/dist/admin-console/__tests__/backoffice.service.test.js.map +0 -1
- package/dist/audit/__tests__/audit.service.test.d.ts +0 -2
- package/dist/audit/__tests__/audit.service.test.d.ts.map +0 -1
- package/dist/audit/__tests__/audit.service.test.js +0 -415
- package/dist/audit/__tests__/audit.service.test.js.map +0 -1
- package/dist/casino/gaming/__tests__/gaming.service.test.d.ts +0 -2
- package/dist/casino/gaming/__tests__/gaming.service.test.d.ts.map +0 -1
- package/dist/casino/gaming/__tests__/gaming.service.test.js +0 -55
- package/dist/casino/gaming/__tests__/gaming.service.test.js.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts +0 -2
- package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.cache.test.js +0 -47
- package/dist/casino/lobby/__tests__/lobby.cache.test.js.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.service.test.d.ts +0 -2
- package/dist/casino/lobby/__tests__/lobby.service.test.d.ts.map +0 -1
- package/dist/casino/lobby/__tests__/lobby.service.test.js +0 -11
- package/dist/casino/lobby/__tests__/lobby.service.test.js.map +0 -1
- package/dist/cms/__tests__/cms.cache.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.cache.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.cache.test.js +0 -87
- package/dist/cms/__tests__/cms.cache.test.js.map +0 -1
- package/dist/cms/__tests__/cms.service.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.service.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.service.test.js +0 -17
- package/dist/cms/__tests__/cms.service.test.js.map +0 -1
- package/dist/compliance/__tests__/compliance.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/compliance.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/compliance.service.test.js +0 -95
- package/dist/compliance/__tests__/compliance.service.test.js.map +0 -1
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts +0 -2
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js +0 -21
- package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js.map +0 -1
- package/dist/compliance/__tests__/kyc.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/kyc.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/kyc.service.test.js +0 -152
- package/dist/compliance/__tests__/kyc.service.test.js.map +0 -1
- package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg-monitoring.service.test.js +0 -99
- package/dist/compliance/__tests__/rg-monitoring.service.test.js.map +0 -1
- package/dist/compliance/__tests__/rg.router.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg.router.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg.router.test.js +0 -65
- package/dist/compliance/__tests__/rg.router.test.js.map +0 -1
- package/dist/compliance/__tests__/rg.service.test.d.ts +0 -2
- package/dist/compliance/__tests__/rg.service.test.d.ts.map +0 -1
- package/dist/compliance/__tests__/rg.service.test.js +0 -206
- package/dist/compliance/__tests__/rg.service.test.js.map +0 -1
- package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts +0 -2
- package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts.map +0 -1
- package/dist/contracts/schemas/__tests__/identity-schemas.test.js +0 -38
- package/dist/contracts/schemas/__tests__/identity-schemas.test.js.map +0 -1
- package/dist/engagement/chat/__tests__/chat.service.test.d.ts +0 -2
- package/dist/engagement/chat/__tests__/chat.service.test.d.ts.map +0 -1
- package/dist/engagement/chat/__tests__/chat.service.test.js +0 -170
- package/dist/engagement/chat/__tests__/chat.service.test.js.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.d.ts +0 -27
- package/dist/engagement/chat/react/use-chat-stream.d.ts.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.js +0 -52
- package/dist/engagement/chat/react/use-chat-stream.js.map +0 -1
- package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts +0 -2
- package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts.map +0 -1
- package/dist/engagement/notifications/__tests__/notifications.service.test.js +0 -83
- package/dist/engagement/notifications/__tests__/notifications.service.test.js.map +0 -1
- package/dist/engagement/react.d.ts +0 -2
- package/dist/engagement/react.d.ts.map +0 -1
- package/dist/engagement/react.js +0 -3
- package/dist/engagement/react.js.map +0 -1
- package/dist/iam/__tests__/iam.service.test.d.ts +0 -2
- package/dist/iam/__tests__/iam.service.test.d.ts.map +0 -1
- package/dist/iam/__tests__/iam.service.test.js +0 -739
- package/dist/iam/__tests__/iam.service.test.js.map +0 -1
- package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/admin-user-directory.test.js +0 -93
- package/dist/pam/identity/__tests__/admin-user-directory.test.js.map +0 -1
- package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/identity.rate-limit.test.js +0 -127
- package/dist/pam/identity/__tests__/identity.rate-limit.test.js.map +0 -1
- package/dist/pam/identity/__tests__/identity.service.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/identity.service.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/identity.service.test.js +0 -292
- package/dist/pam/identity/__tests__/identity.service.test.js.map +0 -1
- package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts +0 -2
- package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts.map +0 -1
- package/dist/pam/identity/__tests__/login-enforcement.service.test.js +0 -41
- package/dist/pam/identity/__tests__/login-enforcement.service.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.js +0 -37
- package/dist/pam/player-management/__tests__/kyc-status-writer.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/player.router.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/player.router.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/player.router.test.js +0 -57
- package/dist/pam/player-management/__tests__/player.router.test.js.map +0 -1
- package/dist/pam/player-management/__tests__/player.service.test.d.ts +0 -2
- package/dist/pam/player-management/__tests__/player.service.test.d.ts.map +0 -1
- package/dist/pam/player-management/__tests__/player.service.test.js +0 -143
- package/dist/pam/player-management/__tests__/player.service.test.js.map +0 -1
- package/dist/pam/profile/__tests__/profile.service.test.d.ts +0 -2
- package/dist/pam/profile/__tests__/profile.service.test.d.ts.map +0 -1
- package/dist/pam/profile/__tests__/profile.service.test.js +0 -47
- package/dist/pam/profile/__tests__/profile.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.js +0 -37
- package/dist/pam/tag/__tests__/get-active-tag-keys.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js +0 -268
- package/dist/pam/tag/__tests__/tag-evaluation.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag-rule.service.test.js +0 -149
- package/dist/pam/tag/__tests__/tag-rule.service.test.js.map +0 -1
- package/dist/pam/tag/__tests__/tag.service.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag.service.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag.service.test.js +0 -262
- package/dist/pam/tag/__tests__/tag.service.test.js.map +0 -1
- package/dist/server/auth/__tests__/admin-guard.test.d.ts +0 -2
- package/dist/server/auth/__tests__/admin-guard.test.d.ts.map +0 -1
- package/dist/server/auth/__tests__/admin-guard.test.js +0 -133
- package/dist/server/auth/__tests__/admin-guard.test.js.map +0 -1
- package/dist/server/auth/__tests__/session-resolver.test.d.ts +0 -2
- package/dist/server/auth/__tests__/session-resolver.test.d.ts.map +0 -1
- package/dist/server/auth/__tests__/session-resolver.test.js +0 -27
- package/dist/server/auth/__tests__/session-resolver.test.js.map +0 -1
- package/dist/server/db/outbox/__tests__/relay.test.d.ts +0 -2
- package/dist/server/db/outbox/__tests__/relay.test.d.ts.map +0 -1
- package/dist/server/db/outbox/__tests__/relay.test.js +0 -122
- package/dist/server/db/outbox/__tests__/relay.test.js.map +0 -1
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.js +0 -190
- package/dist/server/kernel/__tests__/bullmq-job-queue.test.js.map +0 -1
- package/dist/server/kernel/__tests__/cache.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/cache.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/cache.test.js +0 -84
- package/dist/server/kernel/__tests__/cache.test.js.map +0 -1
- package/dist/server/kernel/__tests__/event-bus.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/event-bus.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/event-bus.test.js +0 -113
- package/dist/server/kernel/__tests__/event-bus.test.js.map +0 -1
- package/dist/server/kernel/__tests__/job-queue.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/job-queue.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/job-queue.test.js +0 -132
- package/dist/server/kernel/__tests__/job-queue.test.js.map +0 -1
- package/dist/server/kernel/__tests__/rate-limiter.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/rate-limiter.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/rate-limiter.test.js +0 -69
- package/dist/server/kernel/__tests__/rate-limiter.test.js.map +0 -1
- package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/realtime-authorizer.test.js +0 -19
- package/dist/server/kernel/__tests__/realtime-authorizer.test.js.map +0 -1
- package/dist/server/kernel/__tests__/redis-cache.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/redis-cache.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/redis-cache.test.js +0 -48
- package/dist/server/kernel/__tests__/redis-cache.test.js.map +0 -1
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts +0 -2
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts.map +0 -1
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.js +0 -56
- package/dist/server/kernel/__tests__/redis-rate-limiter.test.js.map +0 -1
- package/dist/server/kernel/job-queue.d.ts +0 -28
- package/dist/server/kernel/job-queue.d.ts.map +0 -1
- package/dist/server/kernel/job-queue.js +0 -177
- package/dist/server/kernel/job-queue.js.map +0 -1
- package/dist/server/runtime/openapi.d.ts +0 -15
- package/dist/server/runtime/openapi.d.ts.map +0 -1
- package/dist/server/runtime/openapi.js +0 -26
- package/dist/server/runtime/openapi.js.map +0 -1
- package/dist/wallet/__tests__/admin-reporting.test.d.ts +0 -2
- package/dist/wallet/__tests__/admin-reporting.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/admin-reporting.test.js +0 -124
- package/dist/wallet/__tests__/admin-reporting.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.js +0 -98
- package/dist/wallet/__tests__/wallet-auto-rule.router.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js +0 -408
- package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-commands.service.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-commands.service.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-commands.service.test.js +0 -159
- package/dist/wallet/__tests__/wallet-commands.service.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet-kyc-gate.test.js +0 -61
- package/dist/wallet/__tests__/wallet-kyc-gate.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.rate-limit.test.js +0 -34
- package/dist/wallet/__tests__/wallet.rate-limit.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.router.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.router.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.router.test.js +0 -43
- package/dist/wallet/__tests__/wallet.router.test.js.map +0 -1
- package/dist/wallet/__tests__/wallet.service.test.d.ts +0 -2
- package/dist/wallet/__tests__/wallet.service.test.d.ts.map +0 -1
- package/dist/wallet/__tests__/wallet.service.test.js +0 -698
- package/dist/wallet/__tests__/wallet.service.test.js.map +0 -1
- package/turbo-generators/src/config.ts +0 -466
- package/turbo-generators/src/templates/adapter.hbs +0 -19
- package/turbo-generators/src/templates/contract.hbs +0 -18
- package/turbo-generators/src/templates/job-worker.hbs +0 -34
- package/turbo-generators/src/templates/module/agents.hbs +0 -67
- package/turbo-generators/src/templates/module/drizzle.config.hbs +0 -22
- package/turbo-generators/src/templates/module/index.hbs +0 -5
- package/turbo-generators/src/templates/module/migrate.hbs +0 -15
- package/turbo-generators/src/templates/module/package.json.hbs +0 -62
- package/turbo-generators/src/templates/module/plugin.hbs +0 -20
- package/turbo-generators/src/templates/module/router.hbs +0 -19
- package/turbo-generators/src/templates/module/schema.hbs +0 -21
- package/turbo-generators/src/templates/module/service.hbs +0 -26
- package/turbo-generators/src/templates/module/tsconfig.json.hbs +0 -8
- package/turbo-generators/src/templates/plugin.hbs +0 -20
- /package/{turbo-generators → generators}/src/templates/adr.hbs +0 -0
- /package/{turbo-generators → generators}/src/templates/config.hbs +0 -0
|
@@ -1,32 +1,182 @@
|
|
|
1
|
-
import { makeNotFoundError, makeConflictError, createDomainError, findOneOrThrow, pageToOffset, withAdvisoryXactLock, assertRateLimit, createLogger, } from '@openora/core/server';
|
|
2
|
-
import {
|
|
1
|
+
import { makeNotFoundError, serializeRow, makeConflictError, createDomainError, findOneOrThrow, pageToOffset, withAdvisoryXactLock, assertRateLimit, createLogger, moneyToNumber, moneyEquals, moneyAdd, moneyCompare, moneySubtract, } from '@openora/core/server';
|
|
2
|
+
import { normalizeKycStatus, DEFAULT_PAYMENT_PROVIDER, } from '@openora/core/contracts';
|
|
3
|
+
import { eq, asc, desc, sql, and, gte, lte, count, inArray, isNull, or } from 'drizzle-orm';
|
|
3
4
|
import { createHash } from 'node:crypto';
|
|
4
|
-
import { wallet, walletTransaction, autoWithdrawalRule, } from '../schema/index.js';
|
|
5
|
+
import { wallet, walletBalance, walletTransaction, autoWithdrawalRule, walletAutoWithdrawalConfig, walletDepositAddress, walletBonusCredit, walletBonusRolloverConfig, walletWithdrawalAddress, walletAsset, } from '../schema/index.js';
|
|
6
|
+
import { LIVE_WEBHOOK_RUN_ID, recordReconciliationFinding, } from './reconciliation-finding.service.js';
|
|
5
7
|
const logger = createLogger('wallet');
|
|
6
8
|
export const WalletNotFoundError = makeNotFoundError('Wallet');
|
|
7
9
|
export const WithdrawalNotFoundError = makeNotFoundError('Withdrawal');
|
|
10
|
+
export const AutoWithdrawalConfigNotFoundError = makeNotFoundError('AutoWithdrawalConfig');
|
|
11
|
+
export const BonusRolloverConfigNotFoundError = makeNotFoundError('BonusRolloverConfig');
|
|
12
|
+
export const PlayerNotFoundError = makeNotFoundError('Player');
|
|
8
13
|
export const InsufficientBalanceError = createDomainError('InsufficientBalanceError', (available, requested) => `Insufficient balance: available ${available}, requested ${requested}`);
|
|
9
14
|
export const WithdrawalNotPendingError = makeConflictError('WithdrawalNotPendingError', 'Withdrawal is not pending and cannot be reviewed');
|
|
10
15
|
export const KycRequiredError = makeConflictError('KycRequiredError', 'KYC verification required before withdrawal');
|
|
11
16
|
export const IdempotencyKeyReuseError = makeConflictError('IdempotencyKeyReuseError', 'Idempotency key was already used with a different amount');
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
17
|
+
export const DepositAddressUnsupportedError = makeConflictError('DepositAddressUnsupportedError', 'The bound payment adapter does not support address-based deposits');
|
|
18
|
+
export const DestinationAddressRequiredError = makeConflictError('DestinationAddressRequiredError', 'A destination address is required for a crypto-rail withdrawal');
|
|
19
|
+
export const BonusRolloverLockedError = createDomainError('BonusRolloverLockedError', (locked) => `Withdrawal blocked: ${locked} is locked by an active bonus rollover requirement`);
|
|
20
|
+
export const DestinationAddressNotWhitelistedError = makeConflictError('DestinationAddressNotWhitelistedError', 'This payout address is not approved for withdrawals. Save it in your address book first');
|
|
21
|
+
export const WalletAssetNotFoundError = makeNotFoundError('WalletAsset');
|
|
22
|
+
export const WalletAssetAlreadyExistsError = makeConflictError('WalletAssetAlreadyExistsError', 'An asset is already configured for this currency and network');
|
|
23
|
+
export const WalletAssetUnsupportedError = makeConflictError('WalletAssetUnsupportedError', 'The bound payment adapter cannot serve this currency and network');
|
|
24
|
+
export const WalletAssetInUseError = makeConflictError('WalletAssetInUseError', 'Players still hold a balance in this currency');
|
|
25
|
+
export const WalletAssetUnknownProviderError = makeConflictError('WalletAssetUnknownProviderError', 'providerName is not a registered payment provider');
|
|
26
|
+
export const WalletAssetHasInFlightTransactionsError = makeConflictError('WalletAssetHasInFlightTransactionsError', 'A pending or processing transaction exists for this currency and network');
|
|
27
|
+
export const WithdrawalAddressAlreadyExistsError = makeConflictError('WithdrawalAddressAlreadyExistsError', 'This address is already saved for that currency and network');
|
|
28
|
+
export const WithdrawalAddressLimitReachedError = createDomainError('WithdrawalAddressLimitReachedError', (limit) => `A player may save at most ${limit} withdrawal addresses`);
|
|
29
|
+
export const AmbiguousNetworkError = createDomainError('AmbiguousNetworkError', (currency, networks) => `Currency ${currency} settles on several networks (${networks}) - a network is required`);
|
|
30
|
+
export const UnsupportedNetworkError = createDomainError('UnsupportedNetworkError', (currency, network) => `Currency ${currency} is not settled on network ${network}`);
|
|
31
|
+
export const WithdrawalDisabledError = createDomainError('WithdrawalDisabledError', (currency) => `Withdrawals are disabled for ${currency} on every configured network`);
|
|
32
|
+
export const BelowMinimumWithdrawalError = createDomainError('BelowMinimumWithdrawalError', (amount, minimum, currency, network) => `Withdrawal of ${amount} ${currency} on ${network} is below the ${minimum} ${currency} minimum`);
|
|
33
|
+
const KYC_PASS_STATUSES = new Set(['approved', 'manually_overridden']);
|
|
34
|
+
export const AmbiguousDepositAddressError = createDomainError('AmbiguousDepositAddressError', (address, network) => `Deposit address ${address} on ${network ?? 'an unknown network'} is issued to more than one user`);
|
|
35
|
+
// Crypto currencies settle on the crypto rail through a custody/MPC vendor; everything
|
|
36
|
+
// else on the fiat rail (a PSP). The concrete provider is recorded per transaction, not
|
|
37
|
+
// here. Overridable per-operator via `platformConfig.wallet.cryptoCurrencies` - see `railFor`.
|
|
38
|
+
const DEFAULT_CRYPTO_CURRENCIES = new Set(['BTC', 'ETH', 'USDT', 'USDC']);
|
|
39
|
+
// A saved-address book, not a payout allowlist: the cap only stops one account turning
|
|
40
|
+
// the table into unbounded free storage. Not operator-configurable until someone asks.
|
|
41
|
+
const WITHDRAWAL_ADDRESS_LIMIT = 50;
|
|
42
|
+
function toWithdrawalAddressDto(row) {
|
|
43
|
+
return {
|
|
44
|
+
id: row.id,
|
|
45
|
+
label: row.label,
|
|
46
|
+
currency: row.currency,
|
|
47
|
+
network: row.network,
|
|
48
|
+
address: row.address,
|
|
49
|
+
createdAt: row.createdAt.toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Mirrors the `wallet.currency` column default: what a player without a wallet row
|
|
53
|
+
// reads as their active currency before one is created on first deposit.
|
|
54
|
+
const DEFAULT_WALLET_CURRENCY = 'USD';
|
|
18
55
|
// Per-user throttle on money mutations - guards a runaway/misbehaving client, not
|
|
19
56
|
// fraud (idempotency + the ledger guard cover correctness). An overlay rebinds
|
|
20
57
|
// RATE_LIMITER to change the backend, not this policy.
|
|
21
58
|
const WALLET_MUTATION_RATE_LIMIT = { limit: 30, windowMs: 60 * 1000 };
|
|
22
|
-
|
|
23
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Pins the chain a payout settles on. With one payable network the choice is implied; with
|
|
61
|
+
* several an explicit network is mandatory, because picking one silently would send a
|
|
62
|
+
* player's USDT over a chain their receiving wallet may not support.
|
|
63
|
+
*
|
|
64
|
+
* `assets` is every catalog row for the currency, enabled or not, so the two empty cases
|
|
65
|
+
* stay distinguishable: no rows at all means the operator never configured this currency
|
|
66
|
+
* (a fiat PSP), and the caller's choice passes through unchecked; rows that are all
|
|
67
|
+
* withdrawal-disabled is a deliberate operator decision and fails closed.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveWithdrawalNetwork(assets, currency, network) {
|
|
70
|
+
if (assets.length === 0) {
|
|
71
|
+
return network?.toUpperCase() ?? null;
|
|
72
|
+
}
|
|
73
|
+
const payable = assets.filter((asset) => asset.withdrawalEnabled);
|
|
74
|
+
const [only, ...rest] = payable;
|
|
75
|
+
if (!only) {
|
|
76
|
+
throw new WithdrawalDisabledError(currency);
|
|
77
|
+
}
|
|
78
|
+
if (network === undefined) {
|
|
79
|
+
if (rest.length > 0) {
|
|
80
|
+
throw new AmbiguousNetworkError(currency, payable.map((asset) => asset.network).join(', '));
|
|
81
|
+
}
|
|
82
|
+
return only.network.toUpperCase();
|
|
83
|
+
}
|
|
84
|
+
const wanted = network.toUpperCase();
|
|
85
|
+
if (!payable.some((asset) => asset.network.toUpperCase() === wanted)) {
|
|
86
|
+
throw new UnsupportedNetworkError(currency, wanted);
|
|
87
|
+
}
|
|
88
|
+
return wanted;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Rejects a payout worth less than the operator's per-network floor. The floor is per chain,
|
|
92
|
+
* not per currency: moving USDT costs cents on BEP20 and dollars on ERC20, so one
|
|
93
|
+
* currency-wide minimum is either too high for the cheap chain or below the fee on the
|
|
94
|
+
* expensive one.
|
|
95
|
+
*/
|
|
96
|
+
export function assertAboveMinimumWithdrawal(assets, amount, currency, network) {
|
|
97
|
+
const asset = assets.find((candidate) => candidate.withdrawalEnabled && candidate.network.toUpperCase() === network);
|
|
98
|
+
if (asset && moneyCompare(amount, asset.minWithdrawal) < 0) {
|
|
99
|
+
throw new BelowMinimumWithdrawalError(amount, asset.minWithdrawal, currency, asset.network);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function railFor(currency, cryptoCurrencies) {
|
|
103
|
+
const set = cryptoCurrencies
|
|
104
|
+
? new Set(cryptoCurrencies.map((c) => c.toUpperCase()))
|
|
105
|
+
: DEFAULT_CRYPTO_CURRENCIES;
|
|
106
|
+
return set.has(currency.toUpperCase()) ? 'crypto' : 'fiat';
|
|
107
|
+
}
|
|
108
|
+
// Currency checks elsewhere are case-insensitive, so `usd` reaches here for a `USD`
|
|
109
|
+
// wallet. Every read and write of wallet_balance funnels through these three helpers,
|
|
110
|
+
// so normalizing the key here is enough to keep one row per wallet+currency.
|
|
111
|
+
export const balanceKey = (currency) => currency.toUpperCase();
|
|
112
|
+
export function creditWalletBalance(txn, walletId, currency, amount) {
|
|
113
|
+
return txn
|
|
114
|
+
.insert(walletBalance)
|
|
115
|
+
.values({ walletId, currency: balanceKey(currency), amount })
|
|
116
|
+
.onConflictDoUpdate({
|
|
117
|
+
target: [walletBalance.walletId, walletBalance.currency],
|
|
118
|
+
set: {
|
|
119
|
+
amount: sql `${walletBalance.amount} + ${amount}::numeric`,
|
|
120
|
+
updatedAt: new Date(),
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
.returning({ amount: walletBalance.amount });
|
|
124
|
+
}
|
|
125
|
+
export function debitWalletBalance(txn, walletId, currency, amount) {
|
|
126
|
+
return txn
|
|
127
|
+
.update(walletBalance)
|
|
128
|
+
.set({ amount: sql `${walletBalance.amount} - ${amount}::numeric` })
|
|
129
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, balanceKey(currency)), gte(walletBalance.amount, amount)))
|
|
130
|
+
.returning({ amount: walletBalance.amount });
|
|
131
|
+
}
|
|
132
|
+
export async function readWalletBalance(txn, walletId, currency) {
|
|
133
|
+
const [row] = await txn
|
|
134
|
+
.select({ amount: walletBalance.amount })
|
|
135
|
+
.from(walletBalance)
|
|
136
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, balanceKey(currency))));
|
|
137
|
+
return row?.amount ?? '0';
|
|
138
|
+
}
|
|
139
|
+
export function debitWithdrawableBalance(txn, walletId, currency, amount) {
|
|
140
|
+
const currencyKey = balanceKey(currency);
|
|
141
|
+
return txn
|
|
142
|
+
.update(walletBalance)
|
|
143
|
+
.set({ amount: sql `${walletBalance.amount} - ${amount}::numeric` })
|
|
144
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, currencyKey), gte(sql `${walletBalance.amount} - COALESCE((
|
|
145
|
+
SELECT SUM(
|
|
146
|
+
${walletBonusCredit.creditedAmount}
|
|
147
|
+
* GREATEST(
|
|
148
|
+
${walletBonusCredit.rolloverRequired} - ${walletBonusCredit.rolloverProgress},
|
|
149
|
+
0
|
|
150
|
+
)
|
|
151
|
+
/ NULLIF(${walletBonusCredit.rolloverRequired}, 0)
|
|
152
|
+
)
|
|
153
|
+
FROM ${walletBonusCredit}
|
|
154
|
+
WHERE ${walletBonusCredit.walletId} = ${walletId}
|
|
155
|
+
AND ${walletBonusCredit.currency} = ${currencyKey}
|
|
156
|
+
AND ${walletBonusCredit.status} = 'active'
|
|
157
|
+
), 0)`, amount)))
|
|
158
|
+
.returning({ amount: walletBalance.amount });
|
|
159
|
+
}
|
|
160
|
+
async function readLockedBonusAmount(txn, walletId, currency) {
|
|
161
|
+
const currencyKey = balanceKey(currency);
|
|
162
|
+
const [row] = await txn
|
|
163
|
+
.select({
|
|
164
|
+
locked: sql `coalesce(sum(
|
|
165
|
+
${walletBonusCredit.creditedAmount}
|
|
166
|
+
* greatest(${walletBonusCredit.rolloverRequired} - ${walletBonusCredit.rolloverProgress}, 0)
|
|
167
|
+
/ nullif(${walletBonusCredit.rolloverRequired}, 0)
|
|
168
|
+
), 0)`,
|
|
169
|
+
})
|
|
170
|
+
.from(walletBonusCredit)
|
|
171
|
+
.where(and(eq(walletBonusCredit.walletId, walletId), eq(walletBonusCredit.currency, currencyKey), eq(walletBonusCredit.status, 'active')));
|
|
172
|
+
return row?.locked ?? '0';
|
|
24
173
|
}
|
|
25
174
|
// Namespace the key per operation so the same raw key on a deposit then a withdraw can't
|
|
26
175
|
// collide on the (walletId, idempotencyKey) unique index. The column is a uuid, so a string
|
|
27
176
|
// prefix won't parse - hash namespace + key into a stable pseudo-uuid instead.
|
|
28
177
|
const DEPOSIT_IDEMPOTENCY_NAMESPACE = 'deposit';
|
|
29
178
|
const WITHDRAW_IDEMPOTENCY_NAMESPACE = 'withdraw';
|
|
179
|
+
const MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE = 'manual-adjustment';
|
|
30
180
|
function namespacedIdempotencyKey(namespace, rawKey) {
|
|
31
181
|
const hex = createHash('sha256').update(`${namespace}:${rawKey}`).digest('hex');
|
|
32
182
|
return [
|
|
@@ -39,72 +189,201 @@ function namespacedIdempotencyKey(namespace, rawKey) {
|
|
|
39
189
|
}
|
|
40
190
|
// ponytail: a flat, currency-agnostic threshold - a starter heuristic for the review
|
|
41
191
|
// queue, not a compliance risk engine. Revisit with a real risk service if/when one exists.
|
|
42
|
-
|
|
192
|
+
// moneyToNumber is the sanctioned JS conversion point for this heuristic comparison only.
|
|
193
|
+
const LARGE_WITHDRAWAL_THRESHOLD = '5000';
|
|
43
194
|
// ponytail: >=3 withdrawals in a 24h window flags velocity; a flat count, not a per-tier rule.
|
|
44
195
|
const HIGH_FREQUENCY_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
45
196
|
const HIGH_FREQUENCY_MIN_COUNT = 3;
|
|
46
197
|
const DAILY_CAP_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
47
198
|
// Also the marker the cumulative-cap query reads back to identify auto-approved payouts - keep write and read in lockstep.
|
|
48
199
|
const AUTO_APPROVED_REASON = 'auto-approved';
|
|
200
|
+
function toDepositAddressResult(row) {
|
|
201
|
+
return {
|
|
202
|
+
address: row.address,
|
|
203
|
+
currency: row.currency,
|
|
204
|
+
...(row.network === null ? {} : { network: row.network }),
|
|
205
|
+
...(row.tag === null ? {} : { tag: row.tag }),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
49
208
|
function toAutoWithdrawalRuleDto(row) {
|
|
50
209
|
return {
|
|
51
210
|
id: row.id,
|
|
52
211
|
userId: row.userId,
|
|
53
|
-
threshold:
|
|
212
|
+
threshold: row.threshold,
|
|
54
213
|
reason: row.reason,
|
|
55
214
|
createdBy: row.createdBy,
|
|
56
215
|
createdAt: row.createdAt.toISOString(),
|
|
57
216
|
updatedAt: row.updatedAt.toISOString(),
|
|
58
217
|
};
|
|
59
218
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
219
|
+
function toAutoWithdrawalConfigDto(row) {
|
|
220
|
+
return {
|
|
221
|
+
id: row.id,
|
|
222
|
+
fiatThreshold: row.fiatThreshold,
|
|
223
|
+
cryptoThreshold: row.cryptoThreshold,
|
|
224
|
+
excludeRiskFlags: row.excludeRiskFlags,
|
|
225
|
+
updatedBy: row.updatedBy,
|
|
226
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
227
|
+
createdAt: row.createdAt.toISOString(),
|
|
228
|
+
};
|
|
64
229
|
}
|
|
230
|
+
function toBonusCreditDto(row) {
|
|
231
|
+
return {
|
|
232
|
+
id: row.id,
|
|
233
|
+
currency: row.currency,
|
|
234
|
+
sourceType: row.sourceType,
|
|
235
|
+
creditedAmount: row.creditedAmount,
|
|
236
|
+
rolloverMultiplier: row.rolloverMultiplier,
|
|
237
|
+
rolloverRequired: row.rolloverRequired,
|
|
238
|
+
rolloverProgress: row.rolloverProgress,
|
|
239
|
+
status: row.status,
|
|
240
|
+
createdAt: row.createdAt.toISOString(),
|
|
241
|
+
completedAt: row.completedAt ? row.completedAt.toISOString() : null,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function toBonusRolloverConfigDto(row) {
|
|
245
|
+
return {
|
|
246
|
+
id: row.id,
|
|
247
|
+
multiplier: row.multiplier,
|
|
248
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const PUBLIC_ASSET_COLUMNS = {
|
|
252
|
+
currency: walletAsset.currency,
|
|
253
|
+
network: walletAsset.network,
|
|
254
|
+
minDeposit: walletAsset.minDeposit,
|
|
255
|
+
minWithdrawal: walletAsset.minWithdrawal,
|
|
256
|
+
withdrawalFee: walletAsset.withdrawalFee,
|
|
257
|
+
depositEnabled: walletAsset.depositEnabled,
|
|
258
|
+
withdrawalEnabled: walletAsset.withdrawalEnabled,
|
|
259
|
+
};
|
|
260
|
+
function toWalletAssetDto(row) {
|
|
261
|
+
return serializeRow(row, { dateFields: ['createdAt', 'updatedAt'], decimalFields: [] });
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Owns all wallet balance mutations and the withdrawal review/auto-approval
|
|
265
|
+
* pipeline. Every balance change is a transactional, idempotent-keyed ledger
|
|
266
|
+
* write (never a bare balance update) - `amount` is always a decimal string,
|
|
267
|
+
* mutated via SQL numeric arithmetic, never a JS float. Domain events emit only
|
|
268
|
+
* AFTER the owning transaction commits, and only for the non-replay branch of
|
|
269
|
+
* an idempotent call.
|
|
270
|
+
*/
|
|
65
271
|
export class WalletService {
|
|
66
272
|
drizzle;
|
|
67
273
|
events;
|
|
68
274
|
payment;
|
|
275
|
+
paymentProviders;
|
|
276
|
+
identityReader;
|
|
69
277
|
directory;
|
|
70
278
|
platformConfig;
|
|
71
279
|
limiter;
|
|
72
280
|
riskTags;
|
|
281
|
+
tagEvaluationCommands;
|
|
73
282
|
audit;
|
|
74
|
-
constructor({ drizzle, events, payment, directory, platformConfig, limiter, riskTags, audit, }) {
|
|
283
|
+
constructor({ drizzle, events, payment, paymentProviders, directory, identityReader, platformConfig, limiter, riskTags, tagEvaluationCommands, audit, }) {
|
|
75
284
|
this.drizzle = drizzle;
|
|
76
285
|
this.events = events;
|
|
77
286
|
this.payment = payment;
|
|
287
|
+
this.paymentProviders = paymentProviders;
|
|
78
288
|
this.directory = directory;
|
|
289
|
+
this.identityReader = identityReader;
|
|
79
290
|
this.platformConfig = platformConfig;
|
|
80
291
|
this.limiter = limiter;
|
|
81
292
|
this.riskTags = riskTags;
|
|
293
|
+
this.tagEvaluationCommands = tagEvaluationCommands;
|
|
82
294
|
this.audit = audit;
|
|
83
295
|
}
|
|
296
|
+
// Every catalog row for the currency, enabled or not - resolveWithdrawalNetwork needs
|
|
297
|
+
// both to tell "never configured" from "deliberately disabled".
|
|
298
|
+
assetsForCurrency(currency) {
|
|
299
|
+
return this.drizzle.db
|
|
300
|
+
.select({
|
|
301
|
+
network: walletAsset.network,
|
|
302
|
+
minWithdrawal: walletAsset.minWithdrawal,
|
|
303
|
+
withdrawalEnabled: walletAsset.withdrawalEnabled,
|
|
304
|
+
})
|
|
305
|
+
.from(walletAsset)
|
|
306
|
+
.where(eq(walletAsset.currency, currency.toUpperCase()));
|
|
307
|
+
}
|
|
308
|
+
resolveRail(currency) {
|
|
309
|
+
return railFor(currency, this.platformConfig?.wallet?.cryptoCurrencies);
|
|
310
|
+
}
|
|
311
|
+
// The concrete vendor a transaction/deposit-address settles through: the catalog row
|
|
312
|
+
// for the exact (currency, network) pair names the bound provider. Reconciliation
|
|
313
|
+
// scopes its diff by this column, so a null network (an unconfigured pair - no
|
|
314
|
+
// catalog row could ever match it) and a configured-but-null providerName column both
|
|
315
|
+
// resolve to the single default binding rather than leaving the column null.
|
|
316
|
+
async providerNameFor(currency, network) {
|
|
317
|
+
if (network === null) {
|
|
318
|
+
return DEFAULT_PAYMENT_PROVIDER;
|
|
319
|
+
}
|
|
320
|
+
const [row] = await this.drizzle.db
|
|
321
|
+
.select({ providerName: walletAsset.providerName })
|
|
322
|
+
.from(walletAsset)
|
|
323
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
324
|
+
return row?.providerName ?? DEFAULT_PAYMENT_PROVIDER;
|
|
325
|
+
}
|
|
84
326
|
rateLimit(userId) {
|
|
85
327
|
return this.limiter
|
|
86
328
|
? assertRateLimit(this.limiter, `wallet-mutation:${userId}`, WALLET_MUTATION_RATE_LIMIT)
|
|
87
329
|
: Promise.resolve();
|
|
88
330
|
}
|
|
89
|
-
/** Fail-closed KYC gate: when enabled, a withdrawal needs a passing status (verified|manually_overridden). */
|
|
90
331
|
async assertKycForWithdrawal(userId) {
|
|
91
|
-
if (!this.platformConfig?.kyc?.gateWithdrawals)
|
|
332
|
+
if (!this.platformConfig?.kyc?.gateWithdrawals) {
|
|
92
333
|
return;
|
|
334
|
+
}
|
|
93
335
|
const status = await this.autoApprovalKycStatus(userId);
|
|
94
|
-
if (!status || !KYC_PASS_STATUSES.has(status)) {
|
|
336
|
+
if (!status || !KYC_PASS_STATUSES.has(normalizeKycStatus(status))) {
|
|
95
337
|
throw new KycRequiredError();
|
|
96
338
|
}
|
|
97
339
|
}
|
|
98
340
|
async getBalance(userId) {
|
|
99
341
|
const [record] = await this.drizzle.db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
100
342
|
if (!record) {
|
|
101
|
-
return { balance: 0, currency:
|
|
343
|
+
return { balance: '0', currency: DEFAULT_WALLET_CURRENCY };
|
|
102
344
|
}
|
|
103
345
|
return {
|
|
104
|
-
balance:
|
|
346
|
+
balance: await readWalletBalance(this.drizzle.db, record.id, record.currency),
|
|
105
347
|
currency: record.currency,
|
|
106
348
|
};
|
|
107
349
|
}
|
|
350
|
+
async getBalances(userId) {
|
|
351
|
+
const [record] = await this.drizzle.db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
352
|
+
if (!record) {
|
|
353
|
+
return { activeCurrency: DEFAULT_WALLET_CURRENCY, balances: [] };
|
|
354
|
+
}
|
|
355
|
+
const rows = await this.drizzle.db
|
|
356
|
+
.select({ currency: walletBalance.currency, balance: walletBalance.amount })
|
|
357
|
+
.from(walletBalance)
|
|
358
|
+
.where(eq(walletBalance.walletId, record.id))
|
|
359
|
+
.orderBy(walletBalance.currency);
|
|
360
|
+
return { activeCurrency: record.currency, balances: rows };
|
|
361
|
+
}
|
|
362
|
+
// TODO: validate `currency` against a canonical supported-currency list once one
|
|
363
|
+
// exists - `platformConfig.wallet.cryptoCurrencies` classifies rails, it is not an
|
|
364
|
+
// allowlist, so today any non-empty string is accepted and persisted.
|
|
365
|
+
async setActiveCurrency(userId, currency) {
|
|
366
|
+
const updated = await this.drizzle.db
|
|
367
|
+
.update(wallet)
|
|
368
|
+
.set({ currency })
|
|
369
|
+
.where(eq(wallet.userId, userId))
|
|
370
|
+
.returning({ currency: wallet.currency });
|
|
371
|
+
const record = updated[0];
|
|
372
|
+
if (!record) {
|
|
373
|
+
throw new WalletNotFoundError(userId);
|
|
374
|
+
}
|
|
375
|
+
return { activeCurrency: record.currency };
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* `idempotencyKey` (when supplied) makes a retried deposit a no-op: a replay
|
|
379
|
+
* returns the original committed result WITHOUT calling the PSP again or
|
|
380
|
+
* crediting the balance twice, and rejects if the same key is reused with a
|
|
381
|
+
* different amount/currency (`IdempotencyKeyReuseError`). A GENUINE
|
|
382
|
+
* concurrent race (two first-attempts, same key, landing at once) can both
|
|
383
|
+
* reach the PSP, but the ledger insert's unique-index conflict still
|
|
384
|
+
* guarantees only one balance credit - the loser's write becomes a replay
|
|
385
|
+
* read of the winner's row.
|
|
386
|
+
*/
|
|
108
387
|
async deposit({ userId, amount, currency, provider, idempotencyKey, }) {
|
|
109
388
|
await this.rateLimit(userId);
|
|
110
389
|
// Short-circuit a replay BEFORE the PSP call - the common retry case (client
|
|
@@ -114,10 +393,17 @@ export class WalletService {
|
|
|
114
393
|
let preResolvedWallet;
|
|
115
394
|
if (idempotencyKey) {
|
|
116
395
|
const found = await this.findDepositReplay({ userId, idempotencyKey, amount, currency });
|
|
117
|
-
if (found.replay)
|
|
396
|
+
if (found.replay) {
|
|
118
397
|
return found.replay;
|
|
398
|
+
}
|
|
119
399
|
preResolvedWallet = found.walletRecord;
|
|
120
400
|
}
|
|
401
|
+
else {
|
|
402
|
+
[preResolvedWallet] = await this.drizzle.db
|
|
403
|
+
.select()
|
|
404
|
+
.from(wallet)
|
|
405
|
+
.where(eq(wallet.userId, userId));
|
|
406
|
+
}
|
|
121
407
|
const psp = await this.payment.processDeposit(amount, currency, { userId, provider });
|
|
122
408
|
const { transactionId, replayed } = await this.drizzle.db.transaction(async (txn) => {
|
|
123
409
|
let walletRecord = preResolvedWallet;
|
|
@@ -125,10 +411,7 @@ export class WalletService {
|
|
|
125
411
|
[walletRecord] = await txn.select().from(wallet).where(eq(wallet.userId, userId));
|
|
126
412
|
}
|
|
127
413
|
if (!walletRecord) {
|
|
128
|
-
|
|
129
|
-
.insert(wallet)
|
|
130
|
-
.values({ userId, balance: '0', currency })
|
|
131
|
-
.returning();
|
|
414
|
+
walletRecord = findOneOrThrow(await txn.insert(wallet).values({ userId, currency }).returning(), new WalletNotFoundError(userId));
|
|
132
415
|
}
|
|
133
416
|
const { row, replayed } = await this.insertIdempotentTransaction(txn, {
|
|
134
417
|
namespace: DEPOSIT_IDEMPOTENCY_NAMESPACE,
|
|
@@ -139,27 +422,141 @@ export class WalletService {
|
|
|
139
422
|
values: {
|
|
140
423
|
walletId: walletRecord.id,
|
|
141
424
|
type: 'deposit',
|
|
142
|
-
amount
|
|
425
|
+
amount,
|
|
143
426
|
currency,
|
|
144
427
|
status: 'completed',
|
|
145
|
-
rail:
|
|
428
|
+
rail: this.resolveRail(currency),
|
|
146
429
|
providerName: provider,
|
|
147
430
|
providerRefId: psp.externalId,
|
|
148
431
|
},
|
|
149
432
|
});
|
|
150
433
|
if (!replayed) {
|
|
151
|
-
await txn
|
|
152
|
-
.update(wallet)
|
|
153
|
-
.set({ balance: sql `${wallet.balance} + ${amount}` })
|
|
154
|
-
.where(eq(wallet.id, walletRecord.id));
|
|
434
|
+
await creditWalletBalance(txn, walletRecord.id, currency, amount);
|
|
155
435
|
}
|
|
156
436
|
return { transactionId: row.id, replayed };
|
|
157
437
|
});
|
|
158
438
|
if (!replayed) {
|
|
159
|
-
this.events.emit('wallet.deposit.completed', {
|
|
439
|
+
this.events.emit('wallet.deposit.completed', {
|
|
440
|
+
userId,
|
|
441
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
442
|
+
amount,
|
|
443
|
+
currency,
|
|
444
|
+
transactionId,
|
|
445
|
+
});
|
|
160
446
|
}
|
|
161
447
|
return { transactionId, status: 'completed' };
|
|
162
448
|
}
|
|
449
|
+
async manualAdjust({ adminId, userId, direction, amount, currency, reason, idempotencyKey, ip, userAgent, }) {
|
|
450
|
+
const playerId = await this.identityReader.getPlayerIdByUserId(userId);
|
|
451
|
+
if (!playerId) {
|
|
452
|
+
throw new PlayerNotFoundError(userId);
|
|
453
|
+
}
|
|
454
|
+
const { result, emitted } = await this.drizzle.db.transaction(async (txn) => {
|
|
455
|
+
let walletRecord = (await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update')).at(0);
|
|
456
|
+
if (!walletRecord) {
|
|
457
|
+
if (direction === 'debit') {
|
|
458
|
+
throw new InsufficientBalanceError('0', amount);
|
|
459
|
+
}
|
|
460
|
+
const [created] = await txn
|
|
461
|
+
.insert(wallet)
|
|
462
|
+
.values({ userId, currency })
|
|
463
|
+
.onConflictDoNothing()
|
|
464
|
+
.returning();
|
|
465
|
+
walletRecord =
|
|
466
|
+
created ??
|
|
467
|
+
findOneOrThrow(await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update'), new WalletNotFoundError(userId));
|
|
468
|
+
}
|
|
469
|
+
const existing = await this.findByIdempotencyKey(txn, walletRecord.id, namespacedIdempotencyKey(MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE, idempotencyKey));
|
|
470
|
+
if (existing) {
|
|
471
|
+
this.assertManualAdjustmentReplayMatches(existing, {
|
|
472
|
+
adminId,
|
|
473
|
+
direction,
|
|
474
|
+
amount,
|
|
475
|
+
currency,
|
|
476
|
+
reason,
|
|
477
|
+
});
|
|
478
|
+
return { result: { transactionId: existing.id, status: existing.status }, emitted: false };
|
|
479
|
+
}
|
|
480
|
+
const { row, replayed } = await this.insertIdempotentTransaction(txn, {
|
|
481
|
+
namespace: MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE,
|
|
482
|
+
walletId: walletRecord.id,
|
|
483
|
+
rawIdempotencyKey: idempotencyKey,
|
|
484
|
+
amount,
|
|
485
|
+
currency,
|
|
486
|
+
values: {
|
|
487
|
+
walletId: walletRecord.id,
|
|
488
|
+
type: direction === 'credit' ? 'manual_credit' : 'manual_debit',
|
|
489
|
+
amount,
|
|
490
|
+
currency,
|
|
491
|
+
status: 'completed',
|
|
492
|
+
reviewedBy: adminId,
|
|
493
|
+
reviewedAt: new Date(),
|
|
494
|
+
reviewReason: reason,
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
if (replayed) {
|
|
498
|
+
this.assertManualAdjustmentReplayMatches(row, {
|
|
499
|
+
adminId,
|
|
500
|
+
direction,
|
|
501
|
+
amount,
|
|
502
|
+
currency,
|
|
503
|
+
reason,
|
|
504
|
+
});
|
|
505
|
+
return { result: { transactionId: row.id, status: row.status }, emitted: false };
|
|
506
|
+
}
|
|
507
|
+
const balances = direction === 'credit'
|
|
508
|
+
? await creditWalletBalance(txn, walletRecord.id, currency, amount)
|
|
509
|
+
: await debitWalletBalance(txn, walletRecord.id, currency, amount);
|
|
510
|
+
const [balance] = balances;
|
|
511
|
+
if (!balance) {
|
|
512
|
+
throw new InsufficientBalanceError(await readWalletBalance(txn, walletRecord.id, currency), amount);
|
|
513
|
+
}
|
|
514
|
+
// Derived from the row the update returned, never read separately beforehand. The
|
|
515
|
+
// wallet row is locked here but the deposit credit path does not take that lock, so
|
|
516
|
+
// a deposit can commit between a pre-read and this update - and `before` is going
|
|
517
|
+
// into an append-only audit record that cannot be corrected later.
|
|
518
|
+
const balanceBefore = direction === 'credit'
|
|
519
|
+
? moneySubtract(balance.amount, amount)
|
|
520
|
+
: moneyAdd(balance.amount, amount);
|
|
521
|
+
await this.audit.recordInTransaction(txn, {
|
|
522
|
+
actorId: adminId,
|
|
523
|
+
actorType: 'admin',
|
|
524
|
+
action: 'wallet.manual_adjustment.created',
|
|
525
|
+
resourceType: 'wallet_transaction',
|
|
526
|
+
resourceId: row.id,
|
|
527
|
+
before: { balance: balanceBefore, currency },
|
|
528
|
+
after: {
|
|
529
|
+
balance: balance.amount,
|
|
530
|
+
currency,
|
|
531
|
+
transactionId: row.id,
|
|
532
|
+
direction,
|
|
533
|
+
amount,
|
|
534
|
+
reason,
|
|
535
|
+
},
|
|
536
|
+
ip,
|
|
537
|
+
userAgent,
|
|
538
|
+
});
|
|
539
|
+
return { result: { transactionId: row.id, status: row.status }, emitted: true };
|
|
540
|
+
});
|
|
541
|
+
// Every other balance-mutating path on this service emits; without this one an admin
|
|
542
|
+
// correction moves a real balance while responsible-gaming monitoring, analytics and
|
|
543
|
+
// any operator subscriber see nothing at all.
|
|
544
|
+
if (emitted) {
|
|
545
|
+
this.events.emit('wallet.manual_adjustment.created', {
|
|
546
|
+
userId,
|
|
547
|
+
playerId,
|
|
548
|
+
adminId,
|
|
549
|
+
amount,
|
|
550
|
+
currency,
|
|
551
|
+
transactionId: result.transactionId,
|
|
552
|
+
direction,
|
|
553
|
+
reason,
|
|
554
|
+
ip,
|
|
555
|
+
userAgent,
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
return result;
|
|
559
|
+
}
|
|
163
560
|
// Pre-PSP replay check for deposit; also returns the resolved wallet so the transaction
|
|
164
561
|
// below can skip re-selecting it. Throws IdempotencyKeyReuseError on an amount/currency mismatch.
|
|
165
562
|
async findDepositReplay({ userId, idempotencyKey, amount, currency, }) {
|
|
@@ -167,20 +564,33 @@ export class WalletService {
|
|
|
167
564
|
.select()
|
|
168
565
|
.from(wallet)
|
|
169
566
|
.where(eq(wallet.userId, userId));
|
|
170
|
-
if (!walletRecord)
|
|
567
|
+
if (!walletRecord) {
|
|
171
568
|
return { walletRecord: undefined, replay: undefined };
|
|
569
|
+
}
|
|
172
570
|
const existing = await this.findByIdempotencyKey(this.drizzle.db, walletRecord.id, namespacedIdempotencyKey(DEPOSIT_IDEMPOTENCY_NAMESPACE, idempotencyKey));
|
|
173
|
-
if (!existing)
|
|
571
|
+
if (!existing) {
|
|
174
572
|
return { walletRecord, replay: undefined };
|
|
573
|
+
}
|
|
175
574
|
this.assertReplayMatches(existing, amount, currency);
|
|
176
575
|
return { walletRecord, replay: { transactionId: existing.id, status: existing.status } };
|
|
177
576
|
}
|
|
577
|
+
// Replay comparison only (not a ledger write). moneyEquals avoids a false mismatch between
|
|
578
|
+
// an unnormalized caller string (eg "10") and the DB's fixed-scale value ("10.00") while
|
|
579
|
+
// staying exact - a float compare would let two amounts differing past the 15th digit pass.
|
|
178
580
|
assertReplayMatches(existing, amount, currency) {
|
|
179
|
-
if (
|
|
581
|
+
if (!moneyEquals(existing.amount, amount) ||
|
|
180
582
|
existing.currency.toUpperCase() !== currency.toUpperCase()) {
|
|
181
583
|
throw new IdempotencyKeyReuseError();
|
|
182
584
|
}
|
|
183
585
|
}
|
|
586
|
+
assertManualAdjustmentReplayMatches(existing, { adminId, direction, amount, currency, reason, }) {
|
|
587
|
+
if (existing.type !== (direction === 'credit' ? 'manual_credit' : 'manual_debit') ||
|
|
588
|
+
existing.reviewedBy !== adminId ||
|
|
589
|
+
existing.reviewReason !== reason) {
|
|
590
|
+
throw new IdempotencyKeyReuseError();
|
|
591
|
+
}
|
|
592
|
+
this.assertReplayMatches(existing, amount, currency);
|
|
593
|
+
}
|
|
184
594
|
// Two concurrent requests with the same key can both pass the pre-insert check and race
|
|
185
595
|
// on the unique index; onConflictDoNothing makes the loser's insert a no-op so it re-reads
|
|
186
596
|
// the winner's committed row and returns it as a replay instead of aborting the transaction.
|
|
@@ -194,8 +604,9 @@ export class WalletService {
|
|
|
194
604
|
const [row] = idempotencyKey
|
|
195
605
|
? await insertQuery.onConflictDoNothing().returning()
|
|
196
606
|
: await insertQuery.returning();
|
|
197
|
-
if (row)
|
|
607
|
+
if (row) {
|
|
198
608
|
return { row, replayed: false };
|
|
609
|
+
}
|
|
199
610
|
// Only the keyed (onConflictDoNothing) branch above can return an empty `returning()`
|
|
200
611
|
// - the plain-insert branch always yields exactly one row.
|
|
201
612
|
if (!idempotencyKey) {
|
|
@@ -208,17 +619,29 @@ export class WalletService {
|
|
|
208
619
|
this.assertReplayMatches(winner, amount, currency);
|
|
209
620
|
return { row: winner, replayed: true };
|
|
210
621
|
}
|
|
211
|
-
/**
|
|
212
|
-
|
|
622
|
+
/**
|
|
623
|
+
* Creates a PENDING withdrawal and HOLDS the funds immediately (balance
|
|
624
|
+
* debited at request time, not on approval) - funds are returned on
|
|
625
|
+
* reject/PSP-failure. The debit is a conditional `UPDATE ... WHERE balance
|
|
626
|
+
* >= amount`, atomic with the row lock (`FOR UPDATE`) taken on the wallet,
|
|
627
|
+
* so two concurrent withdrawals can't both pass a balance check and
|
|
628
|
+
* double-spend. `idempotencyKey` replay semantics mirror `deposit()`. May
|
|
629
|
+
* return an already-`completed`/`processing` result if the request
|
|
630
|
+
* qualifies for (and passes) auto-approval - see `maybeAutoApprove`.
|
|
631
|
+
*/
|
|
632
|
+
async withdraw({ userId, amount, currency, network, idempotencyKey, destinationAddress, ip, userAgent, }) {
|
|
213
633
|
await this.rateLimit(userId);
|
|
214
634
|
await this.assertKycForWithdrawal(userId);
|
|
635
|
+
if (this.resolveRail(currency) === 'crypto' && !destinationAddress) {
|
|
636
|
+
throw new DestinationAddressRequiredError();
|
|
637
|
+
}
|
|
638
|
+
const assets = await this.assetsForCurrency(currency);
|
|
639
|
+
const settlementNetwork = resolveWithdrawalNetwork(assets, currency, network);
|
|
640
|
+
assertAboveMinimumWithdrawal(assets, amount, currency, settlementNetwork);
|
|
641
|
+
const destinationWalletId = await this.requireWhitelistedWalletId(userId, currency, settlementNetwork, destinationAddress);
|
|
215
642
|
const { transactionId, status, replayed, walletId, rail } = await this.drizzle.db.transaction(async (txn) => {
|
|
216
643
|
// FOR UPDATE serializes concurrent withdrawals against a double-debit TOCTOU under READ COMMITTED.
|
|
217
644
|
const current = findOneOrThrow(await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update'), new WalletNotFoundError(userId));
|
|
218
|
-
// Single-currency wallet: reject a mismatch rather than coerce it onto the wrong rail.
|
|
219
|
-
if (currency.toUpperCase() !== current.currency.toUpperCase()) {
|
|
220
|
-
throw new CurrencyMismatchError(currency, current.currency);
|
|
221
|
-
}
|
|
222
645
|
// Replay of an already-committed key: return the original untouched. The new-key race is caught by the insert below.
|
|
223
646
|
if (idempotencyKey) {
|
|
224
647
|
const existing = await this.findByIdempotencyKey(txn, current.id, namespacedIdempotencyKey(WITHDRAW_IDEMPOTENCY_NAMESPACE, idempotencyKey));
|
|
@@ -229,7 +652,7 @@ export class WalletService {
|
|
|
229
652
|
status: existing.status,
|
|
230
653
|
replayed: true,
|
|
231
654
|
walletId: current.id,
|
|
232
|
-
rail:
|
|
655
|
+
rail: this.resolveRail(currency),
|
|
233
656
|
};
|
|
234
657
|
}
|
|
235
658
|
}
|
|
@@ -242,10 +665,13 @@ export class WalletService {
|
|
|
242
665
|
values: {
|
|
243
666
|
walletId: current.id,
|
|
244
667
|
type: 'withdrawal',
|
|
245
|
-
amount
|
|
668
|
+
amount,
|
|
246
669
|
currency,
|
|
247
670
|
status: 'pending',
|
|
248
|
-
rail:
|
|
671
|
+
rail: this.resolveRail(currency),
|
|
672
|
+
network: settlementNetwork,
|
|
673
|
+
destinationAddress: destinationAddress ?? null,
|
|
674
|
+
destinationWalletId,
|
|
249
675
|
},
|
|
250
676
|
});
|
|
251
677
|
if (replayed) {
|
|
@@ -254,29 +680,43 @@ export class WalletService {
|
|
|
254
680
|
status: row.status,
|
|
255
681
|
replayed,
|
|
256
682
|
walletId: current.id,
|
|
257
|
-
rail:
|
|
683
|
+
rail: this.resolveRail(currency),
|
|
258
684
|
};
|
|
259
685
|
}
|
|
260
|
-
|
|
261
|
-
const debited = await txn
|
|
262
|
-
.update(wallet)
|
|
263
|
-
.set({ balance: sql `${wallet.balance} - ${amount}` })
|
|
264
|
-
.where(and(eq(wallet.id, current.id), gte(wallet.balance, amount.toString())))
|
|
265
|
-
.returning({ id: wallet.id });
|
|
686
|
+
const debited = await debitWithdrawableBalance(txn, current.id, currency, amount);
|
|
266
687
|
if (debited.length !== 1) {
|
|
267
|
-
|
|
688
|
+
const [available, locked] = await Promise.all([
|
|
689
|
+
readWalletBalance(txn, current.id, currency),
|
|
690
|
+
readLockedBonusAmount(txn, current.id, currency),
|
|
691
|
+
]);
|
|
692
|
+
if (moneyToNumber(available) < moneyToNumber(amount)) {
|
|
693
|
+
throw new InsufficientBalanceError(available, amount);
|
|
694
|
+
}
|
|
695
|
+
throw new BonusRolloverLockedError(locked);
|
|
696
|
+
}
|
|
697
|
+
if (this.tagEvaluationCommands) {
|
|
698
|
+
await this.tagEvaluationCommands.evaluateWithdrawalRequested(txn, { userId, amount });
|
|
268
699
|
}
|
|
269
700
|
return {
|
|
270
701
|
transactionId: row.id,
|
|
271
702
|
status: row.status,
|
|
272
703
|
replayed,
|
|
273
704
|
walletId: current.id,
|
|
274
|
-
rail:
|
|
705
|
+
rail: this.resolveRail(currency),
|
|
275
706
|
};
|
|
276
707
|
});
|
|
277
|
-
if (replayed)
|
|
708
|
+
if (replayed) {
|
|
278
709
|
return { transactionId, status };
|
|
279
|
-
|
|
710
|
+
}
|
|
711
|
+
this.events.emit('wallet.withdrawal.requested', {
|
|
712
|
+
userId,
|
|
713
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
714
|
+
amount,
|
|
715
|
+
currency,
|
|
716
|
+
transactionId,
|
|
717
|
+
ip: ip ?? null,
|
|
718
|
+
userAgent: userAgent ?? null,
|
|
719
|
+
});
|
|
280
720
|
// Fail-closed post-step: decides who approves (system vs manual queue), never throws out of withdraw() - failure leaves the row pending.
|
|
281
721
|
const auto = await this.maybeAutoApprove({
|
|
282
722
|
userId,
|
|
@@ -292,17 +732,20 @@ export class WalletService {
|
|
|
292
732
|
const db = this.drizzle.db;
|
|
293
733
|
const { page, limit } = filters;
|
|
294
734
|
const conditions = [eq(walletTransaction.type, 'withdrawal')];
|
|
295
|
-
if (filters.status)
|
|
735
|
+
if (filters.status) {
|
|
296
736
|
conditions.push(eq(walletTransaction.status, filters.status));
|
|
297
|
-
|
|
737
|
+
}
|
|
738
|
+
if (filters.currency) {
|
|
298
739
|
conditions.push(eq(walletTransaction.currency, filters.currency));
|
|
299
|
-
|
|
740
|
+
}
|
|
741
|
+
if (filters.rail) {
|
|
300
742
|
conditions.push(eq(walletTransaction.rail, filters.rail));
|
|
743
|
+
}
|
|
301
744
|
if (filters.minAmount !== undefined) {
|
|
302
|
-
conditions.push(gte(walletTransaction.amount, filters.minAmount
|
|
745
|
+
conditions.push(gte(walletTransaction.amount, filters.minAmount));
|
|
303
746
|
}
|
|
304
747
|
if (filters.maxAmount !== undefined) {
|
|
305
|
-
conditions.push(lte(walletTransaction.amount, filters.maxAmount
|
|
748
|
+
conditions.push(lte(walletTransaction.amount, filters.maxAmount));
|
|
306
749
|
}
|
|
307
750
|
if (filters.dateFrom) {
|
|
308
751
|
conditions.push(gte(walletTransaction.createdAt, new Date(filters.dateFrom)));
|
|
@@ -312,19 +755,40 @@ export class WalletService {
|
|
|
312
755
|
}
|
|
313
756
|
// Bounded queue: fetch all SQL-matching rows, then enrich + kycStatus-filter + paginate in memory,
|
|
314
757
|
// else DB-side pagination makes `total` wrong once kycStatus prunes.
|
|
758
|
+
const wdSortBy = filters.sortBy ?? 'createdAt';
|
|
759
|
+
const wdDir = (filters.sortOrder ?? 'desc') === 'asc' ? asc : desc;
|
|
760
|
+
const WD_SORT_COLS = {
|
|
761
|
+
createdAt: walletTransaction.createdAt,
|
|
762
|
+
amount: walletTransaction.amount,
|
|
763
|
+
status: walletTransaction.status,
|
|
764
|
+
currency: walletTransaction.currency,
|
|
765
|
+
rail: walletTransaction.rail,
|
|
766
|
+
reviewedAt: walletTransaction.reviewedAt,
|
|
767
|
+
};
|
|
315
768
|
const rows = await db
|
|
316
769
|
.select({ tx: walletTransaction, userId: wallet.userId })
|
|
317
770
|
.from(walletTransaction)
|
|
318
771
|
.innerJoin(wallet, eq(wallet.id, walletTransaction.walletId))
|
|
319
772
|
.where(and(...conditions))
|
|
320
|
-
.orderBy(desc(walletTransaction.
|
|
773
|
+
.orderBy(wdDir(WD_SORT_COLS[wdSortBy]), desc(walletTransaction.id));
|
|
321
774
|
const userIds = [...new Set(rows.map((r) => r.userId))];
|
|
322
775
|
const summaries = this.directory ? await this.directory.lookupPlayers(userIds) : [];
|
|
323
776
|
const byUserId = new Map(summaries.map((s) => [s.userId, s]));
|
|
324
|
-
|
|
325
|
-
|
|
777
|
+
// Normalize both sides before comparing: the ADMIN_USER_DIRECTORY port's return type
|
|
778
|
+
// still permits the deprecated `verified` value (it aliases `approved`), and this
|
|
779
|
+
// module cannot assume every bound implementation already normalized it at its own
|
|
780
|
+
// read boundary - a raw `===` here would silently hide every legacy-verified player
|
|
781
|
+
// from the queue the moment an admin filters by the canonical `approved`.
|
|
782
|
+
const kycStatusFilter = filters.kycStatus ? normalizeKycStatus(filters.kycStatus) : undefined;
|
|
783
|
+
const matching = kycStatusFilter
|
|
784
|
+
? rows.filter((r) => {
|
|
785
|
+
const kycStatus = byUserId.get(r.userId)?.kycStatus;
|
|
786
|
+
return kycStatus !== undefined && kycStatus !== null
|
|
787
|
+
? normalizeKycStatus(kycStatus) === kycStatusFilter
|
|
788
|
+
: false;
|
|
789
|
+
})
|
|
326
790
|
: rows;
|
|
327
|
-
const start = (page
|
|
791
|
+
const start = pageToOffset(page, limit);
|
|
328
792
|
const pageRows = matching.slice(start, start + limit);
|
|
329
793
|
// One batched velocity query for the page (no N+1); shares the window + threshold + query the auto-approval evaluator uses.
|
|
330
794
|
const pageWalletIds = [...new Set(pageRows.map((r) => r.tx.walletId))];
|
|
@@ -332,21 +796,27 @@ export class WalletService {
|
|
|
332
796
|
const items = pageRows.map((r) => {
|
|
333
797
|
const summary = byUserId.get(r.userId);
|
|
334
798
|
const riskTags = [];
|
|
335
|
-
if (
|
|
799
|
+
if (moneyToNumber(r.tx.amount) >= moneyToNumber(LARGE_WITHDRAWAL_THRESHOLD)) {
|
|
336
800
|
riskTags.push('large_amount');
|
|
337
|
-
|
|
801
|
+
}
|
|
802
|
+
if (frequentWalletIds.has(r.tx.walletId)) {
|
|
338
803
|
riskTags.push('high_frequency');
|
|
804
|
+
}
|
|
339
805
|
return {
|
|
340
806
|
transactionId: r.tx.id,
|
|
341
807
|
userId: r.userId,
|
|
808
|
+
playerId: summary?.playerId ?? null,
|
|
342
809
|
username: summary?.username ?? '',
|
|
343
|
-
amount:
|
|
810
|
+
amount: r.tx.amount,
|
|
344
811
|
currency: r.tx.currency,
|
|
812
|
+
network: r.tx.network,
|
|
345
813
|
rail: r.tx.rail ?? null,
|
|
346
814
|
status: r.tx.status,
|
|
347
815
|
kycStatus: summary?.kycStatus ?? null,
|
|
348
816
|
riskTags,
|
|
349
817
|
requestedAt: r.tx.createdAt.toISOString(),
|
|
818
|
+
destinationAddress: r.tx.destinationAddress,
|
|
819
|
+
txHash: r.tx.txHash,
|
|
350
820
|
};
|
|
351
821
|
});
|
|
352
822
|
return { items, total: matching.length, page, limit };
|
|
@@ -356,11 +826,11 @@ export class WalletService {
|
|
|
356
826
|
* or Failed + refund on PSP error. Robust PSP idempotency-key/reconciliation for a
|
|
357
827
|
* lost-response is deferred - same scope boundary the deposit path declares.
|
|
358
828
|
*/
|
|
359
|
-
async approveWithdrawal(adminId, withdrawalId) {
|
|
829
|
+
async approveWithdrawal(adminId, withdrawalId, meta) {
|
|
360
830
|
// Two-phase: commit the `processing` flip first (FOR UPDATE lock), then call the PSP OUTSIDE
|
|
361
831
|
// the tx (a failure refunds in a second tx). Never inline the PSP call inside the hold transaction.
|
|
362
832
|
const tx = await this.drizzle.db.transaction((txn) => this.flipToProcessing({ txn, withdrawalId, adminId }));
|
|
363
|
-
return this.settleApproved(tx, adminId);
|
|
833
|
+
return this.settleApproved(tx, adminId, meta);
|
|
364
834
|
}
|
|
365
835
|
// Phase one: the pending -> processing flip under a FOR UPDATE lock. Extracted so the auto path can run it
|
|
366
836
|
// inside its advisory-locked cap-check transaction, committing the marker atomically. Never call the PSP here.
|
|
@@ -374,7 +844,7 @@ export class WalletService {
|
|
|
374
844
|
if (current.status !== 'pending' || current.type !== 'withdrawal') {
|
|
375
845
|
throw new WithdrawalNotPendingError();
|
|
376
846
|
}
|
|
377
|
-
|
|
847
|
+
return findOneOrThrow(await txn
|
|
378
848
|
.update(walletTransaction)
|
|
379
849
|
.set({
|
|
380
850
|
status: 'processing',
|
|
@@ -383,14 +853,13 @@ export class WalletService {
|
|
|
383
853
|
...(reviewReason !== undefined ? { reviewReason } : {}),
|
|
384
854
|
})
|
|
385
855
|
.where(eq(walletTransaction.id, withdrawalId))
|
|
386
|
-
.returning();
|
|
387
|
-
return updated;
|
|
856
|
+
.returning(), new WithdrawalNotFoundError(withdrawalId));
|
|
388
857
|
}
|
|
389
858
|
// Phase two: settle a `processing` withdrawal via the PSP (Completed on success, Failed + refund on error).
|
|
390
859
|
// Runs OUTSIDE the hold/flip transaction so the external PSP call never holds a DB lock.
|
|
391
|
-
async settleApproved(tx, adminId) {
|
|
860
|
+
async settleApproved(tx, adminId, meta) {
|
|
392
861
|
const userId = await this.userIdForWallet(tx.walletId);
|
|
393
|
-
const amount =
|
|
862
|
+
const amount = tx.amount;
|
|
394
863
|
// approved/failed are admin-attributed events (schema requires a uuid adminId); the system auto path
|
|
395
864
|
// skips them - its trail is the AUDIT_WRITER entry plus the shared `completed` event below.
|
|
396
865
|
if (adminId) {
|
|
@@ -400,6 +869,8 @@ export class WalletService {
|
|
|
400
869
|
currency: tx.currency,
|
|
401
870
|
transactionId: tx.id,
|
|
402
871
|
adminId,
|
|
872
|
+
ip: meta?.ip ?? null,
|
|
873
|
+
userAgent: meta?.userAgent ?? null,
|
|
403
874
|
});
|
|
404
875
|
}
|
|
405
876
|
let result;
|
|
@@ -409,67 +880,133 @@ export class WalletService {
|
|
|
409
880
|
userId,
|
|
410
881
|
rail: tx.rail,
|
|
411
882
|
adminId,
|
|
883
|
+
destinationAddress: tx.destinationAddress,
|
|
884
|
+
// The provider-side whitelisted destination for that address, when the bound adapter
|
|
885
|
+
// whitelists at all. Absent for an address that predates whitelisting or was never in
|
|
886
|
+
// the book, and such an adapter is expected to refuse rather than pay out to the raw
|
|
887
|
+
// address - the whitelist is the control, so bypassing it would defeat the point.
|
|
888
|
+
...(tx.destinationWalletId ? { destinationWalletId: tx.destinationWalletId } : {}),
|
|
889
|
+
// Pinned at request time; without it an adapter cannot tell ERC20 USDT from TRC20.
|
|
890
|
+
network: tx.network,
|
|
412
891
|
});
|
|
413
892
|
}
|
|
414
893
|
catch (err) {
|
|
415
894
|
// Payout did not happen - mark failed and return the held funds in one transaction.
|
|
416
|
-
await this.
|
|
417
|
-
await txn
|
|
418
|
-
.update(walletTransaction)
|
|
419
|
-
.set({ status: 'failed' })
|
|
420
|
-
.where(eq(walletTransaction.id, tx.id));
|
|
421
|
-
await txn
|
|
422
|
-
.update(wallet)
|
|
423
|
-
.set({ balance: sql `${wallet.balance} + ${amount}` })
|
|
424
|
-
.where(eq(wallet.id, tx.walletId));
|
|
425
|
-
});
|
|
426
|
-
if (adminId) {
|
|
427
|
-
this.events.emit('wallet.withdrawal.failed', {
|
|
428
|
-
userId,
|
|
429
|
-
amount,
|
|
430
|
-
currency: tx.currency,
|
|
431
|
-
transactionId: tx.id,
|
|
432
|
-
adminId,
|
|
433
|
-
});
|
|
434
|
-
}
|
|
895
|
+
await this.finalizeFailedWithdrawal({ tx, adminId, userId, amount });
|
|
435
896
|
throw err;
|
|
436
897
|
}
|
|
898
|
+
if (result.status === 'failed') {
|
|
899
|
+
await this.finalizeFailedWithdrawal({ tx, adminId, userId, amount });
|
|
900
|
+
return { transactionId: tx.id, status: 'failed' };
|
|
901
|
+
}
|
|
902
|
+
if (result.status !== 'completed') {
|
|
903
|
+
await this.drizzle.db
|
|
904
|
+
.update(walletTransaction)
|
|
905
|
+
.set({
|
|
906
|
+
providerName: await this.providerNameFor(tx.currency, tx.network),
|
|
907
|
+
providerRefId: result.externalId,
|
|
908
|
+
})
|
|
909
|
+
.where(eq(walletTransaction.id, tx.id));
|
|
910
|
+
return { transactionId: tx.id, status: 'processing' };
|
|
911
|
+
}
|
|
437
912
|
await this.drizzle.db
|
|
438
913
|
.update(walletTransaction)
|
|
439
914
|
.set({
|
|
440
915
|
status: 'completed',
|
|
441
|
-
providerName: providerNameFor(tx.
|
|
916
|
+
providerName: await this.providerNameFor(tx.currency, tx.network),
|
|
442
917
|
providerRefId: result.externalId,
|
|
443
918
|
})
|
|
444
919
|
.where(eq(walletTransaction.id, tx.id));
|
|
445
920
|
this.events.emit('wallet.withdrawal.completed', {
|
|
446
921
|
userId,
|
|
922
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
447
923
|
amount,
|
|
448
924
|
currency: tx.currency,
|
|
449
925
|
transactionId: tx.id,
|
|
450
926
|
});
|
|
451
927
|
return { transactionId: tx.id, status: 'completed' };
|
|
452
928
|
}
|
|
929
|
+
async finalizeFailedWithdrawal({ tx, adminId, userId, amount, }) {
|
|
930
|
+
const transitioned = await this.drizzle.db.transaction(async (txn) => {
|
|
931
|
+
const updated = await txn
|
|
932
|
+
.update(walletTransaction)
|
|
933
|
+
.set({ status: 'failed' })
|
|
934
|
+
.where(and(eq(walletTransaction.id, tx.id), eq(walletTransaction.status, 'processing')))
|
|
935
|
+
.returning({ id: walletTransaction.id });
|
|
936
|
+
if (updated.length === 0) {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
await creditWalletBalance(txn, tx.walletId, tx.currency, amount);
|
|
940
|
+
return true;
|
|
941
|
+
});
|
|
942
|
+
if (transitioned && adminId) {
|
|
943
|
+
this.events.emit('wallet.withdrawal.failed', {
|
|
944
|
+
userId,
|
|
945
|
+
amount,
|
|
946
|
+
currency: tx.currency,
|
|
947
|
+
transactionId: tx.id,
|
|
948
|
+
adminId,
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
async reconcileWithdrawalStatus(event) {
|
|
953
|
+
const { externalId, status, txHash } = event;
|
|
954
|
+
const [tx] = await this.drizzle.db
|
|
955
|
+
.select()
|
|
956
|
+
.from(walletTransaction)
|
|
957
|
+
.where(eq(walletTransaction.providerRefId, externalId));
|
|
958
|
+
if (!tx || tx.type !== 'withdrawal') {
|
|
959
|
+
logger.warn({ externalId }, 'payment webhook: no matching withdrawal for providerRefId');
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
if (tx.status !== 'processing') {
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const userId = await this.userIdForWallet(tx.walletId);
|
|
966
|
+
if (status === 'completed') {
|
|
967
|
+
const updated = await this.drizzle.db
|
|
968
|
+
.update(walletTransaction)
|
|
969
|
+
.set({ status: 'completed', txHash: txHash ?? tx.txHash })
|
|
970
|
+
.where(and(eq(walletTransaction.id, tx.id), eq(walletTransaction.status, 'processing')))
|
|
971
|
+
.returning({ id: walletTransaction.id });
|
|
972
|
+
if (updated.length === 0) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
this.events.emit('wallet.withdrawal.completed', {
|
|
976
|
+
userId,
|
|
977
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
978
|
+
amount: tx.amount,
|
|
979
|
+
currency: tx.currency,
|
|
980
|
+
transactionId: tx.id,
|
|
981
|
+
});
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
if (status === 'failed') {
|
|
985
|
+
await this.finalizeFailedWithdrawal({ tx, adminId: null, userId, amount: tx.amount });
|
|
986
|
+
}
|
|
987
|
+
}
|
|
453
988
|
// Evaluates the auto-approval gates and settles the payout if all pass; returns undefined to
|
|
454
989
|
// leave the row pending for the manual queue. NEVER throws: any error fails closed to manual.
|
|
455
990
|
async maybeAutoApprove(args) {
|
|
456
|
-
|
|
457
|
-
if (!this.platformConfig?.autoWithdrawal?.enabled || args.rail !== 'fiat')
|
|
991
|
+
if (!this.platformConfig?.autoWithdrawal?.enabled) {
|
|
458
992
|
return undefined;
|
|
993
|
+
}
|
|
459
994
|
try {
|
|
460
995
|
const cfg = this.platformConfig.autoWithdrawal;
|
|
461
996
|
// Threshold/KYC/risk/velocity gates run outside any lock; only the cap check below needs serializing.
|
|
462
997
|
const gates = await this.evaluateAutoApproval(args);
|
|
463
|
-
if (!gates)
|
|
998
|
+
if (!gates) {
|
|
464
999
|
return undefined;
|
|
1000
|
+
}
|
|
465
1001
|
// Serialize the cap-check-and-flip per user with an advisory lock: without it two concurrent
|
|
466
1002
|
// withdrawals read the same daily-cap usage and both auto-approve, bypassing the cap. The cap read
|
|
467
1003
|
// and the flip that writes the marker commit together, so a blocked caller re-reads current usage.
|
|
468
1004
|
// PSP settlement runs AFTER, outside the lock.
|
|
469
1005
|
const decided = await this.drizzle.db.transaction((txn) => withAdvisoryXactLock(txn, args.userId, async () => {
|
|
470
1006
|
const caps = await this.autoApprovalCaps({ walletId: args.walletId, amount: args.amount, cfg }, txn);
|
|
471
|
-
if (caps.exceeded)
|
|
1007
|
+
if (caps.exceeded) {
|
|
472
1008
|
return null;
|
|
1009
|
+
}
|
|
473
1010
|
const tx = await this.flipToProcessing({
|
|
474
1011
|
txn,
|
|
475
1012
|
withdrawalId: args.transactionId,
|
|
@@ -478,8 +1015,9 @@ export class WalletService {
|
|
|
478
1015
|
});
|
|
479
1016
|
return { tx, caps };
|
|
480
1017
|
}));
|
|
481
|
-
if (!decided)
|
|
1018
|
+
if (!decided) {
|
|
482
1019
|
return undefined;
|
|
1020
|
+
}
|
|
483
1021
|
const decision = {
|
|
484
1022
|
...gates,
|
|
485
1023
|
dailyCapAmount: cfg.dailyCapAmount ?? null,
|
|
@@ -494,7 +1032,12 @@ export class WalletService {
|
|
|
494
1032
|
action: 'wallet.withdrawal.auto_approved',
|
|
495
1033
|
resourceType: 'wallet_transaction',
|
|
496
1034
|
resourceId: args.transactionId,
|
|
497
|
-
after: {
|
|
1035
|
+
after: {
|
|
1036
|
+
userId: args.userId,
|
|
1037
|
+
amount: args.amount,
|
|
1038
|
+
currency: args.currency,
|
|
1039
|
+
...decision,
|
|
1040
|
+
},
|
|
498
1041
|
});
|
|
499
1042
|
}
|
|
500
1043
|
catch (err) {
|
|
@@ -518,69 +1061,340 @@ export class WalletService {
|
|
|
518
1061
|
// route to manual. The daily-cap check is NOT here - it runs under the advisory lock (see maybeAutoApprove).
|
|
519
1062
|
async evaluateAutoApproval({ userId, amount, walletId, rail, }) {
|
|
520
1063
|
const cfg = this.platformConfig?.autoWithdrawal;
|
|
521
|
-
if (!cfg?.enabled)
|
|
522
|
-
return null;
|
|
523
|
-
// Hard stop: crypto is irreversible and AML-sensitive - never auto-approved.
|
|
524
|
-
if (rail !== 'fiat')
|
|
1064
|
+
if (!cfg?.enabled) {
|
|
525
1065
|
return null;
|
|
526
|
-
|
|
527
|
-
|
|
1066
|
+
}
|
|
1067
|
+
const threshold = await this.resolveAutoThreshold(userId, rail);
|
|
1068
|
+
if (!threshold || moneyToNumber(threshold.value) <= 0) {
|
|
528
1069
|
return null;
|
|
529
|
-
|
|
1070
|
+
}
|
|
1071
|
+
if (moneyToNumber(amount) > moneyToNumber(threshold.value)) {
|
|
530
1072
|
return null;
|
|
1073
|
+
}
|
|
531
1074
|
// Independent of kyc.gateWithdrawals: auto-approval always demands a passing status; anything else fails closed.
|
|
532
1075
|
const kycStatus = await this.autoApprovalKycStatus(userId);
|
|
533
|
-
if (!kycStatus || !KYC_PASS_STATUSES.has(kycStatus))
|
|
1076
|
+
if (!kycStatus || !KYC_PASS_STATUSES.has(normalizeKycStatus(kycStatus))) {
|
|
534
1077
|
return null;
|
|
535
|
-
|
|
1078
|
+
}
|
|
1079
|
+
const effectiveExcludeTags = threshold.config.excludeRiskFlags;
|
|
1080
|
+
const riskTags = await this.autoApprovalRiskTags(userId, effectiveExcludeTags);
|
|
536
1081
|
// null = exclusions configured but the lookup port is unavailable => fail closed.
|
|
537
|
-
if (riskTags === null)
|
|
1082
|
+
if (riskTags === null) {
|
|
538
1083
|
return null;
|
|
539
|
-
|
|
1084
|
+
}
|
|
1085
|
+
if (riskTags.some((t) => effectiveExcludeTags.includes(t))) {
|
|
540
1086
|
return null;
|
|
1087
|
+
}
|
|
541
1088
|
const heuristics = await this.autoApprovalHeuristics({ walletId, amount });
|
|
542
|
-
if (heuristics.largeAmount || heuristics.highFrequency)
|
|
1089
|
+
if (heuristics.largeAmount || heuristics.highFrequency) {
|
|
543
1090
|
return null;
|
|
1091
|
+
}
|
|
544
1092
|
return {
|
|
545
1093
|
threshold: threshold.value,
|
|
546
1094
|
thresholdSource: threshold.source,
|
|
547
1095
|
kycStatus,
|
|
548
1096
|
riskTagsEvaluated: riskTags,
|
|
1097
|
+
effectiveExcludeTags,
|
|
549
1098
|
};
|
|
550
1099
|
}
|
|
551
|
-
|
|
552
|
-
|
|
1100
|
+
async resolveAutoThreshold(userId, rail) {
|
|
1101
|
+
// Always read the global singleton first, even when a per-player override may end up
|
|
1102
|
+
// winning below - an unseeded install (missing row) must fail closed for EVERY player,
|
|
1103
|
+
// not just those without an override. getAutoWithdrawalConfig() throws when absent.
|
|
1104
|
+
const config = await this.getAutoWithdrawalConfig();
|
|
553
1105
|
const [rule] = await this.drizzle.db
|
|
554
1106
|
.select()
|
|
555
1107
|
.from(autoWithdrawalRule)
|
|
556
1108
|
.where(eq(autoWithdrawalRule.userId, userId));
|
|
557
|
-
if (rule)
|
|
558
|
-
return { value:
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
1109
|
+
if (rule) {
|
|
1110
|
+
return { value: rule.threshold, source: 'per-player', config };
|
|
1111
|
+
}
|
|
1112
|
+
const global = rail === 'crypto' ? config.cryptoThreshold : config.fiatThreshold;
|
|
1113
|
+
return { value: global, source: 'global', config };
|
|
1114
|
+
}
|
|
1115
|
+
// The row always exists in a properly-seeded install (seeded once) - a
|
|
1116
|
+
// missing row is an unexpected failure mode on the READ path, not a normal
|
|
1117
|
+
// "unconfigured" state, so this throws rather than silently defaulting.
|
|
1118
|
+
// maybeAutoApprove's outer try/catch handles that thrown error the same as any
|
|
1119
|
+
// other unexpected error: fail closed to pending.
|
|
1120
|
+
async getAutoWithdrawalConfig() {
|
|
1121
|
+
const config = await this.getAutoWithdrawalConfigOrNull();
|
|
1122
|
+
if (!config) {
|
|
1123
|
+
throw new AutoWithdrawalConfigNotFoundError('global');
|
|
1124
|
+
}
|
|
1125
|
+
return config;
|
|
1126
|
+
}
|
|
1127
|
+
// Non-throwing variant for callers that need to tell "missing" from "found"
|
|
1128
|
+
// without a try/catch (eg the router's audit `before` read).
|
|
1129
|
+
async getAutoWithdrawalConfigOrNull() {
|
|
1130
|
+
const [row] = await this.drizzle.db
|
|
1131
|
+
.select()
|
|
1132
|
+
.from(walletAutoWithdrawalConfig)
|
|
1133
|
+
.where(eq(walletAutoWithdrawalConfig.singletonKey, 'global'));
|
|
1134
|
+
return row ? toAutoWithdrawalConfigDto(row) : null;
|
|
1135
|
+
}
|
|
1136
|
+
// Upsert, not a plain UPDATE: the WRITE path lets a Super Admin self-heal a
|
|
1137
|
+
// missing singleton row (eg an install that skipped the seed step) through the
|
|
1138
|
+
// existing route with zero new surface. The READ path (getAutoWithdrawalConfig,
|
|
1139
|
+
// resolveAutoThreshold) still throws on a missing row and stays fail-closed -
|
|
1140
|
+
// a withdrawal must never silently create config.
|
|
1141
|
+
//
|
|
1142
|
+
// Update + audit write run in one transaction: an audit-write failure must roll back
|
|
1143
|
+
// the threshold change too, or the config could change with no audit trail.
|
|
1144
|
+
async setAutoWithdrawalConfig(adminId, { fiatThreshold, cryptoThreshold, excludeRiskFlags, }, meta) {
|
|
1145
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1146
|
+
const [before] = await txn
|
|
1147
|
+
.select()
|
|
1148
|
+
.from(walletAutoWithdrawalConfig)
|
|
1149
|
+
.where(eq(walletAutoWithdrawalConfig.singletonKey, 'global'));
|
|
1150
|
+
const rows = await txn
|
|
1151
|
+
.insert(walletAutoWithdrawalConfig)
|
|
1152
|
+
.values({
|
|
1153
|
+
singletonKey: 'global',
|
|
1154
|
+
fiatThreshold,
|
|
1155
|
+
cryptoThreshold,
|
|
1156
|
+
excludeRiskFlags,
|
|
1157
|
+
updatedBy: adminId,
|
|
1158
|
+
})
|
|
1159
|
+
.onConflictDoUpdate({
|
|
1160
|
+
target: walletAutoWithdrawalConfig.singletonKey,
|
|
1161
|
+
set: { fiatThreshold, cryptoThreshold, excludeRiskFlags, updatedBy: adminId },
|
|
1162
|
+
})
|
|
1163
|
+
.returning();
|
|
1164
|
+
const config = toAutoWithdrawalConfigDto(findOneOrThrow(rows, new AutoWithdrawalConfigNotFoundError('global')));
|
|
1165
|
+
await this.audit.recordInTransaction(txn, {
|
|
1166
|
+
actorId: adminId,
|
|
1167
|
+
actorType: 'admin',
|
|
1168
|
+
action: 'wallet.auto_withdrawal_config.set',
|
|
1169
|
+
resourceType: 'auto_withdrawal_config',
|
|
1170
|
+
resourceId: config.id,
|
|
1171
|
+
before: before
|
|
1172
|
+
? {
|
|
1173
|
+
fiatThreshold: before.fiatThreshold,
|
|
1174
|
+
cryptoThreshold: before.cryptoThreshold,
|
|
1175
|
+
excludeRiskFlags: before.excludeRiskFlags,
|
|
1176
|
+
}
|
|
1177
|
+
: null,
|
|
1178
|
+
after: {
|
|
1179
|
+
fiatThreshold: config.fiatThreshold,
|
|
1180
|
+
cryptoThreshold: config.cryptoThreshold,
|
|
1181
|
+
excludeRiskFlags: config.excludeRiskFlags,
|
|
1182
|
+
},
|
|
1183
|
+
...meta,
|
|
1184
|
+
});
|
|
1185
|
+
return config;
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
async getBonusRolloverStatus(userId, status = 'active') {
|
|
1189
|
+
const rows = await this.drizzle.db
|
|
1190
|
+
.select()
|
|
1191
|
+
.from(walletBonusCredit)
|
|
1192
|
+
.where(and(eq(walletBonusCredit.userId, userId), eq(walletBonusCredit.status, status)))
|
|
1193
|
+
.orderBy(desc(walletBonusCredit.createdAt))
|
|
1194
|
+
.limit(50);
|
|
1195
|
+
return { credits: rows.map(toBonusCreditDto) };
|
|
1196
|
+
}
|
|
1197
|
+
async getBonusRolloverConfig() {
|
|
1198
|
+
const config = await this.getBonusRolloverConfigOrNull();
|
|
1199
|
+
if (!config) {
|
|
1200
|
+
throw new BonusRolloverConfigNotFoundError('global');
|
|
1201
|
+
}
|
|
1202
|
+
return config;
|
|
1203
|
+
}
|
|
1204
|
+
async getBonusRolloverConfigOrNull() {
|
|
1205
|
+
const [row] = await this.drizzle.db
|
|
1206
|
+
.select()
|
|
1207
|
+
.from(walletBonusRolloverConfig)
|
|
1208
|
+
.where(eq(walletBonusRolloverConfig.singletonKey, 'global'));
|
|
1209
|
+
return row ? toBonusRolloverConfigDto(row) : null;
|
|
1210
|
+
}
|
|
1211
|
+
async setBonusRolloverConfig(adminId, { multiplier }, meta) {
|
|
1212
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1213
|
+
const [before] = await txn
|
|
1214
|
+
.select()
|
|
1215
|
+
.from(walletBonusRolloverConfig)
|
|
1216
|
+
.where(eq(walletBonusRolloverConfig.singletonKey, 'global'));
|
|
1217
|
+
const rows = await txn
|
|
1218
|
+
.insert(walletBonusRolloverConfig)
|
|
1219
|
+
.values({ singletonKey: 'global', multiplier, updatedBy: adminId })
|
|
1220
|
+
.onConflictDoUpdate({
|
|
1221
|
+
target: walletBonusRolloverConfig.singletonKey,
|
|
1222
|
+
set: { multiplier, updatedBy: adminId, updatedAt: new Date() },
|
|
1223
|
+
})
|
|
1224
|
+
.returning();
|
|
1225
|
+
const config = toBonusRolloverConfigDto(findOneOrThrow(rows, new BonusRolloverConfigNotFoundError('global')));
|
|
1226
|
+
await this.audit.recordInTransaction(txn, {
|
|
1227
|
+
actorId: adminId,
|
|
1228
|
+
actorType: 'admin',
|
|
1229
|
+
action: 'wallet.bonus_rollover_config.set',
|
|
1230
|
+
resourceType: 'bonus_rollover_config',
|
|
1231
|
+
resourceId: config.id,
|
|
1232
|
+
before: before ? { multiplier: before.multiplier } : null,
|
|
1233
|
+
after: { multiplier: config.multiplier },
|
|
1234
|
+
...meta,
|
|
1235
|
+
});
|
|
1236
|
+
return config;
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
async listWalletAssets() {
|
|
1240
|
+
const rows = await this.drizzle.db
|
|
1241
|
+
.select()
|
|
1242
|
+
.from(walletAsset)
|
|
1243
|
+
.orderBy(asc(walletAsset.currency), asc(walletAsset.network));
|
|
1244
|
+
return rows.map(toWalletAssetDto);
|
|
1245
|
+
}
|
|
1246
|
+
listEnabledWalletAssets() {
|
|
1247
|
+
return this.drizzle.db
|
|
1248
|
+
.select(PUBLIC_ASSET_COLUMNS)
|
|
1249
|
+
.from(walletAsset)
|
|
1250
|
+
.where(or(eq(walletAsset.depositEnabled, true), eq(walletAsset.withdrawalEnabled, true)))
|
|
1251
|
+
.orderBy(asc(walletAsset.currency), asc(walletAsset.network));
|
|
1252
|
+
}
|
|
1253
|
+
async getWalletAsset(currency, network) {
|
|
1254
|
+
const [row] = await this.drizzle.db
|
|
1255
|
+
.select()
|
|
1256
|
+
.from(walletAsset)
|
|
1257
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1258
|
+
return row ? toWalletAssetDto(row) : null;
|
|
1259
|
+
}
|
|
1260
|
+
// The catalog is operator-editable, so an admin can name a pair the bound vendor has
|
|
1261
|
+
// never heard of. Reject at write time rather than at a player's deposit request.
|
|
1262
|
+
assertAdapterSupports(currency, network) {
|
|
1263
|
+
if (this.payment.supportsAsset && !this.payment.supportsAsset(currency, network)) {
|
|
1264
|
+
throw new WalletAssetUnsupportedError();
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
// Same discipline as assertAdapterSupports, for the provider key itself: an
|
|
1268
|
+
// unvalidated typo silently falls back to the default adapter, which means eg a
|
|
1269
|
+
// crypto payout attempted through a PSP. Undefined (the default binding) always passes.
|
|
1270
|
+
assertProviderNameValid(providerName) {
|
|
1271
|
+
if (providerName !== undefined && !this.paymentProviders.names().includes(providerName)) {
|
|
1272
|
+
throw new WalletAssetUnknownProviderError();
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
async createWalletAsset(adminId, input, meta) {
|
|
1276
|
+
this.assertAdapterSupports(input.currency, input.network);
|
|
1277
|
+
this.assertProviderNameValid(input.providerName);
|
|
1278
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1279
|
+
const rows = await txn.insert(walletAsset).values(input).onConflictDoNothing().returning();
|
|
1280
|
+
// Empty => the (currency, network) unique index rejected it.
|
|
1281
|
+
const asset = toWalletAssetDto(findOneOrThrow(rows, new WalletAssetAlreadyExistsError()));
|
|
1282
|
+
await this.audit.recordInTransaction(txn, {
|
|
1283
|
+
actorId: adminId,
|
|
1284
|
+
actorType: 'admin',
|
|
1285
|
+
action: 'wallet.wallet_asset.created',
|
|
1286
|
+
resourceType: 'wallet_asset',
|
|
1287
|
+
resourceId: asset.id,
|
|
1288
|
+
before: null,
|
|
1289
|
+
after: asset,
|
|
1290
|
+
...meta,
|
|
1291
|
+
});
|
|
1292
|
+
return asset;
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
// Deliberately touches only the catalog row: a withdrawal already pending or processing
|
|
1296
|
+
// in this currency keeps its own terms and is never cancelled by disabling the pair.
|
|
1297
|
+
async updateWalletAsset(adminId, { currency, network, ...changes }, meta) {
|
|
1298
|
+
if (changes.providerAssetId !== undefined) {
|
|
1299
|
+
this.assertAdapterSupports(currency, network);
|
|
1300
|
+
}
|
|
1301
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1302
|
+
const [before] = await txn
|
|
1303
|
+
.select()
|
|
1304
|
+
.from(walletAsset)
|
|
1305
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1306
|
+
if (!before) {
|
|
1307
|
+
throw new WalletAssetNotFoundError(`${currency}/${network}`);
|
|
1308
|
+
}
|
|
1309
|
+
const rows = await txn
|
|
1310
|
+
.update(walletAsset)
|
|
1311
|
+
.set(changes)
|
|
1312
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)))
|
|
1313
|
+
.returning();
|
|
1314
|
+
const asset = toWalletAssetDto(findOneOrThrow(rows, new WalletAssetNotFoundError(`${currency}/${network}`)));
|
|
1315
|
+
await this.audit.recordInTransaction(txn, {
|
|
1316
|
+
actorId: adminId,
|
|
1317
|
+
actorType: 'admin',
|
|
1318
|
+
action: 'wallet.wallet_asset.updated',
|
|
1319
|
+
resourceType: 'wallet_asset',
|
|
1320
|
+
resourceId: asset.id,
|
|
1321
|
+
before: toWalletAssetDto(before),
|
|
1322
|
+
after: asset,
|
|
1323
|
+
...meta,
|
|
1324
|
+
});
|
|
1325
|
+
return asset;
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
async deleteWalletAsset(adminId, currency, network, meta) {
|
|
1329
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1330
|
+
const [before] = await txn
|
|
1331
|
+
.select()
|
|
1332
|
+
.from(walletAsset)
|
|
1333
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1334
|
+
if (!before) {
|
|
1335
|
+
return false;
|
|
1336
|
+
}
|
|
1337
|
+
// wallet_balance is keyed by currency only (no network column), so this guard is
|
|
1338
|
+
// necessarily currency-wide: removing one network of a currency players still hold
|
|
1339
|
+
// is blocked even if their balance arrived over another network. Fails safe.
|
|
1340
|
+
const [held] = await txn
|
|
1341
|
+
.select({ n: count() })
|
|
1342
|
+
.from(walletBalance)
|
|
1343
|
+
.where(and(eq(walletBalance.currency, currency), sql `${walletBalance.amount} > 0`));
|
|
1344
|
+
if ((held?.n ?? 0) > 0) {
|
|
1345
|
+
throw new WalletAssetInUseError();
|
|
1346
|
+
}
|
|
1347
|
+
// Renaming a pair is a delete plus a create (the (currency, network) key AND
|
|
1348
|
+
// providerName are immutable), so this delete is the only way providerName ever
|
|
1349
|
+
// effectively changes. Block it while a pending/processing transaction exists for
|
|
1350
|
+
// this exact (currency, network) pair - otherwise the vendor reference an in-flight
|
|
1351
|
+
// payout is settling through gets rewritten out from under it.
|
|
1352
|
+
const [inFlight] = await txn
|
|
1353
|
+
.select({ n: count() })
|
|
1354
|
+
.from(walletTransaction)
|
|
1355
|
+
.where(and(eq(walletTransaction.currency, currency), eq(walletTransaction.network, network), inArray(walletTransaction.status, ['pending', 'processing'])));
|
|
1356
|
+
if ((inFlight?.n ?? 0) > 0) {
|
|
1357
|
+
throw new WalletAssetHasInFlightTransactionsError();
|
|
1358
|
+
}
|
|
1359
|
+
await txn
|
|
1360
|
+
.delete(walletAsset)
|
|
1361
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1362
|
+
await this.audit.recordInTransaction(txn, {
|
|
1363
|
+
actorId: adminId,
|
|
1364
|
+
actorType: 'admin',
|
|
1365
|
+
action: 'wallet.wallet_asset.deleted',
|
|
1366
|
+
resourceType: 'wallet_asset',
|
|
1367
|
+
resourceId: before.id,
|
|
1368
|
+
before: toWalletAssetDto(before),
|
|
1369
|
+
after: null,
|
|
1370
|
+
...meta,
|
|
1371
|
+
});
|
|
1372
|
+
return true;
|
|
1373
|
+
});
|
|
563
1374
|
}
|
|
564
1375
|
async autoApprovalKycStatus(userId) {
|
|
565
1376
|
// No directory bound => cannot verify KYC => fail closed.
|
|
566
|
-
if (!this.directory)
|
|
1377
|
+
if (!this.directory) {
|
|
567
1378
|
return null;
|
|
1379
|
+
}
|
|
568
1380
|
const [summary] = await this.directory.lookupPlayers([userId]);
|
|
569
1381
|
return summary?.kycStatus ?? null;
|
|
570
1382
|
}
|
|
571
1383
|
// Active tag keys; [] when no exclusions configured or none carried; null when configured but the port is unbound (fail closed).
|
|
572
1384
|
async autoApprovalRiskTags(userId, excludeRiskFlags) {
|
|
573
|
-
if (excludeRiskFlags.length === 0)
|
|
1385
|
+
if (excludeRiskFlags.length === 0) {
|
|
574
1386
|
return [];
|
|
575
|
-
|
|
1387
|
+
}
|
|
1388
|
+
if (!this.riskTags) {
|
|
576
1389
|
return null;
|
|
1390
|
+
}
|
|
577
1391
|
const byUser = await this.riskTags.getActiveTagKeys([userId]);
|
|
578
1392
|
return byUser.get(userId) ?? [];
|
|
579
1393
|
}
|
|
580
1394
|
async autoApprovalHeuristics({ walletId, amount, }) {
|
|
581
1395
|
const frequent = await this.frequentWithdrawalWalletIds(this.drizzle.db, [walletId]);
|
|
582
1396
|
return {
|
|
583
|
-
largeAmount: amount >= LARGE_WITHDRAWAL_THRESHOLD,
|
|
1397
|
+
largeAmount: moneyToNumber(amount) >= moneyToNumber(LARGE_WITHDRAWAL_THRESHOLD),
|
|
584
1398
|
highFrequency: frequent.has(walletId),
|
|
585
1399
|
};
|
|
586
1400
|
}
|
|
@@ -588,8 +1402,9 @@ export class WalletService {
|
|
|
588
1402
|
// Single source of the velocity check, shared by the review queue tag and the auto-approval heuristic.
|
|
589
1403
|
async frequentWithdrawalWalletIds(db, walletIds) {
|
|
590
1404
|
const frequent = new Set();
|
|
591
|
-
if (walletIds.length === 0)
|
|
1405
|
+
if (walletIds.length === 0) {
|
|
592
1406
|
return frequent;
|
|
1407
|
+
}
|
|
593
1408
|
const since = new Date(Date.now() - HIGH_FREQUENCY_WINDOW_MS);
|
|
594
1409
|
const counts = await db
|
|
595
1410
|
.select({ walletId: walletTransaction.walletId, n: count() })
|
|
@@ -597,8 +1412,9 @@ export class WalletService {
|
|
|
597
1412
|
.where(and(eq(walletTransaction.type, 'withdrawal'), gte(walletTransaction.createdAt, since), inArray(walletTransaction.walletId, walletIds)))
|
|
598
1413
|
.groupBy(walletTransaction.walletId);
|
|
599
1414
|
for (const row of counts) {
|
|
600
|
-
if (Number(row.n) >= HIGH_FREQUENCY_MIN_COUNT)
|
|
1415
|
+
if (Number(row.n) >= HIGH_FREQUENCY_MIN_COUNT) {
|
|
601
1416
|
frequent.add(row.walletId);
|
|
1417
|
+
}
|
|
602
1418
|
}
|
|
603
1419
|
return frequent;
|
|
604
1420
|
}
|
|
@@ -607,24 +1423,30 @@ export class WalletService {
|
|
|
607
1423
|
async autoApprovalCaps({ walletId, amount, cfg, }, db) {
|
|
608
1424
|
const since = new Date(Date.now() - DAILY_CAP_WINDOW_MS);
|
|
609
1425
|
const [row] = await db
|
|
610
|
-
.select({
|
|
1426
|
+
.select({
|
|
1427
|
+
total: sql `coalesce(sum(${walletTransaction.amount}), 0)`,
|
|
1428
|
+
n: count(),
|
|
1429
|
+
})
|
|
611
1430
|
.from(walletTransaction)
|
|
612
1431
|
.where(and(eq(walletTransaction.walletId, walletId), eq(walletTransaction.type, 'withdrawal'), eq(walletTransaction.reviewReason, AUTO_APPROVED_REASON), gte(walletTransaction.createdAt, since)));
|
|
613
|
-
const amountUsed =
|
|
1432
|
+
const amountUsed = row?.total ?? '0';
|
|
614
1433
|
const countUsed = Number(row?.n ?? 0);
|
|
615
|
-
|
|
1434
|
+
// Cap comparison is a review-queue decision, not a ledger write - moneyToNumber is the
|
|
1435
|
+
// documented single conversion point (see the helper's own doc comment).
|
|
1436
|
+
const amountExceeded = cfg.dailyCapAmount !== undefined &&
|
|
1437
|
+
moneyToNumber(amountUsed) + moneyToNumber(amount) > moneyToNumber(cfg.dailyCapAmount);
|
|
616
1438
|
const countExceeded = cfg.dailyCapCount !== undefined && countUsed + 1 > cfg.dailyCapCount;
|
|
617
1439
|
return { exceeded: amountExceeded || countExceeded, amountUsed, countUsed };
|
|
618
1440
|
}
|
|
619
1441
|
async setAutoWithdrawalRule({ userId, threshold, reason, createdBy, }) {
|
|
620
|
-
const
|
|
1442
|
+
const row = findOneOrThrow(await this.drizzle.db
|
|
621
1443
|
.insert(autoWithdrawalRule)
|
|
622
|
-
.values({ userId, threshold
|
|
1444
|
+
.values({ userId, threshold, reason, createdBy })
|
|
623
1445
|
.onConflictDoUpdate({
|
|
624
1446
|
target: autoWithdrawalRule.userId,
|
|
625
|
-
set: { threshold
|
|
1447
|
+
set: { threshold, reason, createdBy },
|
|
626
1448
|
})
|
|
627
|
-
.returning();
|
|
1449
|
+
.returning(), new WalletNotFoundError(userId));
|
|
628
1450
|
return toAutoWithdrawalRuleDto(row);
|
|
629
1451
|
}
|
|
630
1452
|
async getAutoWithdrawalRule(userId) {
|
|
@@ -641,7 +1463,7 @@ export class WalletService {
|
|
|
641
1463
|
.returning({ id: autoWithdrawalRule.id });
|
|
642
1464
|
return deleted.length > 0;
|
|
643
1465
|
}
|
|
644
|
-
async rejectWithdrawal(adminId, withdrawalId, reason) {
|
|
1466
|
+
async rejectWithdrawal(adminId, withdrawalId, reason, meta) {
|
|
645
1467
|
const reviewedAt = new Date();
|
|
646
1468
|
const tx = await this.drizzle.db.transaction(async (txn) => {
|
|
647
1469
|
const current = findOneOrThrow(await txn
|
|
@@ -652,40 +1474,51 @@ export class WalletService {
|
|
|
652
1474
|
if (current.status !== 'pending' || current.type !== 'withdrawal') {
|
|
653
1475
|
throw new WithdrawalNotPendingError();
|
|
654
1476
|
}
|
|
655
|
-
const
|
|
1477
|
+
const updated = findOneOrThrow(await txn
|
|
656
1478
|
.update(walletTransaction)
|
|
657
1479
|
.set({ status: 'rejected', reviewedBy: adminId, reviewedAt, reviewReason: reason })
|
|
658
1480
|
.where(eq(walletTransaction.id, withdrawalId))
|
|
659
|
-
.returning();
|
|
660
|
-
await txn
|
|
661
|
-
.update(wallet)
|
|
662
|
-
.set({ balance: sql `${wallet.balance} + ${updated.amount}` })
|
|
663
|
-
.where(eq(wallet.id, updated.walletId));
|
|
1481
|
+
.returning(), new WithdrawalNotFoundError(withdrawalId));
|
|
1482
|
+
await creditWalletBalance(txn, updated.walletId, updated.currency, updated.amount);
|
|
664
1483
|
return updated;
|
|
665
1484
|
});
|
|
666
1485
|
const userId = await this.userIdForWallet(tx.walletId);
|
|
667
1486
|
this.events.emit('wallet.withdrawal.rejected', {
|
|
668
1487
|
userId,
|
|
669
|
-
amount:
|
|
1488
|
+
amount: tx.amount,
|
|
670
1489
|
currency: tx.currency,
|
|
671
1490
|
transactionId: tx.id,
|
|
672
1491
|
adminId,
|
|
673
1492
|
reason,
|
|
1493
|
+
ip: meta?.ip ?? null,
|
|
1494
|
+
userAgent: meta?.userAgent ?? null,
|
|
674
1495
|
});
|
|
675
1496
|
return { transactionId: tx.id, status: 'rejected' };
|
|
676
1497
|
}
|
|
677
|
-
async getTransactions(userId, page, limit) {
|
|
1498
|
+
async getTransactions({ userId, page, limit, sortBy, sortOrder, includeInternal = false, }) {
|
|
678
1499
|
const db = this.drizzle.db;
|
|
679
1500
|
const [walletRecord] = await db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
680
|
-
if (!walletRecord)
|
|
1501
|
+
if (!walletRecord) {
|
|
681
1502
|
return { items: [], total: 0, page, limit };
|
|
1503
|
+
}
|
|
1504
|
+
const dir = (sortOrder ?? 'desc') === 'asc' ? asc : desc;
|
|
1505
|
+
const TX_SORT_COLS = {
|
|
1506
|
+
createdAt: walletTransaction.createdAt,
|
|
1507
|
+
amount: walletTransaction.amount,
|
|
1508
|
+
type: walletTransaction.type,
|
|
1509
|
+
status: walletTransaction.status,
|
|
1510
|
+
currency: walletTransaction.currency,
|
|
1511
|
+
rail: walletTransaction.rail,
|
|
1512
|
+
reviewedAt: walletTransaction.reviewedAt,
|
|
1513
|
+
};
|
|
1514
|
+
const col = TX_SORT_COLS[sortBy ?? 'createdAt'];
|
|
682
1515
|
const where = eq(walletTransaction.walletId, walletRecord.id);
|
|
683
1516
|
const [txs, [{ n }]] = await Promise.all([
|
|
684
1517
|
db
|
|
685
1518
|
.select()
|
|
686
1519
|
.from(walletTransaction)
|
|
687
1520
|
.where(where)
|
|
688
|
-
.orderBy(desc(walletTransaction.
|
|
1521
|
+
.orderBy(dir(col), desc(walletTransaction.id))
|
|
689
1522
|
.limit(limit)
|
|
690
1523
|
.offset(pageToOffset(page, limit)),
|
|
691
1524
|
db.select({ n: count() }).from(walletTransaction).where(where),
|
|
@@ -694,16 +1527,155 @@ export class WalletService {
|
|
|
694
1527
|
items: txs.map((tx) => ({
|
|
695
1528
|
id: tx.id,
|
|
696
1529
|
type: tx.type,
|
|
697
|
-
amount:
|
|
1530
|
+
amount: tx.amount,
|
|
698
1531
|
currency: tx.currency,
|
|
1532
|
+
network: tx.network,
|
|
699
1533
|
status: tx.status,
|
|
700
1534
|
createdAt: tx.createdAt.toISOString(),
|
|
1535
|
+
reviewedBy: includeInternal ? tx.reviewedBy : null,
|
|
1536
|
+
reviewedAt: includeInternal ? (tx.reviewedAt?.toISOString() ?? null) : null,
|
|
1537
|
+
reviewReason: includeInternal ? tx.reviewReason : null,
|
|
701
1538
|
})),
|
|
702
1539
|
total: Number(n),
|
|
703
1540
|
page,
|
|
704
1541
|
limit,
|
|
705
1542
|
};
|
|
706
1543
|
}
|
|
1544
|
+
async getOrCreateDepositAddress(userId, currency, network) {
|
|
1545
|
+
const existing = await this.findDepositAddress(userId, currency, network);
|
|
1546
|
+
if (existing) {
|
|
1547
|
+
return toDepositAddressResult(existing);
|
|
1548
|
+
}
|
|
1549
|
+
if (!this.payment.issueDepositAddress) {
|
|
1550
|
+
throw new DepositAddressUnsupportedError();
|
|
1551
|
+
}
|
|
1552
|
+
const issued = await this.payment.issueDepositAddress(userId, currency, network);
|
|
1553
|
+
const [row] = await this.drizzle.db
|
|
1554
|
+
.insert(walletDepositAddress)
|
|
1555
|
+
.values({
|
|
1556
|
+
userId,
|
|
1557
|
+
currency,
|
|
1558
|
+
network: network ?? null,
|
|
1559
|
+
address: issued.address,
|
|
1560
|
+
tag: issued.tag ?? null,
|
|
1561
|
+
providerName: await this.providerNameFor(currency, network ?? null),
|
|
1562
|
+
})
|
|
1563
|
+
.onConflictDoNothing()
|
|
1564
|
+
.returning();
|
|
1565
|
+
if (row) {
|
|
1566
|
+
return toDepositAddressResult(row);
|
|
1567
|
+
}
|
|
1568
|
+
const winner = await this.findDepositAddress(userId, currency, network);
|
|
1569
|
+
if (!winner) {
|
|
1570
|
+
throw new Error(`wallet deposit address: idempotency conflict but no row found (userId=${userId}, currency=${currency}, network=${network ?? 'none'})`);
|
|
1571
|
+
}
|
|
1572
|
+
return toDepositAddressResult(winner);
|
|
1573
|
+
}
|
|
1574
|
+
/**
|
|
1575
|
+
* `providerName` is the vendor the webhook route already resolved (verifier + adapter
|
|
1576
|
+
* came from the same registry entry) - it is only used to label a finding when this
|
|
1577
|
+
* deposit can't be attributed, never to look anything up. Defaults to the single
|
|
1578
|
+
* default binding for callers (tests, a poller with no named provider) that don't care.
|
|
1579
|
+
*/
|
|
1580
|
+
async creditDepositByAddress(event, providerName = DEFAULT_PAYMENT_PROVIDER) {
|
|
1581
|
+
const depositAddress = await this.findDepositAddressByAddress(event);
|
|
1582
|
+
if (!depositAddress) {
|
|
1583
|
+
// A known vendor defect hits this live: a token deposit reported under a sibling
|
|
1584
|
+
// token's asset id never resolves to a row. Never let it survive only as a log
|
|
1585
|
+
// line - file a finding so an operator can attribute and manually credit it.
|
|
1586
|
+
logger.warn({ address: event.address, network: event.network, tag: event.tag }, 'payment webhook: no wallet_deposit_address for inbound deposit');
|
|
1587
|
+
await recordReconciliationFinding(this.drizzle.db, {
|
|
1588
|
+
runId: LIVE_WEBHOOK_RUN_ID,
|
|
1589
|
+
providerName,
|
|
1590
|
+
kind: 'unattributed_deposit',
|
|
1591
|
+
currency: event.currency,
|
|
1592
|
+
network: event.network ?? null,
|
|
1593
|
+
amount: event.amount,
|
|
1594
|
+
address: event.address,
|
|
1595
|
+
tag: event.tag ?? null,
|
|
1596
|
+
txHash: event.txHash,
|
|
1597
|
+
externalId: event.externalId,
|
|
1598
|
+
detail: 'no wallet_deposit_address matched this address/network/tag',
|
|
1599
|
+
});
|
|
1600
|
+
return;
|
|
1601
|
+
}
|
|
1602
|
+
if (event.network === undefined &&
|
|
1603
|
+
event.currency.toUpperCase() !== depositAddress.currency.toUpperCase()) {
|
|
1604
|
+
// Same "do not silently drop" discipline as the no-address branch above - this is
|
|
1605
|
+
// the push-path counterpart to the poll-path's currency_mismatch finding.
|
|
1606
|
+
logger.warn({
|
|
1607
|
+
address: event.address,
|
|
1608
|
+
eventCurrency: event.currency,
|
|
1609
|
+
addressCurrency: depositAddress.currency,
|
|
1610
|
+
}, 'payment webhook: currency mismatch for inbound deposit');
|
|
1611
|
+
await recordReconciliationFinding(this.drizzle.db, {
|
|
1612
|
+
runId: LIVE_WEBHOOK_RUN_ID,
|
|
1613
|
+
providerName: depositAddress.providerName,
|
|
1614
|
+
kind: 'currency_mismatch',
|
|
1615
|
+
currency: event.currency,
|
|
1616
|
+
network: event.network ?? depositAddress.network,
|
|
1617
|
+
amount: event.amount,
|
|
1618
|
+
address: event.address,
|
|
1619
|
+
tag: event.tag ?? null,
|
|
1620
|
+
txHash: event.txHash,
|
|
1621
|
+
externalId: event.externalId,
|
|
1622
|
+
detail: `currency mismatch: event reported ${event.currency}, address issued for ${depositAddress.currency}`,
|
|
1623
|
+
});
|
|
1624
|
+
return;
|
|
1625
|
+
}
|
|
1626
|
+
const { transactionId, replayed } = await this.drizzle.db.transaction(async (txn) => {
|
|
1627
|
+
let [walletRecord] = await txn
|
|
1628
|
+
.select()
|
|
1629
|
+
.from(wallet)
|
|
1630
|
+
.where(eq(wallet.userId, depositAddress.userId));
|
|
1631
|
+
if (!walletRecord) {
|
|
1632
|
+
walletRecord = findOneOrThrow(await txn
|
|
1633
|
+
.insert(wallet)
|
|
1634
|
+
.values({ userId: depositAddress.userId, currency: event.currency })
|
|
1635
|
+
.returning(), new WalletNotFoundError(depositAddress.userId));
|
|
1636
|
+
}
|
|
1637
|
+
const [inserted] = await txn
|
|
1638
|
+
.insert(walletTransaction)
|
|
1639
|
+
.values({
|
|
1640
|
+
walletId: walletRecord.id,
|
|
1641
|
+
type: 'deposit',
|
|
1642
|
+
amount: event.amount,
|
|
1643
|
+
currency: event.currency,
|
|
1644
|
+
status: 'completed',
|
|
1645
|
+
rail: this.resolveRail(event.currency),
|
|
1646
|
+
// Prefer the chain the vendor reported; fall back to the one the address was
|
|
1647
|
+
// issued on, which is the only network an address-only webhook can imply.
|
|
1648
|
+
network: event.network ?? depositAddress.network,
|
|
1649
|
+
providerName: depositAddress.providerName,
|
|
1650
|
+
providerRefId: event.externalId,
|
|
1651
|
+
destinationAddress: event.address,
|
|
1652
|
+
txHash: event.txHash,
|
|
1653
|
+
})
|
|
1654
|
+
.onConflictDoNothing()
|
|
1655
|
+
.returning();
|
|
1656
|
+
if (inserted) {
|
|
1657
|
+
await creditWalletBalance(txn, walletRecord.id, event.currency, event.amount);
|
|
1658
|
+
return { transactionId: inserted.id, replayed: false };
|
|
1659
|
+
}
|
|
1660
|
+
const [winner] = await txn
|
|
1661
|
+
.select()
|
|
1662
|
+
.from(walletTransaction)
|
|
1663
|
+
.where(eq(walletTransaction.providerRefId, event.externalId));
|
|
1664
|
+
if (!winner) {
|
|
1665
|
+
throw new Error(`payment webhook: idempotency conflict but no row found (externalId=${event.externalId})`);
|
|
1666
|
+
}
|
|
1667
|
+
return { transactionId: winner.id, replayed: true };
|
|
1668
|
+
});
|
|
1669
|
+
if (!replayed) {
|
|
1670
|
+
this.events.emit('wallet.deposit.completed', {
|
|
1671
|
+
userId: depositAddress.userId,
|
|
1672
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(depositAddress.userId),
|
|
1673
|
+
amount: event.amount,
|
|
1674
|
+
currency: event.currency,
|
|
1675
|
+
transactionId,
|
|
1676
|
+
});
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
707
1679
|
async userIdForWallet(walletId) {
|
|
708
1680
|
const record = findOneOrThrow(await this.drizzle.db
|
|
709
1681
|
.select({ userId: wallet.userId })
|
|
@@ -718,5 +1690,179 @@ export class WalletService {
|
|
|
718
1690
|
.where(and(eq(walletTransaction.walletId, walletId), eq(walletTransaction.idempotencyKey, idempotencyKey)));
|
|
719
1691
|
return existing;
|
|
720
1692
|
}
|
|
1693
|
+
async findDepositAddress(userId, currency, network) {
|
|
1694
|
+
const [row] = await this.drizzle.db
|
|
1695
|
+
.select()
|
|
1696
|
+
.from(walletDepositAddress)
|
|
1697
|
+
.where(and(eq(walletDepositAddress.userId, userId), eq(walletDepositAddress.currency, currency), network === undefined
|
|
1698
|
+
? isNull(walletDepositAddress.network)
|
|
1699
|
+
: eq(walletDepositAddress.network, network)));
|
|
1700
|
+
return row;
|
|
1701
|
+
}
|
|
1702
|
+
async findDepositAddressByAddress({ address, network, tag, }) {
|
|
1703
|
+
const rows = await this.drizzle.db
|
|
1704
|
+
.select()
|
|
1705
|
+
.from(walletDepositAddress)
|
|
1706
|
+
.where(and(eq(walletDepositAddress.address, address), tag === undefined ? isNull(walletDepositAddress.tag) : eq(walletDepositAddress.tag, tag), network === undefined
|
|
1707
|
+
? undefined
|
|
1708
|
+
: or(eq(walletDepositAddress.network, network), isNull(walletDepositAddress.network))));
|
|
1709
|
+
const owners = new Set(rows.map((row) => row.userId));
|
|
1710
|
+
if (owners.size > 1) {
|
|
1711
|
+
throw new AmbiguousDepositAddressError(address, network);
|
|
1712
|
+
}
|
|
1713
|
+
return rows.find((row) => row.network === network) ?? rows[0];
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* The player's own payout address book. Every method here is scoped on `userId` - a
|
|
1717
|
+
* saved address is personal data with no admin read path, so there is
|
|
1718
|
+
* deliberately no variant of these that takes an arbitrary user id.
|
|
1719
|
+
*/
|
|
1720
|
+
async listWithdrawalAddresses(userId, currency) {
|
|
1721
|
+
const rows = await this.drizzle.db
|
|
1722
|
+
.select()
|
|
1723
|
+
.from(walletWithdrawalAddress)
|
|
1724
|
+
.where(and(eq(walletWithdrawalAddress.userId, userId), currency === undefined ? undefined : eq(walletWithdrawalAddress.currency, currency)))
|
|
1725
|
+
.orderBy(desc(walletWithdrawalAddress.createdAt));
|
|
1726
|
+
return rows.map(toWithdrawalAddressDto);
|
|
1727
|
+
}
|
|
1728
|
+
async createWithdrawalAddress(userId, input, meta) {
|
|
1729
|
+
// Shares the wallet mutation budget with deposit/withdraw: the row cap alone does
|
|
1730
|
+
// not bound writes, since deleting frees a slot and lets a client churn forever.
|
|
1731
|
+
await this.rateLimit(userId);
|
|
1732
|
+
// ponytail: count-then-insert, so N concurrent creates can land N over the cap.
|
|
1733
|
+
// Move to an insert...where (select count) < limit if that ever matters.
|
|
1734
|
+
const [existing] = await this.drizzle.db
|
|
1735
|
+
.select({ total: count() })
|
|
1736
|
+
.from(walletWithdrawalAddress)
|
|
1737
|
+
.where(eq(walletWithdrawalAddress.userId, userId));
|
|
1738
|
+
if ((existing?.total ?? 0) >= WITHDRAWAL_ADDRESS_LIMIT) {
|
|
1739
|
+
throw new WithdrawalAddressLimitReachedError(WITHDRAWAL_ADDRESS_LIMIT);
|
|
1740
|
+
}
|
|
1741
|
+
// Registered with the custody provider BEFORE the row exists, so a rejected or unreachable
|
|
1742
|
+
// provider leaves no saved address the player would believe they can withdraw to. The port
|
|
1743
|
+
// is required to be idempotent, so the conflict path below cannot orphan a destination.
|
|
1744
|
+
const whitelisted = await this.whitelistWithdrawalAddress(userId, input);
|
|
1745
|
+
// onConflictDoNothing turns the unique index into a domain conflict rather than a
|
|
1746
|
+
// 500 - a double-submitted form is a 409, not an incident.
|
|
1747
|
+
const [row] = await this.drizzle.db
|
|
1748
|
+
.insert(walletWithdrawalAddress)
|
|
1749
|
+
.values({ userId, ...input, ...whitelisted })
|
|
1750
|
+
.onConflictDoNothing()
|
|
1751
|
+
.returning();
|
|
1752
|
+
if (!row) {
|
|
1753
|
+
throw new WithdrawalAddressAlreadyExistsError();
|
|
1754
|
+
}
|
|
1755
|
+
await this.audit.record({
|
|
1756
|
+
actorId: userId,
|
|
1757
|
+
actorType: 'player',
|
|
1758
|
+
action: 'wallet.withdrawal_address.created',
|
|
1759
|
+
resourceType: 'wallet_withdrawal_address',
|
|
1760
|
+
resourceId: row.id,
|
|
1761
|
+
// The address string is deliberately absent: the audit log is admin-readable and
|
|
1762
|
+
// a player's saved addresses are not. The row id is enough to correlate.
|
|
1763
|
+
after: { label: row.label, currency: row.currency, network: row.network },
|
|
1764
|
+
...meta,
|
|
1765
|
+
});
|
|
1766
|
+
return toWithdrawalAddressDto(row);
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Refuses a payout to an address the provider has not approved. A no-op for an adapter that
|
|
1770
|
+
* does not whitelist, and for a fiat rail, which has no address at all.
|
|
1771
|
+
*/
|
|
1772
|
+
async requireWhitelistedWalletId(userId, currency, network, destinationAddress) {
|
|
1773
|
+
if (!this.payment.whitelistWithdrawalAddress || !destinationAddress) {
|
|
1774
|
+
return null;
|
|
1775
|
+
}
|
|
1776
|
+
const walletId = await this.whitelistedWalletId(userId, currency, network, destinationAddress);
|
|
1777
|
+
if (!walletId) {
|
|
1778
|
+
throw new DestinationAddressNotWhitelistedError();
|
|
1779
|
+
}
|
|
1780
|
+
return walletId;
|
|
1781
|
+
}
|
|
1782
|
+
/**
|
|
1783
|
+
* The approved destination saved for this address, or null. Matched on the address itself
|
|
1784
|
+
* rather than an id on the transaction, because a withdrawal is requested by address and may
|
|
1785
|
+
* name one the player never saved.
|
|
1786
|
+
*/
|
|
1787
|
+
async whitelistedWalletId(userId, currency, network, address) {
|
|
1788
|
+
if (!this.payment.whitelistWithdrawalAddress || !address) {
|
|
1789
|
+
return null;
|
|
1790
|
+
}
|
|
1791
|
+
const providerName = await this.providerNameFor(currency, network);
|
|
1792
|
+
const [row] = await this.drizzle.db
|
|
1793
|
+
.select({
|
|
1794
|
+
id: walletWithdrawalAddress.id,
|
|
1795
|
+
network: walletWithdrawalAddress.network,
|
|
1796
|
+
providerName: walletWithdrawalAddress.providerName,
|
|
1797
|
+
providerWalletId: walletWithdrawalAddress.providerWalletId,
|
|
1798
|
+
})
|
|
1799
|
+
.from(walletWithdrawalAddress)
|
|
1800
|
+
.where(and(eq(walletWithdrawalAddress.userId, userId), eq(walletWithdrawalAddress.currency, currency), eq(walletWithdrawalAddress.address, address), ...(network ? [eq(walletWithdrawalAddress.network, network)] : [])))
|
|
1801
|
+
.limit(1);
|
|
1802
|
+
if (!row) {
|
|
1803
|
+
return null;
|
|
1804
|
+
}
|
|
1805
|
+
// An id minted by a different provider names nothing in the current one, and a row
|
|
1806
|
+
// saved while no whitelisting adapter was bound has no id at all. Both re-register
|
|
1807
|
+
// with the provider that will actually settle, rather than failing a payout on a
|
|
1808
|
+
// saved address the player cannot fix themselves.
|
|
1809
|
+
if (row.providerWalletId && row.providerName === providerName) {
|
|
1810
|
+
return row.providerWalletId;
|
|
1811
|
+
}
|
|
1812
|
+
const { providerWalletId } = await this.payment.whitelistWithdrawalAddress({
|
|
1813
|
+
userId,
|
|
1814
|
+
currency,
|
|
1815
|
+
network: row.network,
|
|
1816
|
+
address,
|
|
1817
|
+
});
|
|
1818
|
+
await this.drizzle.db
|
|
1819
|
+
.update(walletWithdrawalAddress)
|
|
1820
|
+
.set({ providerName, providerWalletId })
|
|
1821
|
+
.where(eq(walletWithdrawalAddress.id, row.id));
|
|
1822
|
+
return providerWalletId;
|
|
1823
|
+
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Delegates to the bound payment adapter when it whitelists destinations, and returns nothing
|
|
1826
|
+
* to store when it does not. A vendor failure propagates rather than being swallowed: saving
|
|
1827
|
+
* the address anyway would produce a row that looks usable and fails only once the player has
|
|
1828
|
+
* committed to a payout.
|
|
1829
|
+
*/
|
|
1830
|
+
async whitelistWithdrawalAddress(userId, input) {
|
|
1831
|
+
if (!this.payment.whitelistWithdrawalAddress) {
|
|
1832
|
+
return {};
|
|
1833
|
+
}
|
|
1834
|
+
const { providerWalletId } = await this.payment.whitelistWithdrawalAddress({
|
|
1835
|
+
userId,
|
|
1836
|
+
currency: input.currency,
|
|
1837
|
+
network: input.network,
|
|
1838
|
+
address: input.address,
|
|
1839
|
+
});
|
|
1840
|
+
return {
|
|
1841
|
+
providerName: await this.providerNameFor(input.currency, input.network),
|
|
1842
|
+
providerWalletId,
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
/** False when the row does not exist OR belongs to someone else - the caller cannot
|
|
1846
|
+
* tell the two apart, which is what stops the id space being probed. */
|
|
1847
|
+
async deleteWithdrawalAddress(userId, id, meta) {
|
|
1848
|
+
await this.rateLimit(userId);
|
|
1849
|
+
const [row] = await this.drizzle.db
|
|
1850
|
+
.delete(walletWithdrawalAddress)
|
|
1851
|
+
.where(and(eq(walletWithdrawalAddress.id, id), eq(walletWithdrawalAddress.userId, userId)))
|
|
1852
|
+
.returning();
|
|
1853
|
+
if (!row) {
|
|
1854
|
+
return false;
|
|
1855
|
+
}
|
|
1856
|
+
await this.audit.record({
|
|
1857
|
+
actorId: userId,
|
|
1858
|
+
actorType: 'player',
|
|
1859
|
+
action: 'wallet.withdrawal_address.deleted',
|
|
1860
|
+
resourceType: 'wallet_withdrawal_address',
|
|
1861
|
+
resourceId: row.id,
|
|
1862
|
+
before: { label: row.label, currency: row.currency, network: row.network },
|
|
1863
|
+
...meta,
|
|
1864
|
+
});
|
|
1865
|
+
return true;
|
|
1866
|
+
}
|
|
721
1867
|
}
|
|
722
1868
|
//# sourceMappingURL=wallet.service.js.map
|