@openora/core 0.4.1-canary.11 → 0.4.1-canary.111
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/README.md +10 -10
- 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 +284 -28
- package/dist/admin-console/contract/index.d.ts.map +1 -1
- package/dist/admin-console/contract/index.js +74 -6
- 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 +126 -18
- 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 +61 -8
- package/dist/admin-console/service/backoffice.service.d.ts.map +1 -1
- package/dist/admin-console/service/backoffice.service.js +67 -11
- 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 +642 -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 +54 -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 +22 -4
- package/dist/audit/contract/index.js.map +1 -1
- package/dist/audit/migrate.d.ts.map +1 -1
- package/dist/audit/migrate.js +12 -0
- package/dist/audit/migrate.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 +353 -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 +9 -6
- package/dist/audit/service/audit.service.d.ts.map +1 -1
- package/dist/audit/service/audit.service.js +35 -10
- 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 +7 -1
- package/dist/casino/gaming/contract/index.js.map +1 -1
- package/dist/casino/gaming/drizzle/migrations/0002_yummy_lifeguard.sql +4 -0
- package/dist/casino/gaming/drizzle/migrations/meta/0002_snapshot.json +237 -0
- package/dist/casino/gaming/drizzle/migrations/meta/_journal.json +7 -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 +11 -1
- package/dist/casino/gaming/schema/index.js.map +1 -1
- package/dist/casino/gaming/service/gaming.service.d.ts +10 -3
- package/dist/casino/gaming/service/gaming.service.d.ts.map +1 -1
- package/dist/casino/gaming/service/gaming.service.js +50 -13
- 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.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 +54 -14
- 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 +27 -17
- 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 +408 -6
- 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/rg.d.ts +76 -11
- package/dist/compliance/contract/rg.d.ts.map +1 -1
- package/dist/compliance/contract/rg.js +23 -2
- package/dist/compliance/contract/rg.js.map +1 -1
- 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/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 +21 -0
- package/dist/compliance/plugin.d.ts +139 -1
- package/dist/compliance/plugin.d.ts.map +1 -1
- package/dist/compliance/plugin.js +47 -9
- package/dist/compliance/plugin.js.map +1 -1
- package/dist/compliance/router/index.d.ts +242 -8
- package/dist/compliance/router/index.d.ts.map +1 -1
- package/dist/compliance/router/index.js +85 -26
- package/dist/compliance/router/index.js.map +1 -1
- package/dist/compliance/schema/index.d.ts +66 -4
- package/dist/compliance/schema/index.d.ts.map +1 -1
- package/dist/compliance/schema/index.js +9 -1
- package/dist/compliance/schema/index.js.map +1 -1
- package/dist/compliance/service/compliance.service.d.ts +16 -8
- package/dist/compliance/service/compliance.service.d.ts.map +1 -1
- package/dist/compliance/service/compliance.service.js +36 -16
- package/dist/compliance/service/compliance.service.js.map +1 -1
- package/dist/compliance/service/kyc.service.d.ts +156 -11
- package/dist/compliance/service/kyc.service.d.ts.map +1 -1
- package/dist/compliance/service/kyc.service.js +287 -37
- package/dist/compliance/service/kyc.service.js.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.d.ts +1 -1
- package/dist/compliance/service/rg-monitoring.service.d.ts.map +1 -1
- package/dist/compliance/service/rg-monitoring.service.js +23 -11
- package/dist/compliance/service/rg-monitoring.service.js.map +1 -1
- package/dist/compliance/service/rg.service.d.ts +17 -6
- package/dist/compliance/service/rg.service.d.ts.map +1 -1
- package/dist/compliance/service/rg.service.js +110 -24
- 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/__tests__/identity.test.d.ts +2 -0
- package/dist/contracts/__tests__/identity.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/identity.test.js +49 -0
- package/dist/contracts/__tests__/identity.test.js.map +1 -0
- package/dist/contracts/__tests__/player.test.d.ts +2 -0
- package/dist/contracts/__tests__/player.test.d.ts.map +1 -0
- package/dist/contracts/__tests__/player.test.js +51 -0
- package/dist/contracts/__tests__/player.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 +11 -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 +11 -0
- 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 +54 -0
- package/dist/contracts/adapters/email-template.d.ts.map +1 -0
- package/dist/contracts/adapters/email-template.js +61 -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/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 +54 -13
- package/dist/contracts/adapters/index.d.ts.map +1 -1
- package/dist/contracts/adapters/index.js +30 -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 +195 -0
- 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/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 +11 -0
- 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 +9 -1
- 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 +17 -0
- package/dist/contracts/schemas/common.d.ts.map +1 -1
- package/dist/contracts/schemas/common.js +28 -2
- 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 +496 -1
- package/dist/contracts/schemas/events.d.ts.map +1 -1
- package/dist/contracts/schemas/events.js +343 -61
- 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/iam.d.ts +30 -0
- package/dist/contracts/schemas/iam.d.ts.map +1 -1
- package/dist/contracts/schemas/iam.js +33 -0
- package/dist/contracts/schemas/iam.js.map +1 -1
- package/dist/contracts/schemas/identity.d.ts +97 -3
- package/dist/contracts/schemas/identity.d.ts.map +1 -1
- package/dist/contracts/schemas/identity.js +81 -6
- 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 -29
- package/dist/contracts/schemas/platform-config.d.ts.map +1 -1
- package/dist/contracts/schemas/platform-config.js +82 -5
- package/dist/contracts/schemas/platform-config.js.map +1 -1
- package/dist/contracts/schemas/player.d.ts +84 -4
- package/dist/contracts/schemas/player.d.ts.map +1 -1
- package/dist/contracts/schemas/player.js +72 -8
- 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 +86 -2
- package/dist/contracts/schemas/tag.d.ts.map +1 -1
- package/dist/contracts/schemas/tag.js +13 -1
- package/dist/contracts/schemas/tag.js.map +1 -1
- package/dist/contracts/schemas/wallet-tx.d.ts +43 -3
- package/dist/contracts/schemas/wallet-tx.d.ts.map +1 -1
- package/dist/contracts/schemas/wallet-tx.js +40 -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/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 +267 -27
- 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 +1058 -66
- 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/__tests__/migration-upgrade.int.test.d.ts +2 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.d.ts.map +1 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js +52 -0
- package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js.map +1 -0
- package/dist/engagement/chat-commands/contract/index.d.ts +165 -0
- package/dist/engagement/chat-commands/contract/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/contract/index.js +66 -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 +22 -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 +113 -0
- package/dist/engagement/chat-commands/router/index.d.ts.map +1 -0
- package/dist/engagement/chat-commands/router/index.js +24 -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 +36 -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 +52 -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 +141 -0
- package/dist/engagement/chat-commands/service/chat-commands.service.js.map +1 -0
- package/dist/engagement/contracts.d.ts +2 -0
- package/dist/engagement/contracts.d.ts.map +1 -1
- package/dist/engagement/contracts.js +2 -0
- package/dist/engagement/contracts.js.map +1 -1
- package/dist/engagement/index.d.ts +2 -0
- package/dist/engagement/index.d.ts.map +1 -1
- package/dist/engagement/index.js +2 -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 +17 -1
- package/dist/engagement/notifications/contract/index.d.ts.map +1 -1
- package/dist/engagement/notifications/contract/index.js +8 -1
- package/dist/engagement/notifications/contract/index.js.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 +82 -6
- package/dist/engagement/notifications/plugin.js.map +1 -1
- package/dist/engagement/notifications/router/index.d.ts +4 -0
- package/dist/engagement/notifications/router/index.d.ts.map +1 -1
- package/dist/engagement/server.d.ts +2 -0
- package/dist/engagement/server.d.ts.map +1 -1
- package/dist/engagement/server.js +2 -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/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 +9 -5
- 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/service/iam.service.d.ts +24 -15
- package/dist/iam/service/iam.service.d.ts.map +1 -1
- package/dist/iam/service/iam.service.js +112 -11
- 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 +195 -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 +118 -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 +586 -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 +33 -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 +88 -35
- package/dist/pam/identity/admin-user-directory.js.map +1 -1
- package/dist/pam/identity/contract/index.d.ts +156 -15
- package/dist/pam/identity/contract/index.d.ts.map +1 -1
- package/dist/pam/identity/contract/index.js +65 -7
- 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 +44 -11
- 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 +145 -16
- package/dist/pam/identity/router/index.d.ts.map +1 -1
- package/dist/pam/identity/router/index.js +66 -12
- 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 +107 -33
- package/dist/pam/identity/service/identity.service.d.ts.map +1 -1
- package/dist/pam/identity/service/identity.service.js +717 -124
- 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/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 +371 -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 +37 -0
- package/dist/pam/identity/service/rg-guard.service.d.ts.map +1 -0
- package/dist/pam/identity/service/rg-guard.service.js +60 -0
- package/dist/pam/identity/service/rg-guard.service.js.map +1 -0
- package/dist/pam/identity/service/session.service.d.ts +14 -5
- package/dist/pam/identity/service/session.service.d.ts.map +1 -1
- package/dist/pam/identity/service/session.service.js +35 -12
- 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 +115 -15
- 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 +87 -15
- 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 +25 -10
- package/dist/pam/player-management/service/kyc-status-writer.js.map +1 -1
- package/dist/pam/player-management/service/player.service.d.ts +52 -21
- package/dist/pam/player-management/service/player.service.d.ts.map +1 -1
- package/dist/pam/player-management/service/player.service.js +129 -43
- 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/service/player-note.service.d.ts +5 -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 +5 -3
- 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 +133 -0
- package/dist/pam/profile/__tests__/profile.service.int.test.js.map +1 -0
- package/dist/pam/profile/contract/index.d.ts +17 -4
- 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/0003_absurd_morbius.sql +4 -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/0003_snapshot.json +224 -0
- package/dist/pam/profile/drizzle/migrations/meta/_journal.json +21 -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 +17 -6
- package/dist/pam/profile/react/profile.d.ts.map +1 -1
- package/dist/pam/profile/router/index.d.ts +17 -4
- package/dist/pam/profile/router/index.d.ts.map +1 -1
- package/dist/pam/profile/schema/index.d.ts +142 -6
- package/dist/pam/profile/schema/index.d.ts.map +1 -1
- package/dist/pam/profile/schema/index.js +16 -10
- package/dist/pam/profile/schema/index.js.map +1 -1
- package/dist/pam/profile/service/profile.service.d.ts +28 -6
- package/dist/pam/profile/service/profile.service.d.ts.map +1 -1
- package/dist/pam/profile/service/profile.service.js +26 -16
- 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/player-mapper.d.ts +12 -4
- package/dist/pam/shared/player-mapper.d.ts.map +1 -1
- package/dist/pam/shared/player-mapper.js +12 -5
- 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 +25 -0
- 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 +139 -1
- 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/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/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 +21 -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 +114 -1
- 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 +42 -3
- package/dist/pam/tag/schema/index.d.ts.map +1 -1
- package/dist/pam/tag/schema/index.js +13 -2
- 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 +42 -0
- 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/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 +473 -48
- package/dist/pam/tag/service/tag-evaluation.service.js.map +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts +1 -1
- package/dist/pam/tag/service/tag-mappers.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-mappers.js +1 -0
- package/dist/pam/tag/service/tag-mappers.js.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.d.ts +5 -5
- package/dist/pam/tag/service/tag-rule.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag-rule.service.js +8 -2
- package/dist/pam/tag/service/tag-rule.service.js.map +1 -1
- package/dist/pam/tag/service/tag.service.d.ts +147 -13
- package/dist/pam/tag/service/tag.service.d.ts.map +1 -1
- package/dist/pam/tag/service/tag.service.js +297 -30
- package/dist/pam/tag/service/tag.service.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 +60 -28
- package/dist/react/hooks/use-event-stream.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 +153 -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 +155 -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__/permissions.test.d.ts +2 -0
- package/dist/server/auth/__tests__/permissions.test.d.ts.map +1 -0
- package/dist/server/auth/__tests__/permissions.test.js +15 -0
- package/dist/server/auth/__tests__/permissions.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 +12 -10
- package/dist/server/auth/admin-guard.d.ts.map +1 -1
- package/dist/server/auth/admin-guard.js +89 -43
- package/dist/server/auth/admin-guard.js.map +1 -1
- package/dist/server/auth/auth.d.ts +30 -0
- package/dist/server/auth/auth.d.ts.map +1 -1
- package/dist/server/auth/auth.js +66 -17
- 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/permissions.d.ts +121 -14
- package/dist/server/auth/permissions.d.ts.map +1 -1
- package/dist/server/auth/permissions.js +14 -20
- 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 +148 -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.service.d.ts.map +1 -1
- package/dist/server/db/drizzle.service.js +8 -0
- 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 +38 -0
- package/dist/server/db/migrate.d.ts.map +1 -1
- package/dist/server/db/migrate.js +81 -12
- 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/query-helpers.d.ts +5 -0
- package/dist/server/db/query-helpers.d.ts.map +1 -1
- package/dist/server/db/query-helpers.js +44 -0
- 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.map +1 -1
- package/dist/server/kernel/bullmq-job-queue.js +27 -4
- 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 +0 -55
- package/dist/server/kernel/cache.js.map +1 -1
- package/dist/server/kernel/container.d.ts +7 -6
- package/dist/server/kernel/container.d.ts.map +1 -1
- package/dist/server/kernel/container.js +3 -0
- 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 -18
- package/dist/server/kernel/event-bus.d.ts.map +1 -1
- package/dist/server/kernel/event-bus.js +11 -34
- 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 +19 -4
- 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/rate-limiter.d.ts +2 -10
- package/dist/server/kernel/rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/rate-limiter.js +0 -34
- 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 +55 -19
- 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 +10 -0
- 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 +1 -0
- package/dist/server/kernel/redis-rate-limiter.d.ts.map +1 -1
- package/dist/server/kernel/redis-rate-limiter.js +11 -0
- 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/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 +2 -2
- 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 +10 -2
- 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/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 +98 -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 +62 -0
- package/dist/server/runtime/core-token-catalog.js.map +1 -0
- package/dist/server/runtime/create-app.d.ts +17 -23
- package/dist/server/runtime/create-app.d.ts.map +1 -1
- package/dist/server/runtime/create-app.js +129 -74
- 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 +50 -15
- package/dist/testing/mock.d.ts.map +1 -1
- package/dist/testing/mock.js +119 -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 +92 -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 +274 -0
- package/dist/wallet/__tests__/custody-sweep.service.int.test.js.map +1 -0
- package/dist/wallet/__tests__/deposit-gate.test.d.ts +2 -0
- package/dist/wallet/__tests__/deposit-gate.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/deposit-gate.test.js +46 -0
- package/dist/wallet/__tests__/deposit-gate.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 +415 -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 +245 -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 +137 -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 +205 -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-balance-stream.router.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.test.js +31 -0
- package/dist/wallet/__tests__/wallet-balance-stream.router.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 +114 -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 +213 -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 +48 -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 +129 -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-transaction-direction-backfill.test.d.ts +2 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.d.ts.map +1 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.js +24 -0
- package/dist/wallet/__tests__/wallet-transaction-direction-backfill.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 +310 -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 +171 -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 +104 -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 +1483 -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/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 +1 -0
- package/dist/wallet/adapters/wallet-reader.service.d.ts.map +1 -1
- package/dist/wallet/adapters/wallet-reader.service.js +18 -1
- package/dist/wallet/adapters/wallet-reader.service.js.map +1 -1
- package/dist/wallet/admin-reporting.d.ts +3 -3
- package/dist/wallet/admin-reporting.d.ts.map +1 -1
- package/dist/wallet/admin-reporting.js +11 -3
- package/dist/wallet/admin-reporting.js.map +1 -1
- package/dist/wallet/contract/index.d.ts +937 -17
- package/dist/wallet/contract/index.d.ts.map +1 -1
- package/dist/wallet/contract/index.js +452 -14
- package/dist/wallet/contract/index.js.map +1 -1
- 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/0013_polite_peter_parker.sql +1 -0
- package/dist/wallet/drizzle/migrations/0014_abandoned_madripoor.sql +20 -0
- package/dist/wallet/drizzle/migrations/0015_right_oracle.sql +3 -0
- package/dist/wallet/drizzle/migrations/0016_curly_ben_urich.sql +2 -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/0013_snapshot.json +1913 -0
- package/dist/wallet/drizzle/migrations/meta/0014_snapshot.json +1925 -0
- package/dist/wallet/drizzle/migrations/meta/0015_snapshot.json +1937 -0
- package/dist/wallet/drizzle/migrations/meta/0016_snapshot.json +1943 -0
- package/dist/wallet/drizzle/migrations/meta/_journal.json +105 -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 +138 -1
- package/dist/wallet/plugin.d.ts.map +1 -1
- package/dist/wallet/plugin.js +188 -19
- package/dist/wallet/plugin.js.map +1 -1
- package/dist/wallet/router/index.d.ts +508 -11
- package/dist/wallet/router/index.d.ts.map +1 -1
- package/dist/wallet/router/index.js +228 -22
- package/dist/wallet/router/index.js.map +1 -1
- package/dist/wallet/schema/index.d.ts +2100 -9
- package/dist/wallet/schema/index.d.ts.map +1 -1
- package/dist/wallet/schema/index.js +296 -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 +388 -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 +47 -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 +533 -0
- package/dist/wallet/service/reconciliation.service.js.map +1 -0
- package/dist/wallet/service/wallet-commands.service.d.ts +10 -2
- package/dist/wallet/service/wallet-commands.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet-commands.service.js +164 -26
- package/dist/wallet/service/wallet-commands.service.js.map +1 -1
- package/dist/wallet/service/wallet.service.d.ts +596 -16
- package/dist/wallet/service/wallet.service.d.ts.map +1 -1
- package/dist/wallet/service/wallet.service.js +1300 -96
- 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/package.json +108 -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 -442
- 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.router.test.d.ts +0 -2
- package/dist/cms/__tests__/cms.router.test.d.ts.map +0 -1
- package/dist/cms/__tests__/cms.router.test.js +0 -51
- package/dist/cms/__tests__/cms.router.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 -96
- 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 -154
- 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 -110
- 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 -66
- 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 -212
- 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 -26
- package/dist/engagement/chat/react/use-chat-stream.d.ts.map +0 -1
- package/dist/engagement/chat/react/use-chat-stream.js +0 -54
- 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 -84
- 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 -744
- 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 -38
- 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 -144
- 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 -48
- 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 -38
- 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 -269
- 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.router.test.d.ts +0 -2
- package/dist/pam/tag/__tests__/tag.router.test.d.ts.map +0 -1
- package/dist/pam/tag/__tests__/tag.router.test.js +0 -38
- package/dist/pam/tag/__tests__/tag.router.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 -124
- 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 -116
- 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 -135
- 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 -74
- 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 -49
- 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 -40
- package/dist/server/kernel/job-queue.d.ts.map +0 -1
- package/dist/server/kernel/job-queue.js +0 -200
- 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 -419
- 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 -176
- 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 -726
- package/dist/wallet/__tests__/wallet.service.test.js.map +0 -1
- package/turbo-generators/src/config.ts +0 -478
- 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,225 @@
|
|
|
1
|
-
import { makeNotFoundError, makeConflictError, createDomainError, findOneOrThrow, pageToOffset, withAdvisoryXactLock, assertRateLimit, createLogger, moneyToNumber, } 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
|
+
export const DepositDisabledError = createDomainError('DepositDisabledError', (currency, network) => network
|
|
34
|
+
? `Deposits are disabled for ${currency} on ${network}`
|
|
35
|
+
: `Deposits are disabled for ${currency} on every configured network`);
|
|
36
|
+
export const BelowMinimumDepositError = createDomainError('BelowMinimumDepositError', (amount, minimum, currency, network) => `Deposit of ${amount} ${currency} on ${network} is below the ${minimum} ${currency} minimum`);
|
|
37
|
+
const KYC_PASS_STATUSES = new Set(['approved', 'manually_overridden']);
|
|
38
|
+
export const AmbiguousDepositAddressError = createDomainError('AmbiguousDepositAddressError', (address, network) => `Deposit address ${address} on ${network ?? 'an unknown network'} is issued to more than one user`);
|
|
39
|
+
// Crypto currencies settle on the crypto rail through a custody/MPC vendor; everything
|
|
40
|
+
// else on the fiat rail (a PSP). The concrete provider is recorded per transaction, not
|
|
41
|
+
// here. Overridable per-operator via `platformConfig.wallet.cryptoCurrencies` - see `railFor`.
|
|
42
|
+
const DEFAULT_CRYPTO_CURRENCIES = new Set(['BTC', 'ETH', 'USDT', 'USDC']);
|
|
43
|
+
// A saved-address book, not a payout allowlist: the cap only stops one account turning
|
|
44
|
+
// the table into unbounded free storage. Not operator-configurable until someone asks.
|
|
45
|
+
const WITHDRAWAL_ADDRESS_LIMIT = 50;
|
|
46
|
+
function toWithdrawalAddressDto(row) {
|
|
47
|
+
return {
|
|
48
|
+
id: row.id,
|
|
49
|
+
label: row.label,
|
|
50
|
+
currency: row.currency,
|
|
51
|
+
network: row.network,
|
|
52
|
+
address: row.address,
|
|
53
|
+
destinationTag: row.destinationTag,
|
|
54
|
+
createdAt: row.createdAt.toISOString(),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Mirrors the `wallet.currency` column default: what a player without a wallet row
|
|
58
|
+
// reads as their active currency before one is created on first deposit.
|
|
59
|
+
const DEFAULT_WALLET_CURRENCY = 'USD';
|
|
18
60
|
// Per-user throttle on money mutations - guards a runaway/misbehaving client, not
|
|
19
61
|
// fraud (idempotency + the ledger guard cover correctness). An overlay rebinds
|
|
20
62
|
// RATE_LIMITER to change the backend, not this policy.
|
|
21
63
|
const WALLET_MUTATION_RATE_LIMIT = { limit: 30, windowMs: 60 * 1000 };
|
|
22
|
-
|
|
23
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Pins the chain a payout settles on. With one payable network the choice is implied; with
|
|
66
|
+
* several an explicit network is mandatory, because picking one silently would send a
|
|
67
|
+
* player's USDT over a chain their receiving wallet may not support.
|
|
68
|
+
*
|
|
69
|
+
* `assets` is every catalog row for the currency, enabled or not, so the two empty cases
|
|
70
|
+
* stay distinguishable: no rows at all means the operator never configured this currency
|
|
71
|
+
* (a fiat PSP), and the caller's choice passes through unchecked; rows that are all
|
|
72
|
+
* withdrawal-disabled is a deliberate operator decision and fails closed.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveWithdrawalNetwork(assets, currency, network) {
|
|
75
|
+
if (assets.length === 0) {
|
|
76
|
+
return network?.toUpperCase() ?? null;
|
|
77
|
+
}
|
|
78
|
+
const payable = assets.filter((asset) => asset.withdrawalEnabled);
|
|
79
|
+
const [only, ...rest] = payable;
|
|
80
|
+
if (!only) {
|
|
81
|
+
throw new WithdrawalDisabledError(currency);
|
|
82
|
+
}
|
|
83
|
+
if (network === undefined) {
|
|
84
|
+
if (rest.length > 0) {
|
|
85
|
+
throw new AmbiguousNetworkError(currency, payable.map((asset) => asset.network).join(', '));
|
|
86
|
+
}
|
|
87
|
+
return only.network.toUpperCase();
|
|
88
|
+
}
|
|
89
|
+
const wanted = network.toUpperCase();
|
|
90
|
+
if (!payable.some((asset) => asset.network.toUpperCase() === wanted)) {
|
|
91
|
+
throw new UnsupportedNetworkError(currency, wanted);
|
|
92
|
+
}
|
|
93
|
+
return wanted;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Rejects a payout worth less than the operator's per-network floor. The floor is per chain,
|
|
97
|
+
* not per currency: moving USDT costs cents on BEP20 and dollars on ERC20, so one
|
|
98
|
+
* currency-wide minimum is either too high for the cheap chain or below the fee on the
|
|
99
|
+
* expensive one.
|
|
100
|
+
*/
|
|
101
|
+
export function assertAboveMinimumWithdrawal(assets, amount, currency, network) {
|
|
102
|
+
const asset = assets.find((candidate) => candidate.withdrawalEnabled && candidate.network.toUpperCase() === network);
|
|
103
|
+
if (asset && moneyCompare(amount, asset.minWithdrawal) < 0) {
|
|
104
|
+
throw new BelowMinimumWithdrawalError(amount, asset.minWithdrawal, currency, asset.network);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export function assertDepositAllowed(assets, currency, network) {
|
|
108
|
+
if (assets.length === 0) {
|
|
109
|
+
// No catalog row at all means the operator never configured this currency (a fiat
|
|
110
|
+
// PSP), and a currency-level request passes through unchecked. A request naming a
|
|
111
|
+
// network does not: the pair it names does not exist - either a typo or a catalog
|
|
112
|
+
// row deleted while this request was in flight - so it fails closed.
|
|
113
|
+
if (network !== undefined) {
|
|
114
|
+
throw new UnsupportedNetworkError(currency, network.toUpperCase());
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (network === undefined) {
|
|
119
|
+
if (!assets.some((asset) => asset.depositEnabled)) {
|
|
120
|
+
throw new DepositDisabledError(currency, null);
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const wanted = network.toUpperCase();
|
|
125
|
+
const asset = assets.find((candidate) => candidate.network.toUpperCase() === wanted);
|
|
126
|
+
if (!asset) {
|
|
127
|
+
throw new UnsupportedNetworkError(currency, wanted);
|
|
128
|
+
}
|
|
129
|
+
if (!asset.depositEnabled) {
|
|
130
|
+
throw new DepositDisabledError(currency, asset.network);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function assertAboveMinimumDeposit(assets, amount, currency, network) {
|
|
134
|
+
const enabled = assets.filter((asset) => asset.depositEnabled);
|
|
135
|
+
const wanted = network?.toUpperCase();
|
|
136
|
+
const applicable = wanted
|
|
137
|
+
? enabled.filter((asset) => asset.network.toUpperCase() === wanted)
|
|
138
|
+
: enabled;
|
|
139
|
+
const floor = applicable.reduce((lowest, asset) => !lowest || moneyCompare(asset.minDeposit, lowest.minDeposit) < 0 ? asset : lowest, undefined);
|
|
140
|
+
if (floor && moneyCompare(amount, floor.minDeposit) < 0) {
|
|
141
|
+
throw new BelowMinimumDepositError(amount, floor.minDeposit, currency, floor.network);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function railFor(currency, cryptoCurrencies) {
|
|
145
|
+
const set = cryptoCurrencies
|
|
146
|
+
? new Set(cryptoCurrencies.map((c) => c.toUpperCase()))
|
|
147
|
+
: DEFAULT_CRYPTO_CURRENCIES;
|
|
148
|
+
return set.has(currency.toUpperCase()) ? 'crypto' : 'fiat';
|
|
149
|
+
}
|
|
150
|
+
// Currency checks elsewhere are case-insensitive, so `usd` reaches here for a `USD`
|
|
151
|
+
// wallet. Every read and write of wallet_balance funnels through these three helpers,
|
|
152
|
+
// so normalizing the key here is enough to keep one row per wallet+currency.
|
|
153
|
+
export const balanceKey = (currency) => currency.toUpperCase();
|
|
154
|
+
export function creditWalletBalance(txn, walletId, currency, amount) {
|
|
155
|
+
return txn
|
|
156
|
+
.insert(walletBalance)
|
|
157
|
+
.values({ walletId, currency: balanceKey(currency), amount })
|
|
158
|
+
.onConflictDoUpdate({
|
|
159
|
+
target: [walletBalance.walletId, walletBalance.currency],
|
|
160
|
+
set: {
|
|
161
|
+
amount: sql `${walletBalance.amount} + ${amount}::numeric`,
|
|
162
|
+
updatedAt: new Date(),
|
|
163
|
+
},
|
|
164
|
+
})
|
|
165
|
+
.returning({ amount: walletBalance.amount });
|
|
166
|
+
}
|
|
167
|
+
export function debitWalletBalance(txn, walletId, currency, amount) {
|
|
168
|
+
return txn
|
|
169
|
+
.update(walletBalance)
|
|
170
|
+
.set({ amount: sql `${walletBalance.amount} - ${amount}::numeric` })
|
|
171
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, balanceKey(currency)), gte(walletBalance.amount, amount)))
|
|
172
|
+
.returning({ amount: walletBalance.amount });
|
|
173
|
+
}
|
|
174
|
+
export async function readWalletBalance(txn, walletId, currency) {
|
|
175
|
+
const [row] = await txn
|
|
176
|
+
.select({ amount: walletBalance.amount })
|
|
177
|
+
.from(walletBalance)
|
|
178
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, balanceKey(currency))));
|
|
179
|
+
return row?.amount ?? '0';
|
|
180
|
+
}
|
|
181
|
+
export function debitWithdrawableBalance(txn, walletId, currency, amount) {
|
|
182
|
+
const currencyKey = balanceKey(currency);
|
|
183
|
+
return txn
|
|
184
|
+
.update(walletBalance)
|
|
185
|
+
.set({ amount: sql `${walletBalance.amount} - ${amount}::numeric` })
|
|
186
|
+
.where(and(eq(walletBalance.walletId, walletId), eq(walletBalance.currency, currencyKey), gte(sql `${walletBalance.amount} - COALESCE((
|
|
187
|
+
SELECT SUM(
|
|
188
|
+
${walletBonusCredit.creditedAmount}
|
|
189
|
+
* GREATEST(
|
|
190
|
+
${walletBonusCredit.rolloverRequired} - ${walletBonusCredit.rolloverProgress},
|
|
191
|
+
0
|
|
192
|
+
)
|
|
193
|
+
/ NULLIF(${walletBonusCredit.rolloverRequired}, 0)
|
|
194
|
+
)
|
|
195
|
+
FROM ${walletBonusCredit}
|
|
196
|
+
WHERE ${walletBonusCredit.walletId} = ${walletId}
|
|
197
|
+
AND ${walletBonusCredit.currency} = ${currencyKey}
|
|
198
|
+
AND ${walletBonusCredit.status} = 'active'
|
|
199
|
+
), 0)`, amount)))
|
|
200
|
+
.returning({ amount: walletBalance.amount });
|
|
201
|
+
}
|
|
202
|
+
async function readLockedBonusAmount(txn, walletId, currency) {
|
|
203
|
+
const currencyKey = balanceKey(currency);
|
|
204
|
+
const [row] = await txn
|
|
205
|
+
.select({
|
|
206
|
+
locked: sql `coalesce(sum(
|
|
207
|
+
${walletBonusCredit.creditedAmount}
|
|
208
|
+
* greatest(${walletBonusCredit.rolloverRequired} - ${walletBonusCredit.rolloverProgress}, 0)
|
|
209
|
+
/ nullif(${walletBonusCredit.rolloverRequired}, 0)
|
|
210
|
+
), 0)`,
|
|
211
|
+
})
|
|
212
|
+
.from(walletBonusCredit)
|
|
213
|
+
.where(and(eq(walletBonusCredit.walletId, walletId), eq(walletBonusCredit.currency, currencyKey), eq(walletBonusCredit.status, 'active')));
|
|
214
|
+
return row?.locked ?? '0';
|
|
24
215
|
}
|
|
25
216
|
// Namespace the key per operation so the same raw key on a deposit then a withdraw can't
|
|
26
217
|
// collide on the (walletId, idempotencyKey) unique index. The column is a uuid, so a string
|
|
27
218
|
// prefix won't parse - hash namespace + key into a stable pseudo-uuid instead.
|
|
28
219
|
const DEPOSIT_IDEMPOTENCY_NAMESPACE = 'deposit';
|
|
29
220
|
const WITHDRAW_IDEMPOTENCY_NAMESPACE = 'withdraw';
|
|
221
|
+
const MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE = 'manual-adjustment';
|
|
222
|
+
const MANUAL_ADJUSTMENT_TYPES = new Set(['manual_credit', 'manual_debit']);
|
|
30
223
|
function namespacedIdempotencyKey(namespace, rawKey) {
|
|
31
224
|
const hex = createHash('sha256').update(`${namespace}:${rawKey}`).digest('hex');
|
|
32
225
|
return [
|
|
@@ -47,6 +240,14 @@ const HIGH_FREQUENCY_MIN_COUNT = 3;
|
|
|
47
240
|
const DAILY_CAP_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
48
241
|
// Also the marker the cumulative-cap query reads back to identify auto-approved payouts - keep write and read in lockstep.
|
|
49
242
|
const AUTO_APPROVED_REASON = 'auto-approved';
|
|
243
|
+
function toDepositAddressResult(row) {
|
|
244
|
+
return {
|
|
245
|
+
address: row.address,
|
|
246
|
+
currency: row.currency,
|
|
247
|
+
...(row.network === null ? {} : { network: row.network }),
|
|
248
|
+
...(row.tag === null ? {} : { tag: row.tag }),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
50
251
|
function toAutoWithdrawalRuleDto(row) {
|
|
51
252
|
return {
|
|
52
253
|
id: row.id,
|
|
@@ -58,10 +259,49 @@ function toAutoWithdrawalRuleDto(row) {
|
|
|
58
259
|
updatedAt: row.updatedAt.toISOString(),
|
|
59
260
|
};
|
|
60
261
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
262
|
+
function toAutoWithdrawalConfigDto(row) {
|
|
263
|
+
return {
|
|
264
|
+
id: row.id,
|
|
265
|
+
fiatThreshold: row.fiatThreshold,
|
|
266
|
+
cryptoThreshold: row.cryptoThreshold,
|
|
267
|
+
excludeRiskFlags: row.excludeRiskFlags,
|
|
268
|
+
updatedBy: row.updatedBy,
|
|
269
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
270
|
+
createdAt: row.createdAt.toISOString(),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function toBonusCreditDto(row) {
|
|
274
|
+
return {
|
|
275
|
+
id: row.id,
|
|
276
|
+
currency: row.currency,
|
|
277
|
+
sourceType: row.sourceType,
|
|
278
|
+
creditedAmount: row.creditedAmount,
|
|
279
|
+
rolloverMultiplier: row.rolloverMultiplier,
|
|
280
|
+
rolloverRequired: row.rolloverRequired,
|
|
281
|
+
rolloverProgress: row.rolloverProgress,
|
|
282
|
+
status: row.status,
|
|
283
|
+
createdAt: row.createdAt.toISOString(),
|
|
284
|
+
completedAt: row.completedAt ? row.completedAt.toISOString() : null,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function toBonusRolloverConfigDto(row) {
|
|
288
|
+
return {
|
|
289
|
+
id: row.id,
|
|
290
|
+
multiplier: row.multiplier,
|
|
291
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
const PUBLIC_ASSET_COLUMNS = {
|
|
295
|
+
currency: walletAsset.currency,
|
|
296
|
+
network: walletAsset.network,
|
|
297
|
+
minDeposit: walletAsset.minDeposit,
|
|
298
|
+
minWithdrawal: walletAsset.minWithdrawal,
|
|
299
|
+
withdrawalFee: walletAsset.withdrawalFee,
|
|
300
|
+
depositEnabled: walletAsset.depositEnabled,
|
|
301
|
+
withdrawalEnabled: walletAsset.withdrawalEnabled,
|
|
302
|
+
};
|
|
303
|
+
function toWalletAssetDto(row) {
|
|
304
|
+
return serializeRow(row, { dateFields: ['createdAt', 'updatedAt'], decimalFields: [] });
|
|
65
305
|
}
|
|
66
306
|
/**
|
|
67
307
|
* Owns all wallet balance mutations and the withdrawal review/auto-approval
|
|
@@ -75,46 +315,149 @@ export class WalletService {
|
|
|
75
315
|
drizzle;
|
|
76
316
|
events;
|
|
77
317
|
payment;
|
|
318
|
+
paymentProviders;
|
|
319
|
+
identityReader;
|
|
78
320
|
directory;
|
|
79
321
|
platformConfig;
|
|
80
322
|
limiter;
|
|
81
323
|
riskTags;
|
|
324
|
+
tagEvaluationCommands;
|
|
82
325
|
audit;
|
|
83
|
-
constructor({ drizzle, events, payment, directory, platformConfig, limiter, riskTags, audit, }) {
|
|
326
|
+
constructor({ drizzle, events, payment, paymentProviders, directory, identityReader, platformConfig, limiter, riskTags, tagEvaluationCommands, audit, }) {
|
|
84
327
|
this.drizzle = drizzle;
|
|
85
328
|
this.events = events;
|
|
86
329
|
this.payment = payment;
|
|
330
|
+
this.paymentProviders = paymentProviders;
|
|
87
331
|
this.directory = directory;
|
|
332
|
+
this.identityReader = identityReader;
|
|
88
333
|
this.platformConfig = platformConfig;
|
|
89
334
|
this.limiter = limiter;
|
|
90
335
|
this.riskTags = riskTags;
|
|
336
|
+
this.tagEvaluationCommands = tagEvaluationCommands;
|
|
91
337
|
this.audit = audit;
|
|
92
338
|
}
|
|
339
|
+
// Every catalog row for the currency, enabled or not - resolveWithdrawalNetwork needs
|
|
340
|
+
// both to tell "never configured" from "deliberately disabled".
|
|
341
|
+
assetsForCurrency(currency) {
|
|
342
|
+
return this.drizzle.db
|
|
343
|
+
.select({
|
|
344
|
+
network: walletAsset.network,
|
|
345
|
+
minWithdrawal: walletAsset.minWithdrawal,
|
|
346
|
+
withdrawalEnabled: walletAsset.withdrawalEnabled,
|
|
347
|
+
})
|
|
348
|
+
.from(walletAsset)
|
|
349
|
+
.where(eq(walletAsset.currency, currency.toUpperCase()));
|
|
350
|
+
}
|
|
351
|
+
// `for('share')` blocks a concurrent deleteWalletAsset (which takes `for('update')` on
|
|
352
|
+
// the same rows) from removing the pair while a deposit is being gated against it.
|
|
353
|
+
depositAssetsForCurrency(currency, db = this.drizzle.db) {
|
|
354
|
+
return db
|
|
355
|
+
.select({
|
|
356
|
+
network: walletAsset.network,
|
|
357
|
+
minDeposit: walletAsset.minDeposit,
|
|
358
|
+
depositEnabled: walletAsset.depositEnabled,
|
|
359
|
+
})
|
|
360
|
+
.from(walletAsset)
|
|
361
|
+
.where(eq(walletAsset.currency, currency.toUpperCase()))
|
|
362
|
+
.for('share');
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* `network` is optional because not every deposit path knows one: `deposit()` takes a
|
|
366
|
+
* PSP amount and currency only, so it is gated currency-wide (any enabled network
|
|
367
|
+
* clears it). Per-network gating applies where a network is actually chosen, ie
|
|
368
|
+
* `getOrCreateDepositAddress`, which is the path that hands a player a chain address.
|
|
369
|
+
*/
|
|
370
|
+
async assertDepositable(currency, amount, network, db = this.drizzle.db) {
|
|
371
|
+
const assets = await this.depositAssetsForCurrency(currency, db);
|
|
372
|
+
assertDepositAllowed(assets, currency, network);
|
|
373
|
+
if (amount !== undefined) {
|
|
374
|
+
assertAboveMinimumDeposit(assets, amount, currency, network);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
resolveRail(currency) {
|
|
378
|
+
return railFor(currency, this.platformConfig?.wallet?.cryptoCurrencies);
|
|
379
|
+
}
|
|
380
|
+
// The concrete vendor a transaction/deposit-address settles through: the catalog row
|
|
381
|
+
// for the exact (currency, network) pair names the bound provider. Reconciliation
|
|
382
|
+
// scopes its diff by this column, so a null network (an unconfigured pair - no
|
|
383
|
+
// catalog row could ever match it) and a configured-but-null providerName column both
|
|
384
|
+
// resolve to the single default binding rather than leaving the column null.
|
|
385
|
+
async providerNameFor(currency, network) {
|
|
386
|
+
if (network === null) {
|
|
387
|
+
return DEFAULT_PAYMENT_PROVIDER;
|
|
388
|
+
}
|
|
389
|
+
const [row] = await this.drizzle.db
|
|
390
|
+
.select({ providerName: walletAsset.providerName })
|
|
391
|
+
.from(walletAsset)
|
|
392
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
393
|
+
return row?.providerName ?? DEFAULT_PAYMENT_PROVIDER;
|
|
394
|
+
}
|
|
395
|
+
// Fails closed on a named provider that is no longer registered (removed or
|
|
396
|
+
// misconfigured after the catalog row was written). Falling back to the default
|
|
397
|
+
// adapter would pay a withdrawal out through the wrong vendor while still recording
|
|
398
|
+
// the old provider name - money moved somewhere the ledger does not describe.
|
|
399
|
+
async paymentAdapterFor(currency, network) {
|
|
400
|
+
const providerName = await this.providerNameFor(currency, network);
|
|
401
|
+
if (providerName === DEFAULT_PAYMENT_PROVIDER) {
|
|
402
|
+
return { providerName, adapter: this.payment };
|
|
403
|
+
}
|
|
404
|
+
const adapter = this.paymentProviders.get(providerName)?.adapter;
|
|
405
|
+
if (!adapter) {
|
|
406
|
+
throw new WalletAssetUnknownProviderError();
|
|
407
|
+
}
|
|
408
|
+
return { providerName, adapter };
|
|
409
|
+
}
|
|
93
410
|
rateLimit(userId) {
|
|
94
411
|
return this.limiter
|
|
95
412
|
? assertRateLimit(this.limiter, `wallet-mutation:${userId}`, WALLET_MUTATION_RATE_LIMIT)
|
|
96
413
|
: Promise.resolve();
|
|
97
414
|
}
|
|
98
|
-
/** Fail-closed KYC gate: when enabled, a withdrawal needs a passing status (verified|manually_overridden). */
|
|
99
415
|
async assertKycForWithdrawal(userId) {
|
|
100
416
|
if (!this.platformConfig?.kyc?.gateWithdrawals) {
|
|
101
417
|
return;
|
|
102
418
|
}
|
|
103
419
|
const status = await this.autoApprovalKycStatus(userId);
|
|
104
|
-
if (!status || !KYC_PASS_STATUSES.has(status)) {
|
|
420
|
+
if (!status || !KYC_PASS_STATUSES.has(normalizeKycStatus(status))) {
|
|
105
421
|
throw new KycRequiredError();
|
|
106
422
|
}
|
|
107
423
|
}
|
|
108
424
|
async getBalance(userId) {
|
|
109
425
|
const [record] = await this.drizzle.db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
110
426
|
if (!record) {
|
|
111
|
-
return { balance: '0', currency:
|
|
427
|
+
return { balance: '0', currency: DEFAULT_WALLET_CURRENCY };
|
|
112
428
|
}
|
|
113
429
|
return {
|
|
114
|
-
balance: record.
|
|
430
|
+
balance: await readWalletBalance(this.drizzle.db, record.id, record.currency),
|
|
115
431
|
currency: record.currency,
|
|
116
432
|
};
|
|
117
433
|
}
|
|
434
|
+
async getBalances(userId) {
|
|
435
|
+
const [record] = await this.drizzle.db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
436
|
+
if (!record) {
|
|
437
|
+
return { activeCurrency: DEFAULT_WALLET_CURRENCY, balances: [] };
|
|
438
|
+
}
|
|
439
|
+
const rows = await this.drizzle.db
|
|
440
|
+
.select({ currency: walletBalance.currency, balance: walletBalance.amount })
|
|
441
|
+
.from(walletBalance)
|
|
442
|
+
.where(eq(walletBalance.walletId, record.id))
|
|
443
|
+
.orderBy(walletBalance.currency);
|
|
444
|
+
return { activeCurrency: record.currency, balances: rows };
|
|
445
|
+
}
|
|
446
|
+
// TODO: validate `currency` against a canonical supported-currency list once one
|
|
447
|
+
// exists - `platformConfig.wallet.cryptoCurrencies` classifies rails, it is not an
|
|
448
|
+
// allowlist, so today any non-empty string is accepted and persisted.
|
|
449
|
+
async setActiveCurrency(userId, currency) {
|
|
450
|
+
const updated = await this.drizzle.db
|
|
451
|
+
.update(wallet)
|
|
452
|
+
.set({ currency })
|
|
453
|
+
.where(eq(wallet.userId, userId))
|
|
454
|
+
.returning({ currency: wallet.currency });
|
|
455
|
+
const record = updated[0];
|
|
456
|
+
if (!record) {
|
|
457
|
+
throw new WalletNotFoundError(userId);
|
|
458
|
+
}
|
|
459
|
+
return { activeCurrency: record.currency };
|
|
460
|
+
}
|
|
118
461
|
/**
|
|
119
462
|
* `idempotencyKey` (when supplied) makes a retried deposit a no-op: a replay
|
|
120
463
|
* returns the original committed result WITHOUT calling the PSP again or
|
|
@@ -124,9 +467,16 @@ export class WalletService {
|
|
|
124
467
|
* reach the PSP, but the ledger insert's unique-index conflict still
|
|
125
468
|
* guarantees only one balance credit - the loser's write becomes a replay
|
|
126
469
|
* read of the winner's row.
|
|
470
|
+
*
|
|
471
|
+
* Deposit gating is network-aware when a network is known (e.g. via
|
|
472
|
+
* `getOrCreateDepositAddress`), but here we gate on "any network for this
|
|
473
|
+
* currency is enabled" because `provider` routing may resolve a specific
|
|
474
|
+
* network inside `processDeposit`. A fiat PSP (no networks) passes through
|
|
475
|
+
* unchecked; an explicit network route checks that specific network only.
|
|
127
476
|
*/
|
|
128
477
|
async deposit({ userId, amount, currency, provider, idempotencyKey, }) {
|
|
129
478
|
await this.rateLimit(userId);
|
|
479
|
+
await this.assertDepositable(currency, amount);
|
|
130
480
|
// Short-circuit a replay BEFORE the PSP call - the common retry case (client
|
|
131
481
|
// resends after a timeout) must not re-charge. A genuine concurrent race (two
|
|
132
482
|
// first-attempts for the same key landing here at once) can still both reach the
|
|
@@ -139,6 +489,12 @@ export class WalletService {
|
|
|
139
489
|
}
|
|
140
490
|
preResolvedWallet = found.walletRecord;
|
|
141
491
|
}
|
|
492
|
+
else {
|
|
493
|
+
[preResolvedWallet] = await this.drizzle.db
|
|
494
|
+
.select()
|
|
495
|
+
.from(wallet)
|
|
496
|
+
.where(eq(wallet.userId, userId));
|
|
497
|
+
}
|
|
142
498
|
const psp = await this.payment.processDeposit(amount, currency, { userId, provider });
|
|
143
499
|
const { transactionId, replayed } = await this.drizzle.db.transaction(async (txn) => {
|
|
144
500
|
let walletRecord = preResolvedWallet;
|
|
@@ -146,7 +502,7 @@ export class WalletService {
|
|
|
146
502
|
[walletRecord] = await txn.select().from(wallet).where(eq(wallet.userId, userId));
|
|
147
503
|
}
|
|
148
504
|
if (!walletRecord) {
|
|
149
|
-
walletRecord = findOneOrThrow(await txn.insert(wallet).values({ userId,
|
|
505
|
+
walletRecord = findOneOrThrow(await txn.insert(wallet).values({ userId, currency }).returning(), new WalletNotFoundError(userId));
|
|
150
506
|
}
|
|
151
507
|
const { row, replayed } = await this.insertIdempotentTransaction(txn, {
|
|
152
508
|
namespace: DEPOSIT_IDEMPOTENCY_NAMESPACE,
|
|
@@ -160,22 +516,21 @@ export class WalletService {
|
|
|
160
516
|
amount,
|
|
161
517
|
currency,
|
|
162
518
|
status: 'completed',
|
|
163
|
-
|
|
519
|
+
direction: 'credit',
|
|
520
|
+
rail: this.resolveRail(currency),
|
|
164
521
|
providerName: provider,
|
|
165
522
|
providerRefId: psp.externalId,
|
|
166
523
|
},
|
|
167
524
|
});
|
|
168
525
|
if (!replayed) {
|
|
169
|
-
await txn
|
|
170
|
-
.update(wallet)
|
|
171
|
-
.set({ balance: sql `${wallet.balance} + ${amount}::numeric` })
|
|
172
|
-
.where(eq(wallet.id, walletRecord.id));
|
|
526
|
+
await creditWalletBalance(txn, walletRecord.id, currency, amount);
|
|
173
527
|
}
|
|
174
528
|
return { transactionId: row.id, replayed };
|
|
175
529
|
});
|
|
176
530
|
if (!replayed) {
|
|
177
531
|
this.events.emit('wallet.deposit.completed', {
|
|
178
532
|
userId,
|
|
533
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
179
534
|
amount,
|
|
180
535
|
currency,
|
|
181
536
|
transactionId,
|
|
@@ -183,6 +538,118 @@ export class WalletService {
|
|
|
183
538
|
}
|
|
184
539
|
return { transactionId, status: 'completed' };
|
|
185
540
|
}
|
|
541
|
+
async manualAdjust({ adminId, userId, direction, amount, currency, reason, idempotencyKey, ip, userAgent, }) {
|
|
542
|
+
const playerId = await this.identityReader.getPlayerIdByUserId(userId);
|
|
543
|
+
if (!playerId) {
|
|
544
|
+
throw new PlayerNotFoundError(userId);
|
|
545
|
+
}
|
|
546
|
+
const { result, emitted } = await this.drizzle.db.transaction(async (txn) => {
|
|
547
|
+
let walletRecord = (await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update')).at(0);
|
|
548
|
+
if (!walletRecord) {
|
|
549
|
+
if (direction === 'debit') {
|
|
550
|
+
throw new InsufficientBalanceError('0', amount);
|
|
551
|
+
}
|
|
552
|
+
const [created] = await txn
|
|
553
|
+
.insert(wallet)
|
|
554
|
+
.values({ userId, currency })
|
|
555
|
+
.onConflictDoNothing()
|
|
556
|
+
.returning();
|
|
557
|
+
walletRecord =
|
|
558
|
+
created ??
|
|
559
|
+
findOneOrThrow(await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update'), new WalletNotFoundError(userId));
|
|
560
|
+
}
|
|
561
|
+
const existing = await this.findByIdempotencyKey(txn, walletRecord.id, namespacedIdempotencyKey(MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE, idempotencyKey));
|
|
562
|
+
if (existing) {
|
|
563
|
+
this.assertManualAdjustmentReplayMatches(existing, {
|
|
564
|
+
adminId,
|
|
565
|
+
direction,
|
|
566
|
+
amount,
|
|
567
|
+
currency,
|
|
568
|
+
reason,
|
|
569
|
+
});
|
|
570
|
+
return { result: { transactionId: existing.id, status: existing.status }, emitted: false };
|
|
571
|
+
}
|
|
572
|
+
const { row, replayed } = await this.insertIdempotentTransaction(txn, {
|
|
573
|
+
namespace: MANUAL_ADJUSTMENT_IDEMPOTENCY_NAMESPACE,
|
|
574
|
+
walletId: walletRecord.id,
|
|
575
|
+
rawIdempotencyKey: idempotencyKey,
|
|
576
|
+
amount,
|
|
577
|
+
currency,
|
|
578
|
+
values: {
|
|
579
|
+
walletId: walletRecord.id,
|
|
580
|
+
type: direction === 'credit' ? 'manual_credit' : 'manual_debit',
|
|
581
|
+
amount,
|
|
582
|
+
currency,
|
|
583
|
+
status: 'completed',
|
|
584
|
+
direction,
|
|
585
|
+
reviewedBy: adminId,
|
|
586
|
+
reviewedAt: new Date(),
|
|
587
|
+
reviewReason: reason,
|
|
588
|
+
},
|
|
589
|
+
});
|
|
590
|
+
if (replayed) {
|
|
591
|
+
this.assertManualAdjustmentReplayMatches(row, {
|
|
592
|
+
adminId,
|
|
593
|
+
direction,
|
|
594
|
+
amount,
|
|
595
|
+
currency,
|
|
596
|
+
reason,
|
|
597
|
+
});
|
|
598
|
+
return { result: { transactionId: row.id, status: row.status }, emitted: false };
|
|
599
|
+
}
|
|
600
|
+
const balances = direction === 'credit'
|
|
601
|
+
? await creditWalletBalance(txn, walletRecord.id, currency, amount)
|
|
602
|
+
: await debitWalletBalance(txn, walletRecord.id, currency, amount);
|
|
603
|
+
const [balance] = balances;
|
|
604
|
+
if (!balance) {
|
|
605
|
+
throw new InsufficientBalanceError(await readWalletBalance(txn, walletRecord.id, currency), amount);
|
|
606
|
+
}
|
|
607
|
+
// Derived from the row the update returned, never read separately beforehand. The
|
|
608
|
+
// wallet row is locked here but the deposit credit path does not take that lock, so
|
|
609
|
+
// a deposit can commit between a pre-read and this update - and `before` is going
|
|
610
|
+
// into an append-only audit record that cannot be corrected later.
|
|
611
|
+
const balanceBefore = direction === 'credit'
|
|
612
|
+
? moneySubtract(balance.amount, amount)
|
|
613
|
+
: moneyAdd(balance.amount, amount);
|
|
614
|
+
await this.audit.recordInTransaction(txn, {
|
|
615
|
+
actorId: adminId,
|
|
616
|
+
actorType: 'admin',
|
|
617
|
+
action: 'wallet.manual_adjustment.created',
|
|
618
|
+
resourceType: 'wallet_transaction',
|
|
619
|
+
resourceId: row.id,
|
|
620
|
+
before: { balance: balanceBefore, currency },
|
|
621
|
+
after: {
|
|
622
|
+
balance: balance.amount,
|
|
623
|
+
currency,
|
|
624
|
+
transactionId: row.id,
|
|
625
|
+
direction,
|
|
626
|
+
amount,
|
|
627
|
+
reason,
|
|
628
|
+
},
|
|
629
|
+
ip,
|
|
630
|
+
userAgent,
|
|
631
|
+
});
|
|
632
|
+
return { result: { transactionId: row.id, status: row.status }, emitted: true };
|
|
633
|
+
});
|
|
634
|
+
// Every other balance-mutating path on this service emits; without this one an admin
|
|
635
|
+
// correction moves a real balance while responsible-gaming monitoring, analytics and
|
|
636
|
+
// any operator subscriber see nothing at all.
|
|
637
|
+
if (emitted) {
|
|
638
|
+
this.events.emit('wallet.manual_adjustment.created', {
|
|
639
|
+
userId,
|
|
640
|
+
playerId,
|
|
641
|
+
adminId,
|
|
642
|
+
amount,
|
|
643
|
+
currency,
|
|
644
|
+
transactionId: result.transactionId,
|
|
645
|
+
direction,
|
|
646
|
+
reason,
|
|
647
|
+
ip,
|
|
648
|
+
userAgent,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
return result;
|
|
652
|
+
}
|
|
186
653
|
// Pre-PSP replay check for deposit; also returns the resolved wallet so the transaction
|
|
187
654
|
// below can skip re-selecting it. Throws IdempotencyKeyReuseError on an amount/currency mismatch.
|
|
188
655
|
async findDepositReplay({ userId, idempotencyKey, amount, currency, }) {
|
|
@@ -200,14 +667,23 @@ export class WalletService {
|
|
|
200
667
|
this.assertReplayMatches(existing, amount, currency);
|
|
201
668
|
return { walletRecord, replay: { transactionId: existing.id, status: existing.status } };
|
|
202
669
|
}
|
|
203
|
-
// Replay comparison only (not a ledger write)
|
|
204
|
-
//
|
|
670
|
+
// Replay comparison only (not a ledger write). moneyEquals avoids a false mismatch between
|
|
671
|
+
// an unnormalized caller string (eg "10") and the DB's fixed-scale value ("10.00") while
|
|
672
|
+
// staying exact - a float compare would let two amounts differing past the 15th digit pass.
|
|
205
673
|
assertReplayMatches(existing, amount, currency) {
|
|
206
|
-
if (
|
|
674
|
+
if (!moneyEquals(existing.amount, amount) ||
|
|
207
675
|
existing.currency.toUpperCase() !== currency.toUpperCase()) {
|
|
208
676
|
throw new IdempotencyKeyReuseError();
|
|
209
677
|
}
|
|
210
678
|
}
|
|
679
|
+
assertManualAdjustmentReplayMatches(existing, { adminId, direction, amount, currency, reason, }) {
|
|
680
|
+
if (existing.type !== (direction === 'credit' ? 'manual_credit' : 'manual_debit') ||
|
|
681
|
+
existing.reviewedBy !== adminId ||
|
|
682
|
+
existing.reviewReason !== reason) {
|
|
683
|
+
throw new IdempotencyKeyReuseError();
|
|
684
|
+
}
|
|
685
|
+
this.assertReplayMatches(existing, amount, currency);
|
|
686
|
+
}
|
|
211
687
|
// Two concurrent requests with the same key can both pass the pre-insert check and race
|
|
212
688
|
// on the unique index; onConflictDoNothing makes the loser's insert a no-op so it re-reads
|
|
213
689
|
// the winner's committed row and returns it as a replay instead of aborting the transaction.
|
|
@@ -246,16 +722,19 @@ export class WalletService {
|
|
|
246
722
|
* return an already-`completed`/`processing` result if the request
|
|
247
723
|
* qualifies for (and passes) auto-approval - see `maybeAutoApprove`.
|
|
248
724
|
*/
|
|
249
|
-
async withdraw({ userId, amount, currency, idempotencyKey, }) {
|
|
725
|
+
async withdraw({ userId, amount, currency, network, idempotencyKey, destinationAddress, destinationTag, ip, userAgent, }) {
|
|
250
726
|
await this.rateLimit(userId);
|
|
251
727
|
await this.assertKycForWithdrawal(userId);
|
|
728
|
+
if (this.resolveRail(currency) === 'crypto' && !destinationAddress) {
|
|
729
|
+
throw new DestinationAddressRequiredError();
|
|
730
|
+
}
|
|
731
|
+
const assets = await this.assetsForCurrency(currency);
|
|
732
|
+
const settlementNetwork = resolveWithdrawalNetwork(assets, currency, network);
|
|
733
|
+
assertAboveMinimumWithdrawal(assets, amount, currency, settlementNetwork);
|
|
734
|
+
const destinationWalletId = await this.requireWhitelistedWalletId(userId, currency, settlementNetwork, destinationAddress, destinationTag);
|
|
252
735
|
const { transactionId, status, replayed, walletId, rail } = await this.drizzle.db.transaction(async (txn) => {
|
|
253
736
|
// FOR UPDATE serializes concurrent withdrawals against a double-debit TOCTOU under READ COMMITTED.
|
|
254
737
|
const current = findOneOrThrow(await txn.select().from(wallet).where(eq(wallet.userId, userId)).for('update'), new WalletNotFoundError(userId));
|
|
255
|
-
// Single-currency wallet: reject a mismatch rather than coerce it onto the wrong rail.
|
|
256
|
-
if (currency.toUpperCase() !== current.currency.toUpperCase()) {
|
|
257
|
-
throw new CurrencyMismatchError(currency, current.currency);
|
|
258
|
-
}
|
|
259
738
|
// Replay of an already-committed key: return the original untouched. The new-key race is caught by the insert below.
|
|
260
739
|
if (idempotencyKey) {
|
|
261
740
|
const existing = await this.findByIdempotencyKey(txn, current.id, namespacedIdempotencyKey(WITHDRAW_IDEMPOTENCY_NAMESPACE, idempotencyKey));
|
|
@@ -266,7 +745,7 @@ export class WalletService {
|
|
|
266
745
|
status: existing.status,
|
|
267
746
|
replayed: true,
|
|
268
747
|
walletId: current.id,
|
|
269
|
-
rail:
|
|
748
|
+
rail: this.resolveRail(currency),
|
|
270
749
|
};
|
|
271
750
|
}
|
|
272
751
|
}
|
|
@@ -282,7 +761,12 @@ export class WalletService {
|
|
|
282
761
|
amount,
|
|
283
762
|
currency,
|
|
284
763
|
status: 'pending',
|
|
285
|
-
|
|
764
|
+
direction: 'debit',
|
|
765
|
+
rail: this.resolveRail(currency),
|
|
766
|
+
network: settlementNetwork,
|
|
767
|
+
destinationAddress: destinationAddress ?? null,
|
|
768
|
+
destinationTag: destinationTag ?? null,
|
|
769
|
+
destinationWalletId,
|
|
286
770
|
},
|
|
287
771
|
});
|
|
288
772
|
if (replayed) {
|
|
@@ -291,24 +775,29 @@ export class WalletService {
|
|
|
291
775
|
status: row.status,
|
|
292
776
|
replayed,
|
|
293
777
|
walletId: current.id,
|
|
294
|
-
rail:
|
|
778
|
+
rail: this.resolveRail(currency),
|
|
295
779
|
};
|
|
296
780
|
}
|
|
297
|
-
|
|
298
|
-
const debited = await txn
|
|
299
|
-
.update(wallet)
|
|
300
|
-
.set({ balance: sql `${wallet.balance} - ${amount}::numeric` })
|
|
301
|
-
.where(and(eq(wallet.id, current.id), gte(wallet.balance, amount)))
|
|
302
|
-
.returning({ id: wallet.id });
|
|
781
|
+
const debited = await debitWithdrawableBalance(txn, current.id, currency, amount);
|
|
303
782
|
if (debited.length !== 1) {
|
|
304
|
-
|
|
783
|
+
const [available, locked] = await Promise.all([
|
|
784
|
+
readWalletBalance(txn, current.id, currency),
|
|
785
|
+
readLockedBonusAmount(txn, current.id, currency),
|
|
786
|
+
]);
|
|
787
|
+
if (moneyToNumber(available) < moneyToNumber(amount)) {
|
|
788
|
+
throw new InsufficientBalanceError(available, amount);
|
|
789
|
+
}
|
|
790
|
+
throw new BonusRolloverLockedError(locked);
|
|
791
|
+
}
|
|
792
|
+
if (this.tagEvaluationCommands) {
|
|
793
|
+
await this.tagEvaluationCommands.evaluateWithdrawalRequested(txn, { userId, amount });
|
|
305
794
|
}
|
|
306
795
|
return {
|
|
307
796
|
transactionId: row.id,
|
|
308
797
|
status: row.status,
|
|
309
798
|
replayed,
|
|
310
799
|
walletId: current.id,
|
|
311
|
-
rail:
|
|
800
|
+
rail: this.resolveRail(currency),
|
|
312
801
|
};
|
|
313
802
|
});
|
|
314
803
|
if (replayed) {
|
|
@@ -316,9 +805,12 @@ export class WalletService {
|
|
|
316
805
|
}
|
|
317
806
|
this.events.emit('wallet.withdrawal.requested', {
|
|
318
807
|
userId,
|
|
808
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
319
809
|
amount,
|
|
320
810
|
currency,
|
|
321
811
|
transactionId,
|
|
812
|
+
ip: ip ?? null,
|
|
813
|
+
userAgent: userAgent ?? null,
|
|
322
814
|
});
|
|
323
815
|
// Fail-closed post-step: decides who approves (system vs manual queue), never throws out of withdraw() - failure leaves the row pending.
|
|
324
816
|
const auto = await this.maybeAutoApprove({
|
|
@@ -358,17 +850,38 @@ export class WalletService {
|
|
|
358
850
|
}
|
|
359
851
|
// Bounded queue: fetch all SQL-matching rows, then enrich + kycStatus-filter + paginate in memory,
|
|
360
852
|
// else DB-side pagination makes `total` wrong once kycStatus prunes.
|
|
853
|
+
const wdSortBy = filters.sortBy ?? 'createdAt';
|
|
854
|
+
const wdDir = (filters.sortOrder ?? 'desc') === 'asc' ? asc : desc;
|
|
855
|
+
const WD_SORT_COLS = {
|
|
856
|
+
createdAt: walletTransaction.createdAt,
|
|
857
|
+
amount: walletTransaction.amount,
|
|
858
|
+
status: walletTransaction.status,
|
|
859
|
+
currency: walletTransaction.currency,
|
|
860
|
+
rail: walletTransaction.rail,
|
|
861
|
+
reviewedAt: walletTransaction.reviewedAt,
|
|
862
|
+
};
|
|
361
863
|
const rows = await db
|
|
362
864
|
.select({ tx: walletTransaction, userId: wallet.userId })
|
|
363
865
|
.from(walletTransaction)
|
|
364
866
|
.innerJoin(wallet, eq(wallet.id, walletTransaction.walletId))
|
|
365
867
|
.where(and(...conditions))
|
|
366
|
-
.orderBy(desc(walletTransaction.
|
|
868
|
+
.orderBy(wdDir(WD_SORT_COLS[wdSortBy]), desc(walletTransaction.id));
|
|
367
869
|
const userIds = [...new Set(rows.map((r) => r.userId))];
|
|
368
870
|
const summaries = this.directory ? await this.directory.lookupPlayers(userIds) : [];
|
|
369
871
|
const byUserId = new Map(summaries.map((s) => [s.userId, s]));
|
|
370
|
-
|
|
371
|
-
|
|
872
|
+
// Normalize both sides before comparing: the ADMIN_USER_DIRECTORY port's return type
|
|
873
|
+
// still permits the deprecated `verified` value (it aliases `approved`), and this
|
|
874
|
+
// module cannot assume every bound implementation already normalized it at its own
|
|
875
|
+
// read boundary - a raw `===` here would silently hide every legacy-verified player
|
|
876
|
+
// from the queue the moment an admin filters by the canonical `approved`.
|
|
877
|
+
const kycStatusFilter = filters.kycStatus ? normalizeKycStatus(filters.kycStatus) : undefined;
|
|
878
|
+
const matching = kycStatusFilter
|
|
879
|
+
? rows.filter((r) => {
|
|
880
|
+
const kycStatus = byUserId.get(r.userId)?.kycStatus;
|
|
881
|
+
return kycStatus !== undefined && kycStatus !== null
|
|
882
|
+
? normalizeKycStatus(kycStatus) === kycStatusFilter
|
|
883
|
+
: false;
|
|
884
|
+
})
|
|
372
885
|
: rows;
|
|
373
886
|
const start = pageToOffset(page, limit);
|
|
374
887
|
const pageRows = matching.slice(start, start + limit);
|
|
@@ -387,14 +900,19 @@ export class WalletService {
|
|
|
387
900
|
return {
|
|
388
901
|
transactionId: r.tx.id,
|
|
389
902
|
userId: r.userId,
|
|
903
|
+
playerId: summary?.playerId ?? null,
|
|
390
904
|
username: summary?.username ?? '',
|
|
391
905
|
amount: r.tx.amount,
|
|
392
906
|
currency: r.tx.currency,
|
|
907
|
+
network: r.tx.network,
|
|
393
908
|
rail: r.tx.rail ?? null,
|
|
394
909
|
status: r.tx.status,
|
|
395
910
|
kycStatus: summary?.kycStatus ?? null,
|
|
396
911
|
riskTags,
|
|
397
912
|
requestedAt: r.tx.createdAt.toISOString(),
|
|
913
|
+
destinationAddress: r.tx.destinationAddress,
|
|
914
|
+
destinationTag: r.tx.destinationTag,
|
|
915
|
+
txHash: r.tx.txHash,
|
|
398
916
|
};
|
|
399
917
|
});
|
|
400
918
|
return { items, total: matching.length, page, limit };
|
|
@@ -404,11 +922,11 @@ export class WalletService {
|
|
|
404
922
|
* or Failed + refund on PSP error. Robust PSP idempotency-key/reconciliation for a
|
|
405
923
|
* lost-response is deferred - same scope boundary the deposit path declares.
|
|
406
924
|
*/
|
|
407
|
-
async approveWithdrawal(adminId, withdrawalId) {
|
|
925
|
+
async approveWithdrawal(adminId, withdrawalId, meta) {
|
|
408
926
|
// Two-phase: commit the `processing` flip first (FOR UPDATE lock), then call the PSP OUTSIDE
|
|
409
927
|
// the tx (a failure refunds in a second tx). Never inline the PSP call inside the hold transaction.
|
|
410
928
|
const tx = await this.drizzle.db.transaction((txn) => this.flipToProcessing({ txn, withdrawalId, adminId }));
|
|
411
|
-
return this.settleApproved(tx, adminId);
|
|
929
|
+
return this.settleApproved(tx, adminId, meta);
|
|
412
930
|
}
|
|
413
931
|
// Phase one: the pending -> processing flip under a FOR UPDATE lock. Extracted so the auto path can run it
|
|
414
932
|
// inside its advisory-locked cap-check transaction, committing the marker atomically. Never call the PSP here.
|
|
@@ -435,7 +953,7 @@ export class WalletService {
|
|
|
435
953
|
}
|
|
436
954
|
// Phase two: settle a `processing` withdrawal via the PSP (Completed on success, Failed + refund on error).
|
|
437
955
|
// Runs OUTSIDE the hold/flip transaction so the external PSP call never holds a DB lock.
|
|
438
|
-
async settleApproved(tx, adminId) {
|
|
956
|
+
async settleApproved(tx, adminId, meta) {
|
|
439
957
|
const userId = await this.userIdForWallet(tx.walletId);
|
|
440
958
|
const amount = tx.amount;
|
|
441
959
|
// approved/failed are admin-attributed events (schema requires a uuid adminId); the system auto path
|
|
@@ -447,61 +965,128 @@ export class WalletService {
|
|
|
447
965
|
currency: tx.currency,
|
|
448
966
|
transactionId: tx.id,
|
|
449
967
|
adminId,
|
|
968
|
+
ip: meta?.ip ?? null,
|
|
969
|
+
userAgent: meta?.userAgent ?? null,
|
|
450
970
|
});
|
|
451
971
|
}
|
|
972
|
+
const { providerName, adapter } = await this.paymentAdapterFor(tx.currency, tx.network);
|
|
452
973
|
let result;
|
|
453
974
|
try {
|
|
454
|
-
result = await
|
|
975
|
+
result = await adapter.processWithdrawal(amount, tx.currency, {
|
|
455
976
|
transactionId: tx.id,
|
|
456
977
|
userId,
|
|
457
978
|
rail: tx.rail,
|
|
458
979
|
adminId,
|
|
980
|
+
destinationAddress: tx.destinationAddress,
|
|
981
|
+
destinationTag: tx.destinationTag,
|
|
982
|
+
// The provider-side whitelisted destination for that address, when the bound adapter
|
|
983
|
+
// whitelists at all. Absent for an address that predates whitelisting or was never in
|
|
984
|
+
// the book, and such an adapter is expected to refuse rather than pay out to the raw
|
|
985
|
+
// address - the whitelist is the control, so bypassing it would defeat the point.
|
|
986
|
+
...(tx.destinationWalletId ? { destinationWalletId: tx.destinationWalletId } : {}),
|
|
987
|
+
// Pinned at request time; without it an adapter cannot tell ERC20 USDT from TRC20.
|
|
988
|
+
network: tx.network,
|
|
459
989
|
});
|
|
460
990
|
}
|
|
461
991
|
catch (err) {
|
|
462
992
|
// Payout did not happen - mark failed and return the held funds in one transaction.
|
|
463
|
-
await this.
|
|
464
|
-
await txn
|
|
465
|
-
.update(walletTransaction)
|
|
466
|
-
.set({ status: 'failed' })
|
|
467
|
-
.where(eq(walletTransaction.id, tx.id));
|
|
468
|
-
await txn
|
|
469
|
-
.update(wallet)
|
|
470
|
-
.set({ balance: sql `${wallet.balance} + ${amount}::numeric` })
|
|
471
|
-
.where(eq(wallet.id, tx.walletId));
|
|
472
|
-
});
|
|
473
|
-
if (adminId) {
|
|
474
|
-
this.events.emit('wallet.withdrawal.failed', {
|
|
475
|
-
userId,
|
|
476
|
-
amount,
|
|
477
|
-
currency: tx.currency,
|
|
478
|
-
transactionId: tx.id,
|
|
479
|
-
adminId,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
993
|
+
await this.finalizeFailedWithdrawal({ tx, adminId, userId, amount });
|
|
482
994
|
throw err;
|
|
483
995
|
}
|
|
996
|
+
if (result.status === 'failed') {
|
|
997
|
+
await this.finalizeFailedWithdrawal({ tx, adminId, userId, amount });
|
|
998
|
+
return { transactionId: tx.id, status: 'failed' };
|
|
999
|
+
}
|
|
1000
|
+
if (result.status !== 'completed') {
|
|
1001
|
+
await this.drizzle.db
|
|
1002
|
+
.update(walletTransaction)
|
|
1003
|
+
.set({
|
|
1004
|
+
providerName,
|
|
1005
|
+
providerRefId: result.externalId,
|
|
1006
|
+
})
|
|
1007
|
+
.where(eq(walletTransaction.id, tx.id));
|
|
1008
|
+
return { transactionId: tx.id, status: 'processing' };
|
|
1009
|
+
}
|
|
484
1010
|
await this.drizzle.db
|
|
485
1011
|
.update(walletTransaction)
|
|
486
1012
|
.set({
|
|
487
1013
|
status: 'completed',
|
|
488
|
-
providerName
|
|
1014
|
+
providerName,
|
|
489
1015
|
providerRefId: result.externalId,
|
|
490
1016
|
})
|
|
491
1017
|
.where(eq(walletTransaction.id, tx.id));
|
|
492
1018
|
this.events.emit('wallet.withdrawal.completed', {
|
|
493
1019
|
userId,
|
|
1020
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
494
1021
|
amount,
|
|
495
1022
|
currency: tx.currency,
|
|
496
1023
|
transactionId: tx.id,
|
|
497
1024
|
});
|
|
498
1025
|
return { transactionId: tx.id, status: 'completed' };
|
|
499
1026
|
}
|
|
1027
|
+
async finalizeFailedWithdrawal({ tx, adminId, userId, amount, }) {
|
|
1028
|
+
const transitioned = await this.drizzle.db.transaction(async (txn) => {
|
|
1029
|
+
const updated = await txn
|
|
1030
|
+
.update(walletTransaction)
|
|
1031
|
+
.set({ status: 'failed' })
|
|
1032
|
+
.where(and(eq(walletTransaction.id, tx.id), eq(walletTransaction.status, 'processing')))
|
|
1033
|
+
.returning({ id: walletTransaction.id });
|
|
1034
|
+
if (updated.length === 0) {
|
|
1035
|
+
return false;
|
|
1036
|
+
}
|
|
1037
|
+
await creditWalletBalance(txn, tx.walletId, tx.currency, amount);
|
|
1038
|
+
return true;
|
|
1039
|
+
});
|
|
1040
|
+
if (transitioned && adminId) {
|
|
1041
|
+
this.events.emit('wallet.withdrawal.failed', {
|
|
1042
|
+
userId,
|
|
1043
|
+
amount,
|
|
1044
|
+
currency: tx.currency,
|
|
1045
|
+
transactionId: tx.id,
|
|
1046
|
+
adminId,
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
async reconcileWithdrawalStatus(event) {
|
|
1051
|
+
const { externalId, status, txHash } = event;
|
|
1052
|
+
const [tx] = await this.drizzle.db
|
|
1053
|
+
.select()
|
|
1054
|
+
.from(walletTransaction)
|
|
1055
|
+
.where(eq(walletTransaction.providerRefId, externalId));
|
|
1056
|
+
if (!tx || tx.type !== 'withdrawal') {
|
|
1057
|
+
logger.warn({ externalId }, 'payment webhook: no matching withdrawal for providerRefId');
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (tx.status !== 'processing') {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
const userId = await this.userIdForWallet(tx.walletId);
|
|
1064
|
+
if (status === 'completed') {
|
|
1065
|
+
const updated = await this.drizzle.db
|
|
1066
|
+
.update(walletTransaction)
|
|
1067
|
+
.set({ status: 'completed', txHash: txHash ?? tx.txHash })
|
|
1068
|
+
.where(and(eq(walletTransaction.id, tx.id), eq(walletTransaction.status, 'processing')))
|
|
1069
|
+
.returning({ id: walletTransaction.id });
|
|
1070
|
+
if (updated.length === 0) {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
this.events.emit('wallet.withdrawal.completed', {
|
|
1074
|
+
userId,
|
|
1075
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
|
|
1076
|
+
amount: tx.amount,
|
|
1077
|
+
currency: tx.currency,
|
|
1078
|
+
transactionId: tx.id,
|
|
1079
|
+
});
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
if (status === 'failed') {
|
|
1083
|
+
await this.finalizeFailedWithdrawal({ tx, adminId: null, userId, amount: tx.amount });
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
500
1086
|
// Evaluates the auto-approval gates and settles the payout if all pass; returns undefined to
|
|
501
1087
|
// leave the row pending for the manual queue. NEVER throws: any error fails closed to manual.
|
|
502
1088
|
async maybeAutoApprove(args) {
|
|
503
|
-
|
|
504
|
-
if (!this.platformConfig?.autoWithdrawal?.enabled || args.rail !== 'fiat') {
|
|
1089
|
+
if (!this.platformConfig?.autoWithdrawal?.enabled) {
|
|
505
1090
|
return undefined;
|
|
506
1091
|
}
|
|
507
1092
|
try {
|
|
@@ -577,11 +1162,7 @@ export class WalletService {
|
|
|
577
1162
|
if (!cfg?.enabled) {
|
|
578
1163
|
return null;
|
|
579
1164
|
}
|
|
580
|
-
|
|
581
|
-
if (rail !== 'fiat') {
|
|
582
|
-
return null;
|
|
583
|
-
}
|
|
584
|
-
const threshold = await this.resolveAutoThreshold(userId);
|
|
1165
|
+
const threshold = await this.resolveAutoThreshold(userId, rail);
|
|
585
1166
|
if (!threshold || moneyToNumber(threshold.value) <= 0) {
|
|
586
1167
|
return null;
|
|
587
1168
|
}
|
|
@@ -590,15 +1171,16 @@ export class WalletService {
|
|
|
590
1171
|
}
|
|
591
1172
|
// Independent of kyc.gateWithdrawals: auto-approval always demands a passing status; anything else fails closed.
|
|
592
1173
|
const kycStatus = await this.autoApprovalKycStatus(userId);
|
|
593
|
-
if (!kycStatus || !KYC_PASS_STATUSES.has(kycStatus)) {
|
|
1174
|
+
if (!kycStatus || !KYC_PASS_STATUSES.has(normalizeKycStatus(kycStatus))) {
|
|
594
1175
|
return null;
|
|
595
1176
|
}
|
|
596
|
-
const
|
|
1177
|
+
const effectiveExcludeTags = threshold.config.excludeRiskFlags;
|
|
1178
|
+
const riskTags = await this.autoApprovalRiskTags(userId, effectiveExcludeTags);
|
|
597
1179
|
// null = exclusions configured but the lookup port is unavailable => fail closed.
|
|
598
1180
|
if (riskTags === null) {
|
|
599
1181
|
return null;
|
|
600
1182
|
}
|
|
601
|
-
if (riskTags.some((t) =>
|
|
1183
|
+
if (riskTags.some((t) => effectiveExcludeTags.includes(t))) {
|
|
602
1184
|
return null;
|
|
603
1185
|
}
|
|
604
1186
|
const heuristics = await this.autoApprovalHeuristics({ walletId, amount });
|
|
@@ -610,22 +1192,300 @@ export class WalletService {
|
|
|
610
1192
|
thresholdSource: threshold.source,
|
|
611
1193
|
kycStatus,
|
|
612
1194
|
riskTagsEvaluated: riskTags,
|
|
1195
|
+
effectiveExcludeTags,
|
|
613
1196
|
};
|
|
614
1197
|
}
|
|
615
|
-
|
|
616
|
-
|
|
1198
|
+
async resolveAutoThreshold(userId, rail) {
|
|
1199
|
+
// Always read the global singleton first, even when a per-player override may end up
|
|
1200
|
+
// winning below - an unseeded install (missing row) must fail closed for EVERY player,
|
|
1201
|
+
// not just those without an override. getAutoWithdrawalConfig() throws when absent.
|
|
1202
|
+
const config = await this.getAutoWithdrawalConfig();
|
|
617
1203
|
const [rule] = await this.drizzle.db
|
|
618
1204
|
.select()
|
|
619
1205
|
.from(autoWithdrawalRule)
|
|
620
1206
|
.where(eq(autoWithdrawalRule.userId, userId));
|
|
621
1207
|
if (rule) {
|
|
622
|
-
return { value: rule.threshold, source: 'per-player' };
|
|
1208
|
+
return { value: rule.threshold, source: 'per-player', config };
|
|
1209
|
+
}
|
|
1210
|
+
const global = rail === 'crypto' ? config.cryptoThreshold : config.fiatThreshold;
|
|
1211
|
+
return { value: global, source: 'global', config };
|
|
1212
|
+
}
|
|
1213
|
+
// The row always exists in a properly-seeded install (seeded once) - a
|
|
1214
|
+
// missing row is an unexpected failure mode on the READ path, not a normal
|
|
1215
|
+
// "unconfigured" state, so this throws rather than silently defaulting.
|
|
1216
|
+
// maybeAutoApprove's outer try/catch handles that thrown error the same as any
|
|
1217
|
+
// other unexpected error: fail closed to pending.
|
|
1218
|
+
async getAutoWithdrawalConfig() {
|
|
1219
|
+
const config = await this.getAutoWithdrawalConfigOrNull();
|
|
1220
|
+
if (!config) {
|
|
1221
|
+
throw new AutoWithdrawalConfigNotFoundError('global');
|
|
623
1222
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
1223
|
+
return config;
|
|
1224
|
+
}
|
|
1225
|
+
// Non-throwing variant for callers that need to tell "missing" from "found"
|
|
1226
|
+
// without a try/catch (eg the router's audit `before` read).
|
|
1227
|
+
async getAutoWithdrawalConfigOrNull() {
|
|
1228
|
+
const [row] = await this.drizzle.db
|
|
1229
|
+
.select()
|
|
1230
|
+
.from(walletAutoWithdrawalConfig)
|
|
1231
|
+
.where(eq(walletAutoWithdrawalConfig.singletonKey, 'global'));
|
|
1232
|
+
return row ? toAutoWithdrawalConfigDto(row) : null;
|
|
1233
|
+
}
|
|
1234
|
+
// Upsert, not a plain UPDATE: the WRITE path lets a Super Admin self-heal a
|
|
1235
|
+
// missing singleton row (eg an install that skipped the seed step) through the
|
|
1236
|
+
// existing route with zero new surface. The READ path (getAutoWithdrawalConfig,
|
|
1237
|
+
// resolveAutoThreshold) still throws on a missing row and stays fail-closed -
|
|
1238
|
+
// a withdrawal must never silently create config.
|
|
1239
|
+
//
|
|
1240
|
+
// Update + audit write run in one transaction: an audit-write failure must roll back
|
|
1241
|
+
// the threshold change too, or the config could change with no audit trail.
|
|
1242
|
+
async setAutoWithdrawalConfig(adminId, { fiatThreshold, cryptoThreshold, excludeRiskFlags, }, meta) {
|
|
1243
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1244
|
+
const [before] = await txn
|
|
1245
|
+
.select()
|
|
1246
|
+
.from(walletAutoWithdrawalConfig)
|
|
1247
|
+
.where(eq(walletAutoWithdrawalConfig.singletonKey, 'global'));
|
|
1248
|
+
const rows = await txn
|
|
1249
|
+
.insert(walletAutoWithdrawalConfig)
|
|
1250
|
+
.values({
|
|
1251
|
+
singletonKey: 'global',
|
|
1252
|
+
fiatThreshold,
|
|
1253
|
+
cryptoThreshold,
|
|
1254
|
+
excludeRiskFlags,
|
|
1255
|
+
updatedBy: adminId,
|
|
1256
|
+
})
|
|
1257
|
+
.onConflictDoUpdate({
|
|
1258
|
+
target: walletAutoWithdrawalConfig.singletonKey,
|
|
1259
|
+
set: { fiatThreshold, cryptoThreshold, excludeRiskFlags, updatedBy: adminId },
|
|
1260
|
+
})
|
|
1261
|
+
.returning();
|
|
1262
|
+
const config = toAutoWithdrawalConfigDto(findOneOrThrow(rows, new AutoWithdrawalConfigNotFoundError('global')));
|
|
1263
|
+
await this.audit.recordInTransaction(txn, {
|
|
1264
|
+
actorId: adminId,
|
|
1265
|
+
actorType: 'admin',
|
|
1266
|
+
action: 'wallet.auto_withdrawal_config.set',
|
|
1267
|
+
resourceType: 'auto_withdrawal_config',
|
|
1268
|
+
resourceId: config.id,
|
|
1269
|
+
before: before
|
|
1270
|
+
? {
|
|
1271
|
+
fiatThreshold: before.fiatThreshold,
|
|
1272
|
+
cryptoThreshold: before.cryptoThreshold,
|
|
1273
|
+
excludeRiskFlags: before.excludeRiskFlags,
|
|
1274
|
+
}
|
|
1275
|
+
: null,
|
|
1276
|
+
after: {
|
|
1277
|
+
fiatThreshold: config.fiatThreshold,
|
|
1278
|
+
cryptoThreshold: config.cryptoThreshold,
|
|
1279
|
+
excludeRiskFlags: config.excludeRiskFlags,
|
|
1280
|
+
},
|
|
1281
|
+
...meta,
|
|
1282
|
+
});
|
|
1283
|
+
return config;
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
async getBonusRolloverStatus(userId, status = 'active') {
|
|
1287
|
+
const rows = await this.drizzle.db
|
|
1288
|
+
.select()
|
|
1289
|
+
.from(walletBonusCredit)
|
|
1290
|
+
.where(and(eq(walletBonusCredit.userId, userId), eq(walletBonusCredit.status, status)))
|
|
1291
|
+
.orderBy(desc(walletBonusCredit.createdAt))
|
|
1292
|
+
.limit(50);
|
|
1293
|
+
return { credits: rows.map(toBonusCreditDto) };
|
|
1294
|
+
}
|
|
1295
|
+
async getBonusRolloverConfig() {
|
|
1296
|
+
const config = await this.getBonusRolloverConfigOrNull();
|
|
1297
|
+
if (!config) {
|
|
1298
|
+
throw new BonusRolloverConfigNotFoundError('global');
|
|
627
1299
|
}
|
|
628
|
-
return
|
|
1300
|
+
return config;
|
|
1301
|
+
}
|
|
1302
|
+
async getBonusRolloverConfigOrNull() {
|
|
1303
|
+
const [row] = await this.drizzle.db
|
|
1304
|
+
.select()
|
|
1305
|
+
.from(walletBonusRolloverConfig)
|
|
1306
|
+
.where(eq(walletBonusRolloverConfig.singletonKey, 'global'));
|
|
1307
|
+
return row ? toBonusRolloverConfigDto(row) : null;
|
|
1308
|
+
}
|
|
1309
|
+
async setBonusRolloverConfig(adminId, { multiplier }, meta) {
|
|
1310
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1311
|
+
const [before] = await txn
|
|
1312
|
+
.select()
|
|
1313
|
+
.from(walletBonusRolloverConfig)
|
|
1314
|
+
.where(eq(walletBonusRolloverConfig.singletonKey, 'global'));
|
|
1315
|
+
const rows = await txn
|
|
1316
|
+
.insert(walletBonusRolloverConfig)
|
|
1317
|
+
.values({ singletonKey: 'global', multiplier, updatedBy: adminId })
|
|
1318
|
+
.onConflictDoUpdate({
|
|
1319
|
+
target: walletBonusRolloverConfig.singletonKey,
|
|
1320
|
+
set: { multiplier, updatedBy: adminId, updatedAt: new Date() },
|
|
1321
|
+
})
|
|
1322
|
+
.returning();
|
|
1323
|
+
const config = toBonusRolloverConfigDto(findOneOrThrow(rows, new BonusRolloverConfigNotFoundError('global')));
|
|
1324
|
+
await this.audit.recordInTransaction(txn, {
|
|
1325
|
+
actorId: adminId,
|
|
1326
|
+
actorType: 'admin',
|
|
1327
|
+
action: 'wallet.bonus_rollover_config.set',
|
|
1328
|
+
resourceType: 'bonus_rollover_config',
|
|
1329
|
+
resourceId: config.id,
|
|
1330
|
+
before: before ? { multiplier: before.multiplier } : null,
|
|
1331
|
+
after: { multiplier: config.multiplier },
|
|
1332
|
+
...meta,
|
|
1333
|
+
});
|
|
1334
|
+
return config;
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
async listWalletAssets() {
|
|
1338
|
+
const rows = await this.drizzle.db
|
|
1339
|
+
.select()
|
|
1340
|
+
.from(walletAsset)
|
|
1341
|
+
.orderBy(asc(walletAsset.currency), asc(walletAsset.network));
|
|
1342
|
+
return rows.map(toWalletAssetDto);
|
|
1343
|
+
}
|
|
1344
|
+
listEnabledWalletAssets() {
|
|
1345
|
+
return this.drizzle.db
|
|
1346
|
+
.select(PUBLIC_ASSET_COLUMNS)
|
|
1347
|
+
.from(walletAsset)
|
|
1348
|
+
.where(or(eq(walletAsset.depositEnabled, true), eq(walletAsset.withdrawalEnabled, true)))
|
|
1349
|
+
.orderBy(asc(walletAsset.currency), asc(walletAsset.network));
|
|
1350
|
+
}
|
|
1351
|
+
async getWalletAsset(currency, network) {
|
|
1352
|
+
const [row] = await this.drizzle.db
|
|
1353
|
+
.select()
|
|
1354
|
+
.from(walletAsset)
|
|
1355
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1356
|
+
return row ? toWalletAssetDto(row) : null;
|
|
1357
|
+
}
|
|
1358
|
+
// The catalog is operator-editable, so an admin can name a pair the bound vendor has
|
|
1359
|
+
// never heard of. Reject at write time rather than at a player's deposit request.
|
|
1360
|
+
assertAdapterSupports(currency, network, providerName) {
|
|
1361
|
+
const adapter = (providerName ? this.paymentProviders.get(providerName)?.adapter : undefined) ?? this.payment;
|
|
1362
|
+
if (adapter.supportsAsset && !adapter.supportsAsset(currency, network)) {
|
|
1363
|
+
throw new WalletAssetUnsupportedError();
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
// Same discipline as assertAdapterSupports, for the provider key itself: an
|
|
1367
|
+
// unvalidated typo silently falls back to the default adapter, which means eg a
|
|
1368
|
+
// crypto payout attempted through a PSP. Undefined (the default binding) always passes.
|
|
1369
|
+
assertProviderNameValid(providerName) {
|
|
1370
|
+
if (providerName !== undefined && !this.paymentProviders.names().includes(providerName)) {
|
|
1371
|
+
throw new WalletAssetUnknownProviderError();
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
async createWalletAsset(adminId, input, meta) {
|
|
1375
|
+
this.assertProviderNameValid(input.providerName);
|
|
1376
|
+
this.assertAdapterSupports(input.currency, input.network, input.providerName);
|
|
1377
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1378
|
+
const rows = await txn.insert(walletAsset).values(input).onConflictDoNothing().returning();
|
|
1379
|
+
// Empty => the (currency, network) unique index rejected it.
|
|
1380
|
+
const asset = toWalletAssetDto(findOneOrThrow(rows, new WalletAssetAlreadyExistsError()));
|
|
1381
|
+
await this.audit.recordInTransaction(txn, {
|
|
1382
|
+
actorId: adminId,
|
|
1383
|
+
actorType: 'admin',
|
|
1384
|
+
action: 'wallet.wallet_asset.created',
|
|
1385
|
+
resourceType: 'wallet_asset',
|
|
1386
|
+
resourceId: asset.id,
|
|
1387
|
+
before: null,
|
|
1388
|
+
after: asset,
|
|
1389
|
+
...meta,
|
|
1390
|
+
});
|
|
1391
|
+
return asset;
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
// Deliberately touches only the catalog row: a withdrawal already pending or processing
|
|
1395
|
+
// in this currency keeps its own terms and is never cancelled by disabling the pair.
|
|
1396
|
+
async updateWalletAsset(adminId, { currency, network, ...changes }, meta) {
|
|
1397
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1398
|
+
const [before] = await txn
|
|
1399
|
+
.select()
|
|
1400
|
+
.from(walletAsset)
|
|
1401
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)))
|
|
1402
|
+
// Held until commit, so an address issuance that already gated against this row
|
|
1403
|
+
// (see depositAssetsForCurrency) commits its address first and is then seen by
|
|
1404
|
+
// the in-use count below, instead of slipping in behind the delete.
|
|
1405
|
+
.for('update');
|
|
1406
|
+
if (!before) {
|
|
1407
|
+
throw new WalletAssetNotFoundError(`${currency}/${network}`);
|
|
1408
|
+
}
|
|
1409
|
+
if (changes.providerAssetId !== undefined) {
|
|
1410
|
+
this.assertAdapterSupports(currency, network, before.providerName ?? undefined);
|
|
1411
|
+
}
|
|
1412
|
+
const rows = await txn
|
|
1413
|
+
.update(walletAsset)
|
|
1414
|
+
.set(changes)
|
|
1415
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)))
|
|
1416
|
+
.returning();
|
|
1417
|
+
const asset = toWalletAssetDto(findOneOrThrow(rows, new WalletAssetNotFoundError(`${currency}/${network}`)));
|
|
1418
|
+
await this.audit.recordInTransaction(txn, {
|
|
1419
|
+
actorId: adminId,
|
|
1420
|
+
actorType: 'admin',
|
|
1421
|
+
action: 'wallet.wallet_asset.updated',
|
|
1422
|
+
resourceType: 'wallet_asset',
|
|
1423
|
+
resourceId: asset.id,
|
|
1424
|
+
before: toWalletAssetDto(before),
|
|
1425
|
+
after: asset,
|
|
1426
|
+
...meta,
|
|
1427
|
+
});
|
|
1428
|
+
return asset;
|
|
1429
|
+
});
|
|
1430
|
+
}
|
|
1431
|
+
async deleteWalletAsset(adminId, currency, network, meta) {
|
|
1432
|
+
return this.drizzle.db.transaction(async (txn) => {
|
|
1433
|
+
const [before] = await txn
|
|
1434
|
+
.select()
|
|
1435
|
+
.from(walletAsset)
|
|
1436
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)))
|
|
1437
|
+
// Held until commit, so an address issuance that already gated against this row
|
|
1438
|
+
// (see depositAssetsForCurrency) commits its address first and is then seen by
|
|
1439
|
+
// the in-use count below, instead of slipping in behind the delete.
|
|
1440
|
+
.for('update');
|
|
1441
|
+
if (!before) {
|
|
1442
|
+
return false;
|
|
1443
|
+
}
|
|
1444
|
+
// wallet_balance is keyed by currency only (no network column), so this guard is
|
|
1445
|
+
// necessarily currency-wide: removing one network of a currency players still hold
|
|
1446
|
+
// is blocked even if their balance arrived over another network. Fails safe.
|
|
1447
|
+
const held = await txn
|
|
1448
|
+
.select({ id: walletBalance.id })
|
|
1449
|
+
.from(walletBalance)
|
|
1450
|
+
.where(and(eq(walletBalance.currency, currency), sql `${walletBalance.amount} > 0`))
|
|
1451
|
+
.for('update');
|
|
1452
|
+
if (held.length > 0) {
|
|
1453
|
+
throw new WalletAssetInUseError();
|
|
1454
|
+
}
|
|
1455
|
+
const [issued] = await txn
|
|
1456
|
+
.select({ n: count() })
|
|
1457
|
+
.from(walletDepositAddress)
|
|
1458
|
+
.where(and(eq(walletDepositAddress.currency, currency), eq(walletDepositAddress.network, network)));
|
|
1459
|
+
if ((issued?.n ?? 0) > 0) {
|
|
1460
|
+
throw new WalletAssetInUseError();
|
|
1461
|
+
}
|
|
1462
|
+
// Renaming a pair is a delete plus a create (the (currency, network) key AND
|
|
1463
|
+
// providerName are immutable), so this delete is the only way providerName ever
|
|
1464
|
+
// effectively changes. Block it while a pending/processing transaction exists for
|
|
1465
|
+
// this exact (currency, network) pair - otherwise the vendor reference an in-flight
|
|
1466
|
+
// payout is settling through gets rewritten out from under it.
|
|
1467
|
+
const [inFlight] = await txn
|
|
1468
|
+
.select({ n: count() })
|
|
1469
|
+
.from(walletTransaction)
|
|
1470
|
+
.where(and(eq(walletTransaction.currency, currency), eq(walletTransaction.network, network), inArray(walletTransaction.status, ['pending', 'processing'])));
|
|
1471
|
+
if ((inFlight?.n ?? 0) > 0) {
|
|
1472
|
+
throw new WalletAssetHasInFlightTransactionsError();
|
|
1473
|
+
}
|
|
1474
|
+
await txn
|
|
1475
|
+
.delete(walletAsset)
|
|
1476
|
+
.where(and(eq(walletAsset.currency, currency), eq(walletAsset.network, network)));
|
|
1477
|
+
await this.audit.recordInTransaction(txn, {
|
|
1478
|
+
actorId: adminId,
|
|
1479
|
+
actorType: 'admin',
|
|
1480
|
+
action: 'wallet.wallet_asset.deleted',
|
|
1481
|
+
resourceType: 'wallet_asset',
|
|
1482
|
+
resourceId: before.id,
|
|
1483
|
+
before: toWalletAssetDto(before),
|
|
1484
|
+
after: null,
|
|
1485
|
+
...meta,
|
|
1486
|
+
});
|
|
1487
|
+
return true;
|
|
1488
|
+
});
|
|
629
1489
|
}
|
|
630
1490
|
async autoApprovalKycStatus(userId) {
|
|
631
1491
|
// No directory bound => cannot verify KYC => fail closed.
|
|
@@ -718,7 +1578,7 @@ export class WalletService {
|
|
|
718
1578
|
.returning({ id: autoWithdrawalRule.id });
|
|
719
1579
|
return deleted.length > 0;
|
|
720
1580
|
}
|
|
721
|
-
async rejectWithdrawal(adminId, withdrawalId, reason) {
|
|
1581
|
+
async rejectWithdrawal(adminId, withdrawalId, reason, meta) {
|
|
722
1582
|
const reviewedAt = new Date();
|
|
723
1583
|
const tx = await this.drizzle.db.transaction(async (txn) => {
|
|
724
1584
|
const current = findOneOrThrow(await txn
|
|
@@ -734,10 +1594,7 @@ export class WalletService {
|
|
|
734
1594
|
.set({ status: 'rejected', reviewedBy: adminId, reviewedAt, reviewReason: reason })
|
|
735
1595
|
.where(eq(walletTransaction.id, withdrawalId))
|
|
736
1596
|
.returning(), new WithdrawalNotFoundError(withdrawalId));
|
|
737
|
-
await txn
|
|
738
|
-
.update(wallet)
|
|
739
|
-
.set({ balance: sql `${wallet.balance} + ${updated.amount}::numeric` })
|
|
740
|
-
.where(eq(wallet.id, updated.walletId));
|
|
1597
|
+
await creditWalletBalance(txn, updated.walletId, updated.currency, updated.amount);
|
|
741
1598
|
return updated;
|
|
742
1599
|
});
|
|
743
1600
|
const userId = await this.userIdForWallet(tx.walletId);
|
|
@@ -748,22 +1605,35 @@ export class WalletService {
|
|
|
748
1605
|
transactionId: tx.id,
|
|
749
1606
|
adminId,
|
|
750
1607
|
reason,
|
|
1608
|
+
ip: meta?.ip ?? null,
|
|
1609
|
+
userAgent: meta?.userAgent ?? null,
|
|
751
1610
|
});
|
|
752
1611
|
return { transactionId: tx.id, status: 'rejected' };
|
|
753
1612
|
}
|
|
754
|
-
async getTransactions(userId, page, limit) {
|
|
1613
|
+
async getTransactions({ userId, page, limit, sortBy, sortOrder, includeInternal = false, }) {
|
|
755
1614
|
const db = this.drizzle.db;
|
|
756
1615
|
const [walletRecord] = await db.select().from(wallet).where(eq(wallet.userId, userId));
|
|
757
1616
|
if (!walletRecord) {
|
|
758
1617
|
return { items: [], total: 0, page, limit };
|
|
759
1618
|
}
|
|
1619
|
+
const dir = (sortOrder ?? 'desc') === 'asc' ? asc : desc;
|
|
1620
|
+
const TX_SORT_COLS = {
|
|
1621
|
+
createdAt: walletTransaction.createdAt,
|
|
1622
|
+
amount: walletTransaction.amount,
|
|
1623
|
+
type: walletTransaction.type,
|
|
1624
|
+
status: walletTransaction.status,
|
|
1625
|
+
currency: walletTransaction.currency,
|
|
1626
|
+
rail: walletTransaction.rail,
|
|
1627
|
+
reviewedAt: walletTransaction.reviewedAt,
|
|
1628
|
+
};
|
|
1629
|
+
const col = TX_SORT_COLS[sortBy ?? 'createdAt'];
|
|
760
1630
|
const where = eq(walletTransaction.walletId, walletRecord.id);
|
|
761
1631
|
const [txs, [{ n }]] = await Promise.all([
|
|
762
1632
|
db
|
|
763
1633
|
.select()
|
|
764
1634
|
.from(walletTransaction)
|
|
765
1635
|
.where(where)
|
|
766
|
-
.orderBy(desc(walletTransaction.
|
|
1636
|
+
.orderBy(dir(col), desc(walletTransaction.id))
|
|
767
1637
|
.limit(limit)
|
|
768
1638
|
.offset(pageToOffset(page, limit)),
|
|
769
1639
|
db.select({ n: count() }).from(walletTransaction).where(where),
|
|
@@ -774,14 +1644,163 @@ export class WalletService {
|
|
|
774
1644
|
type: tx.type,
|
|
775
1645
|
amount: tx.amount,
|
|
776
1646
|
currency: tx.currency,
|
|
1647
|
+
network: tx.network,
|
|
777
1648
|
status: tx.status,
|
|
1649
|
+
direction: tx.direction,
|
|
778
1650
|
createdAt: tx.createdAt.toISOString(),
|
|
1651
|
+
reviewedBy: includeInternal ? tx.reviewedBy : null,
|
|
1652
|
+
reviewedAt: includeInternal ? (tx.reviewedAt?.toISOString() ?? null) : null,
|
|
1653
|
+
reviewReason: includeInternal || MANUAL_ADJUSTMENT_TYPES.has(tx.type) ? tx.reviewReason : null,
|
|
779
1654
|
})),
|
|
780
1655
|
total: Number(n),
|
|
781
1656
|
page,
|
|
782
1657
|
limit,
|
|
783
1658
|
};
|
|
784
1659
|
}
|
|
1660
|
+
async getOrCreateDepositAddress(userId, currency, network) {
|
|
1661
|
+
await this.assertDepositable(currency, undefined, network);
|
|
1662
|
+
const existing = await this.findDepositAddress(userId, currency, network);
|
|
1663
|
+
if (existing) {
|
|
1664
|
+
return toDepositAddressResult(existing);
|
|
1665
|
+
}
|
|
1666
|
+
const { providerName, adapter } = await this.paymentAdapterFor(currency, network ?? null);
|
|
1667
|
+
if (!adapter.issueDepositAddress) {
|
|
1668
|
+
throw new DepositAddressUnsupportedError();
|
|
1669
|
+
}
|
|
1670
|
+
const issued = await adapter.issueDepositAddress(userId, currency, network);
|
|
1671
|
+
// Re-gate inside the transaction that writes the row: the catalog pair can be
|
|
1672
|
+
// disabled or deleted while the vendor call is in flight, and this is what makes
|
|
1673
|
+
// deleteWalletAsset's in-use check race-free.
|
|
1674
|
+
const [row] = await this.drizzle.db.transaction(async (txn) => {
|
|
1675
|
+
await this.assertDepositable(currency, undefined, network, txn);
|
|
1676
|
+
return txn
|
|
1677
|
+
.insert(walletDepositAddress)
|
|
1678
|
+
.values({
|
|
1679
|
+
userId,
|
|
1680
|
+
currency,
|
|
1681
|
+
network: network ?? null,
|
|
1682
|
+
address: issued.address,
|
|
1683
|
+
tag: issued.tag ?? null,
|
|
1684
|
+
providerName,
|
|
1685
|
+
})
|
|
1686
|
+
.onConflictDoNothing()
|
|
1687
|
+
.returning();
|
|
1688
|
+
});
|
|
1689
|
+
if (row) {
|
|
1690
|
+
return toDepositAddressResult(row);
|
|
1691
|
+
}
|
|
1692
|
+
const winner = await this.findDepositAddress(userId, currency, network);
|
|
1693
|
+
if (!winner) {
|
|
1694
|
+
throw new Error(`wallet deposit address: idempotency conflict but no row found (userId=${userId}, currency=${currency}, network=${network ?? 'none'})`);
|
|
1695
|
+
}
|
|
1696
|
+
return toDepositAddressResult(winner);
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* `providerName` is the vendor the webhook route already resolved (verifier + adapter
|
|
1700
|
+
* came from the same registry entry) - it is only used to label a finding when this
|
|
1701
|
+
* deposit can't be attributed, never to look anything up. Defaults to the single
|
|
1702
|
+
* default binding for callers (tests, a poller with no named provider) that don't care.
|
|
1703
|
+
*/
|
|
1704
|
+
async creditDepositByAddress(event, providerName = DEFAULT_PAYMENT_PROVIDER) {
|
|
1705
|
+
const depositAddress = await this.findDepositAddressByAddress(event);
|
|
1706
|
+
if (!depositAddress) {
|
|
1707
|
+
// A known vendor defect hits this live: a token deposit reported under a sibling
|
|
1708
|
+
// token's asset id never resolves to a row. Never let it survive only as a log
|
|
1709
|
+
// line - file a finding so an operator can attribute and manually credit it.
|
|
1710
|
+
logger.warn({ address: event.address, network: event.network, tag: event.tag }, 'payment webhook: no wallet_deposit_address for inbound deposit');
|
|
1711
|
+
await recordReconciliationFinding(this.drizzle.db, {
|
|
1712
|
+
runId: LIVE_WEBHOOK_RUN_ID,
|
|
1713
|
+
providerName,
|
|
1714
|
+
kind: 'unattributed_deposit',
|
|
1715
|
+
currency: event.currency,
|
|
1716
|
+
network: event.network ?? null,
|
|
1717
|
+
amount: event.amount,
|
|
1718
|
+
address: event.address,
|
|
1719
|
+
tag: event.tag ?? null,
|
|
1720
|
+
txHash: event.txHash,
|
|
1721
|
+
externalId: event.externalId,
|
|
1722
|
+
detail: 'no wallet_deposit_address matched this address/network/tag',
|
|
1723
|
+
}, this.audit);
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
if (event.network === undefined &&
|
|
1727
|
+
event.currency.toUpperCase() !== depositAddress.currency.toUpperCase()) {
|
|
1728
|
+
// Same "do not silently drop" discipline as the no-address branch above - this is
|
|
1729
|
+
// the push-path counterpart to the poll-path's currency_mismatch finding.
|
|
1730
|
+
logger.warn({
|
|
1731
|
+
address: event.address,
|
|
1732
|
+
eventCurrency: event.currency,
|
|
1733
|
+
addressCurrency: depositAddress.currency,
|
|
1734
|
+
}, 'payment webhook: currency mismatch for inbound deposit');
|
|
1735
|
+
await recordReconciliationFinding(this.drizzle.db, {
|
|
1736
|
+
runId: LIVE_WEBHOOK_RUN_ID,
|
|
1737
|
+
providerName: depositAddress.providerName,
|
|
1738
|
+
kind: 'currency_mismatch',
|
|
1739
|
+
currency: event.currency,
|
|
1740
|
+
network: event.network ?? depositAddress.network,
|
|
1741
|
+
amount: event.amount,
|
|
1742
|
+
address: event.address,
|
|
1743
|
+
tag: event.tag ?? null,
|
|
1744
|
+
txHash: event.txHash,
|
|
1745
|
+
externalId: event.externalId,
|
|
1746
|
+
detail: `currency mismatch: event reported ${event.currency}, address issued for ${depositAddress.currency}`,
|
|
1747
|
+
}, this.audit);
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
const { transactionId, replayed } = await this.drizzle.db.transaction(async (txn) => {
|
|
1751
|
+
let [walletRecord] = await txn
|
|
1752
|
+
.select()
|
|
1753
|
+
.from(wallet)
|
|
1754
|
+
.where(eq(wallet.userId, depositAddress.userId));
|
|
1755
|
+
if (!walletRecord) {
|
|
1756
|
+
walletRecord = findOneOrThrow(await txn
|
|
1757
|
+
.insert(wallet)
|
|
1758
|
+
.values({ userId: depositAddress.userId, currency: event.currency })
|
|
1759
|
+
.returning(), new WalletNotFoundError(depositAddress.userId));
|
|
1760
|
+
}
|
|
1761
|
+
const [inserted] = await txn
|
|
1762
|
+
.insert(walletTransaction)
|
|
1763
|
+
.values({
|
|
1764
|
+
walletId: walletRecord.id,
|
|
1765
|
+
type: 'deposit',
|
|
1766
|
+
amount: event.amount,
|
|
1767
|
+
currency: event.currency,
|
|
1768
|
+
status: 'completed',
|
|
1769
|
+
direction: 'credit',
|
|
1770
|
+
rail: this.resolveRail(event.currency),
|
|
1771
|
+
// Prefer the chain the vendor reported; fall back to the one the address was
|
|
1772
|
+
// issued on, which is the only network an address-only webhook can imply.
|
|
1773
|
+
network: event.network ?? depositAddress.network,
|
|
1774
|
+
providerName: depositAddress.providerName,
|
|
1775
|
+
providerRefId: event.externalId,
|
|
1776
|
+
destinationAddress: event.address,
|
|
1777
|
+
txHash: event.txHash,
|
|
1778
|
+
})
|
|
1779
|
+
.onConflictDoNothing()
|
|
1780
|
+
.returning();
|
|
1781
|
+
if (inserted) {
|
|
1782
|
+
await creditWalletBalance(txn, walletRecord.id, event.currency, event.amount);
|
|
1783
|
+
return { transactionId: inserted.id, replayed: false };
|
|
1784
|
+
}
|
|
1785
|
+
const [winner] = await txn
|
|
1786
|
+
.select()
|
|
1787
|
+
.from(walletTransaction)
|
|
1788
|
+
.where(eq(walletTransaction.providerRefId, event.externalId));
|
|
1789
|
+
if (!winner) {
|
|
1790
|
+
throw new Error(`payment webhook: idempotency conflict but no row found (externalId=${event.externalId})`);
|
|
1791
|
+
}
|
|
1792
|
+
return { transactionId: winner.id, replayed: true };
|
|
1793
|
+
});
|
|
1794
|
+
if (!replayed) {
|
|
1795
|
+
this.events.emit('wallet.deposit.completed', {
|
|
1796
|
+
userId: depositAddress.userId,
|
|
1797
|
+
playerId: await this.identityReader.getPlayerIdByUserIdSafe(depositAddress.userId),
|
|
1798
|
+
amount: event.amount,
|
|
1799
|
+
currency: event.currency,
|
|
1800
|
+
transactionId,
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
785
1804
|
async userIdForWallet(walletId) {
|
|
786
1805
|
const record = findOneOrThrow(await this.drizzle.db
|
|
787
1806
|
.select({ userId: wallet.userId })
|
|
@@ -796,5 +1815,190 @@ export class WalletService {
|
|
|
796
1815
|
.where(and(eq(walletTransaction.walletId, walletId), eq(walletTransaction.idempotencyKey, idempotencyKey)));
|
|
797
1816
|
return existing;
|
|
798
1817
|
}
|
|
1818
|
+
async findDepositAddress(userId, currency, network) {
|
|
1819
|
+
const [row] = await this.drizzle.db
|
|
1820
|
+
.select()
|
|
1821
|
+
.from(walletDepositAddress)
|
|
1822
|
+
.where(and(eq(walletDepositAddress.userId, userId), eq(walletDepositAddress.currency, currency), network === undefined
|
|
1823
|
+
? isNull(walletDepositAddress.network)
|
|
1824
|
+
: eq(walletDepositAddress.network, network)));
|
|
1825
|
+
return row;
|
|
1826
|
+
}
|
|
1827
|
+
async findDepositAddressByAddress({ address, network, tag, }) {
|
|
1828
|
+
const rows = await this.drizzle.db
|
|
1829
|
+
.select()
|
|
1830
|
+
.from(walletDepositAddress)
|
|
1831
|
+
.where(and(eq(walletDepositAddress.address, address), tag === undefined ? isNull(walletDepositAddress.tag) : eq(walletDepositAddress.tag, tag), network === undefined
|
|
1832
|
+
? undefined
|
|
1833
|
+
: or(eq(walletDepositAddress.network, network), isNull(walletDepositAddress.network))));
|
|
1834
|
+
const owners = new Set(rows.map((row) => row.userId));
|
|
1835
|
+
if (owners.size > 1) {
|
|
1836
|
+
throw new AmbiguousDepositAddressError(address, network);
|
|
1837
|
+
}
|
|
1838
|
+
return rows.find((row) => row.network === network) ?? rows[0];
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* The player's own payout address book. Every method here is scoped on `userId` - a
|
|
1842
|
+
* saved address is personal data with no admin read path, so there is
|
|
1843
|
+
* deliberately no variant of these that takes an arbitrary user id.
|
|
1844
|
+
*/
|
|
1845
|
+
async listWithdrawalAddresses(userId, currency) {
|
|
1846
|
+
const rows = await this.drizzle.db
|
|
1847
|
+
.select()
|
|
1848
|
+
.from(walletWithdrawalAddress)
|
|
1849
|
+
.where(and(eq(walletWithdrawalAddress.userId, userId), currency === undefined ? undefined : eq(walletWithdrawalAddress.currency, currency)))
|
|
1850
|
+
.orderBy(desc(walletWithdrawalAddress.createdAt));
|
|
1851
|
+
return rows.map(toWithdrawalAddressDto);
|
|
1852
|
+
}
|
|
1853
|
+
async createWithdrawalAddress(userId, input, meta) {
|
|
1854
|
+
// Shares the wallet mutation budget with deposit/withdraw: the row cap alone does
|
|
1855
|
+
// not bound writes, since deleting frees a slot and lets a client churn forever.
|
|
1856
|
+
await this.rateLimit(userId);
|
|
1857
|
+
// ponytail: count-then-insert, so N concurrent creates can land N over the cap.
|
|
1858
|
+
// Move to an insert...where (select count) < limit if that ever matters.
|
|
1859
|
+
const [existing] = await this.drizzle.db
|
|
1860
|
+
.select({ total: count() })
|
|
1861
|
+
.from(walletWithdrawalAddress)
|
|
1862
|
+
.where(eq(walletWithdrawalAddress.userId, userId));
|
|
1863
|
+
if ((existing?.total ?? 0) >= WITHDRAWAL_ADDRESS_LIMIT) {
|
|
1864
|
+
throw new WithdrawalAddressLimitReachedError(WITHDRAWAL_ADDRESS_LIMIT);
|
|
1865
|
+
}
|
|
1866
|
+
// Registered with the custody provider BEFORE the row exists, so a rejected or unreachable
|
|
1867
|
+
// provider leaves no saved address the player would believe they can withdraw to. The port
|
|
1868
|
+
// is required to be idempotent, so the conflict path below cannot orphan a destination.
|
|
1869
|
+
const whitelisted = await this.whitelistWithdrawalAddress(userId, input);
|
|
1870
|
+
// onConflictDoNothing turns the unique index into a domain conflict rather than a
|
|
1871
|
+
// 500 - a double-submitted form is a 409, not an incident.
|
|
1872
|
+
const [row] = await this.drizzle.db
|
|
1873
|
+
.insert(walletWithdrawalAddress)
|
|
1874
|
+
.values({ userId, ...input, ...whitelisted })
|
|
1875
|
+
.onConflictDoNothing()
|
|
1876
|
+
.returning();
|
|
1877
|
+
if (!row) {
|
|
1878
|
+
throw new WithdrawalAddressAlreadyExistsError();
|
|
1879
|
+
}
|
|
1880
|
+
await this.audit.record({
|
|
1881
|
+
actorId: userId,
|
|
1882
|
+
actorType: 'player',
|
|
1883
|
+
action: 'wallet.withdrawal_address.created',
|
|
1884
|
+
resourceType: 'wallet_withdrawal_address',
|
|
1885
|
+
resourceId: row.id,
|
|
1886
|
+
// The address string is deliberately absent: the audit log is admin-readable and
|
|
1887
|
+
// a player's saved addresses are not. The row id is enough to correlate.
|
|
1888
|
+
after: { label: row.label, currency: row.currency, network: row.network },
|
|
1889
|
+
...meta,
|
|
1890
|
+
});
|
|
1891
|
+
return toWithdrawalAddressDto(row);
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Refuses a payout to a destination the provider has not approved. A no-op for an adapter that
|
|
1895
|
+
* does not whitelist, and for a fiat rail, which has no address at all.
|
|
1896
|
+
*
|
|
1897
|
+
* The tag is matched as strictly as the address. On a tag chain one exchange address is shared
|
|
1898
|
+
* by every account behind it, so an address-only check would let a player whitelist their own
|
|
1899
|
+
* account at that exchange and then pay out to a stranger's tag at the same address - an
|
|
1900
|
+
* auto-approved withdrawal would do it with nobody looking.
|
|
1901
|
+
*/
|
|
1902
|
+
async requireWhitelistedWalletId(userId, currency, network, destinationAddress, destinationTag) {
|
|
1903
|
+
if (!this.payment.whitelistWithdrawalAddress || !destinationAddress) {
|
|
1904
|
+
return null;
|
|
1905
|
+
}
|
|
1906
|
+
const walletId = await this.whitelistedWalletId(userId, currency, network, destinationAddress, destinationTag);
|
|
1907
|
+
if (!walletId) {
|
|
1908
|
+
throw new DestinationAddressNotWhitelistedError();
|
|
1909
|
+
}
|
|
1910
|
+
return walletId;
|
|
1911
|
+
}
|
|
1912
|
+
/**
|
|
1913
|
+
* The approved destination saved for this (address, tag) pair, or null. Matched on the pair
|
|
1914
|
+
* itself rather than an id on the transaction, because a withdrawal is requested by address
|
|
1915
|
+
* and may name one the player never saved. An absent tag matches only a row saved without
|
|
1916
|
+
* one: a tagged payout against an untagged whitelist row is a different beneficiary.
|
|
1917
|
+
*/
|
|
1918
|
+
async whitelistedWalletId(userId, currency, network, address, destinationTag) {
|
|
1919
|
+
if (!this.payment.whitelistWithdrawalAddress || !address) {
|
|
1920
|
+
return null;
|
|
1921
|
+
}
|
|
1922
|
+
const providerName = await this.providerNameFor(currency, network);
|
|
1923
|
+
const [row] = await this.drizzle.db
|
|
1924
|
+
.select({
|
|
1925
|
+
id: walletWithdrawalAddress.id,
|
|
1926
|
+
network: walletWithdrawalAddress.network,
|
|
1927
|
+
destinationTag: walletWithdrawalAddress.destinationTag,
|
|
1928
|
+
providerName: walletWithdrawalAddress.providerName,
|
|
1929
|
+
providerWalletId: walletWithdrawalAddress.providerWalletId,
|
|
1930
|
+
})
|
|
1931
|
+
.from(walletWithdrawalAddress)
|
|
1932
|
+
.where(and(eq(walletWithdrawalAddress.userId, userId), eq(walletWithdrawalAddress.currency, currency), eq(walletWithdrawalAddress.address, address), destinationTag
|
|
1933
|
+
? eq(walletWithdrawalAddress.destinationTag, destinationTag)
|
|
1934
|
+
: isNull(walletWithdrawalAddress.destinationTag), ...(network ? [eq(walletWithdrawalAddress.network, network)] : [])))
|
|
1935
|
+
.limit(1);
|
|
1936
|
+
if (!row) {
|
|
1937
|
+
return null;
|
|
1938
|
+
}
|
|
1939
|
+
// An id minted by a different provider names nothing in the current one, and a row
|
|
1940
|
+
// saved while no whitelisting adapter was bound has no id at all. Both re-register
|
|
1941
|
+
// with the provider that will actually settle, rather than failing a payout on a
|
|
1942
|
+
// saved address the player cannot fix themselves.
|
|
1943
|
+
if (row.providerWalletId && row.providerName === providerName) {
|
|
1944
|
+
return row.providerWalletId;
|
|
1945
|
+
}
|
|
1946
|
+
const { providerWalletId } = await this.payment.whitelistWithdrawalAddress({
|
|
1947
|
+
userId,
|
|
1948
|
+
currency,
|
|
1949
|
+
network: row.network,
|
|
1950
|
+
address,
|
|
1951
|
+
...(row.destinationTag ? { destinationTag: row.destinationTag } : {}),
|
|
1952
|
+
});
|
|
1953
|
+
await this.drizzle.db
|
|
1954
|
+
.update(walletWithdrawalAddress)
|
|
1955
|
+
.set({ providerName, providerWalletId })
|
|
1956
|
+
.where(eq(walletWithdrawalAddress.id, row.id));
|
|
1957
|
+
return providerWalletId;
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Delegates to the bound payment adapter when it whitelists destinations, and returns nothing
|
|
1961
|
+
* to store when it does not. A vendor failure propagates rather than being swallowed: saving
|
|
1962
|
+
* the address anyway would produce a row that looks usable and fails only once the player has
|
|
1963
|
+
* committed to a payout.
|
|
1964
|
+
*/
|
|
1965
|
+
async whitelistWithdrawalAddress(userId, input) {
|
|
1966
|
+
if (!this.payment.whitelistWithdrawalAddress) {
|
|
1967
|
+
return {};
|
|
1968
|
+
}
|
|
1969
|
+
const { providerWalletId } = await this.payment.whitelistWithdrawalAddress({
|
|
1970
|
+
userId,
|
|
1971
|
+
currency: input.currency,
|
|
1972
|
+
network: input.network,
|
|
1973
|
+
address: input.address,
|
|
1974
|
+
...(input.destinationTag ? { destinationTag: input.destinationTag } : {}),
|
|
1975
|
+
});
|
|
1976
|
+
return {
|
|
1977
|
+
providerName: await this.providerNameFor(input.currency, input.network),
|
|
1978
|
+
providerWalletId,
|
|
1979
|
+
};
|
|
1980
|
+
}
|
|
1981
|
+
/** False when the row does not exist OR belongs to someone else - the caller cannot
|
|
1982
|
+
* tell the two apart, which is what stops the id space being probed. */
|
|
1983
|
+
async deleteWithdrawalAddress(userId, id, meta) {
|
|
1984
|
+
await this.rateLimit(userId);
|
|
1985
|
+
const [row] = await this.drizzle.db
|
|
1986
|
+
.delete(walletWithdrawalAddress)
|
|
1987
|
+
.where(and(eq(walletWithdrawalAddress.id, id), eq(walletWithdrawalAddress.userId, userId)))
|
|
1988
|
+
.returning();
|
|
1989
|
+
if (!row) {
|
|
1990
|
+
return false;
|
|
1991
|
+
}
|
|
1992
|
+
await this.audit.record({
|
|
1993
|
+
actorId: userId,
|
|
1994
|
+
actorType: 'player',
|
|
1995
|
+
action: 'wallet.withdrawal_address.deleted',
|
|
1996
|
+
resourceType: 'wallet_withdrawal_address',
|
|
1997
|
+
resourceId: row.id,
|
|
1998
|
+
before: { label: row.label, currency: row.currency, network: row.network },
|
|
1999
|
+
...meta,
|
|
2000
|
+
});
|
|
2001
|
+
return true;
|
|
2002
|
+
}
|
|
799
2003
|
}
|
|
800
2004
|
//# sourceMappingURL=wallet.service.js.map
|