payment-kit 1.29.1 → 1.29.3

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.
Files changed (343) hide show
  1. package/api/dev.ts +41 -2
  2. package/api/hono.d.ts +42 -0
  3. package/api/node-sqlite.d.ts +12 -0
  4. package/api/src/bootstrap.ts +47 -0
  5. package/api/src/crons/base.ts +3 -3
  6. package/api/src/crons/currency.ts +1 -1
  7. package/api/src/crons/index.ts +41 -37
  8. package/api/src/crons/metering-subscription-detection.ts +1 -1
  9. package/api/src/crons/overdue-detection.ts +2 -2
  10. package/api/src/crons/retry-pending-events.ts +6 -0
  11. package/api/src/crons/tenant-fanout.ts +82 -0
  12. package/api/src/host-node/did-connect-runtime-node.ts +33 -0
  13. package/api/src/host-node/serve-static-arc.ts +68 -0
  14. package/api/src/host-node/serve-static.ts +41 -0
  15. package/api/src/index.ts +22 -161
  16. package/api/src/integrations/app-store/client.ts +3 -4
  17. package/api/src/integrations/app-store/handlers/subscription.ts +7 -7
  18. package/api/src/integrations/app-store/signed-data-verifier.ts +3 -2
  19. package/api/src/integrations/arcblock/token.ts +21 -7
  20. package/api/src/integrations/google-play/handlers/subscription.ts +6 -6
  21. package/api/src/integrations/google-play/handlers/voided.ts +2 -2
  22. package/api/src/integrations/google-play/verify.ts +3 -2
  23. package/api/src/integrations/iap-reconcile.ts +3 -5
  24. package/api/src/integrations/stripe/handlers/invoice.ts +2 -2
  25. package/api/src/integrations/stripe/handlers/subscription.ts +3 -3
  26. package/api/src/libs/archive/query.ts +19 -0
  27. package/api/src/libs/audit.ts +61 -4
  28. package/api/src/libs/auth.ts +247 -47
  29. package/api/src/libs/context.ts +89 -1
  30. package/api/src/libs/currency.ts +2 -2
  31. package/api/src/libs/dayjs.ts +8 -2
  32. package/api/src/libs/did-connect/runtime-did-connect-js.ts +88 -0
  33. package/api/src/libs/did-connect/tenant-identity.ts +221 -0
  34. package/api/src/libs/drivers/auth-storage.ts +118 -0
  35. package/api/src/libs/drivers/cron.ts +264 -0
  36. package/api/src/libs/drivers/db.ts +170 -0
  37. package/api/src/libs/drivers/identity.ts +142 -0
  38. package/api/src/libs/drivers/index.ts +40 -0
  39. package/api/src/libs/drivers/locks.ts +226 -0
  40. package/api/src/libs/drivers/migrate-runner.ts +70 -0
  41. package/api/src/libs/drivers/queue.ts +104 -0
  42. package/api/src/libs/drivers/secrets.ts +194 -0
  43. package/api/src/libs/env.ts +170 -54
  44. package/api/src/libs/exchange-rate/service.ts +7 -6
  45. package/api/src/libs/http-fetch-adapter.ts +60 -0
  46. package/api/src/libs/invoice.ts +1 -1
  47. package/api/src/libs/lock.ts +51 -47
  48. package/api/src/libs/logger.ts +48 -8
  49. package/api/src/libs/notification/index.ts +1 -1
  50. package/api/src/libs/notification/template/customer-credit-low-balance.ts +2 -1
  51. package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -1
  52. package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -1
  53. package/api/src/libs/overdraft-protection.ts +1 -1
  54. package/api/src/libs/payout.ts +1 -1
  55. package/api/src/libs/queue/index.ts +271 -52
  56. package/api/src/libs/queue/runtime.ts +175 -0
  57. package/api/src/libs/resource.ts +3 -3
  58. package/api/src/libs/secrets.ts +38 -0
  59. package/api/src/libs/session.ts +3 -2
  60. package/api/src/libs/subscription.ts +5 -5
  61. package/api/src/libs/tenant.ts +92 -0
  62. package/api/src/libs/url.ts +3 -3
  63. package/api/src/libs/util.ts +21 -13
  64. package/api/src/middlewares/hono/cdn.ts +63 -0
  65. package/api/src/middlewares/hono/context.ts +80 -0
  66. package/api/src/middlewares/hono/csrf.ts +83 -0
  67. package/api/src/middlewares/hono/fallback.ts +194 -0
  68. package/api/src/middlewares/hono/pipeline.ts +73 -0
  69. package/api/src/middlewares/hono/resource-mount.ts +42 -0
  70. package/api/src/middlewares/hono/resource.ts +63 -0
  71. package/api/src/middlewares/hono/security.ts +209 -0
  72. package/api/src/middlewares/hono/session.ts +114 -0
  73. package/api/src/middlewares/hono/xss.ts +61 -0
  74. package/api/src/queues/auto-recharge.ts +12 -10
  75. package/api/src/queues/checkout-session.ts +38 -21
  76. package/api/src/queues/credit-consume.ts +40 -36
  77. package/api/src/queues/credit-grant.ts +25 -18
  78. package/api/src/queues/credit-reconciliation.ts +7 -5
  79. package/api/src/queues/discount-status.ts +9 -6
  80. package/api/src/queues/event.ts +41 -11
  81. package/api/src/queues/exchange-rate-health.ts +49 -30
  82. package/api/src/queues/invoice.ts +18 -15
  83. package/api/src/queues/notification.ts +14 -7
  84. package/api/src/queues/payment.ts +64 -37
  85. package/api/src/queues/payout.ts +37 -21
  86. package/api/src/queues/refund.ts +36 -18
  87. package/api/src/queues/subscription.ts +83 -53
  88. package/api/src/queues/token-transfer.ts +15 -10
  89. package/api/src/queues/usage-record.ts +8 -5
  90. package/api/src/queues/vendors/commission.ts +7 -5
  91. package/api/src/queues/vendors/fulfillment-coordinator.ts +17 -13
  92. package/api/src/queues/vendors/fulfillment.ts +4 -2
  93. package/api/src/queues/vendors/return-processor.ts +5 -3
  94. package/api/src/queues/vendors/return-scanner.ts +5 -4
  95. package/api/src/queues/vendors/status-check.ts +10 -7
  96. package/api/src/queues/webhook.ts +60 -32
  97. package/api/src/routes/connect/shared.ts +1 -2
  98. package/api/src/routes/connect/subscribe.ts +3 -3
  99. package/api/src/routes/{archive.ts → hono/archive.ts} +69 -64
  100. package/api/src/routes/{auto-recharge-configs.ts → hono/auto-recharge-configs.ts} +39 -28
  101. package/api/src/routes/{checkout-sessions.ts → hono/checkout-sessions.ts} +790 -923
  102. package/api/src/routes/{coupons.ts → hono/coupons.ts} +93 -76
  103. package/api/src/routes/{credit-grants.ts → hono/credit-grants.ts} +140 -126
  104. package/api/src/routes/hono/credit-tokens.ts +43 -0
  105. package/api/src/routes/{credit-transactions.ts → hono/credit-transactions.ts} +37 -29
  106. package/api/src/routes/{customers.ts → hono/customers.ts} +199 -224
  107. package/api/src/routes/{donations.ts → hono/donations.ts} +41 -32
  108. package/api/src/routes/{entitlements.ts → hono/entitlements.ts} +28 -25
  109. package/api/src/routes/{events.ts → hono/events.ts} +107 -71
  110. package/api/src/routes/{exchange-rate-providers.ts → hono/exchange-rate-providers.ts} +138 -126
  111. package/api/src/routes/hono/exchange-rates.ts +77 -0
  112. package/api/src/routes/hono/index.ts +115 -0
  113. package/api/src/routes/{integrations → hono/integrations}/app-store.ts +68 -48
  114. package/api/src/routes/{integrations → hono/integrations}/google-play.ts +78 -58
  115. package/api/src/routes/hono/integrations/stripe.ts +74 -0
  116. package/api/src/routes/{invoices.ts → hono/invoices.ts} +253 -244
  117. package/api/src/routes/{meter-events.ts → hono/meter-events.ts} +120 -110
  118. package/api/src/routes/hono/meters.ts +288 -0
  119. package/api/src/routes/hono/passports.ts +73 -0
  120. package/api/src/routes/{payment-currencies.ts → hono/payment-currencies.ts} +219 -197
  121. package/api/src/routes/{payment-intents.ts → hono/payment-intents.ts} +136 -132
  122. package/api/src/routes/{payment-links.ts → hono/payment-links.ts} +145 -128
  123. package/api/src/routes/{payment-methods.ts → hono/payment-methods.ts} +125 -93
  124. package/api/src/routes/{payment-stats.ts → hono/payment-stats.ts} +30 -25
  125. package/api/src/routes/{payouts.ts → hono/payouts.ts} +55 -47
  126. package/api/src/routes/{prices.ts → hono/prices.ts} +265 -242
  127. package/api/src/routes/{pricing-table.ts → hono/pricing-table.ts} +94 -87
  128. package/api/src/routes/{products.ts → hono/products.ts} +172 -159
  129. package/api/src/routes/{promotion-codes.ts → hono/promotion-codes.ts} +207 -185
  130. package/api/src/routes/hono/redirect.ts +24 -0
  131. package/api/src/routes/{refunds.ts → hono/refunds.ts} +98 -83
  132. package/api/src/routes/{settings.ts → hono/settings.ts} +64 -55
  133. package/api/src/routes/{subscription-items.ts → hono/subscription-items.ts} +64 -57
  134. package/api/src/routes/{subscriptions.ts → hono/subscriptions.ts} +475 -528
  135. package/api/src/routes/{tax-rates.ts → hono/tax-rates.ts} +71 -70
  136. package/api/src/routes/hono/tool.ts +69 -0
  137. package/api/src/routes/{usage-records.ts → hono/usage-records.ts} +47 -42
  138. package/api/src/routes/{vendor.ts → hono/vendor.ts} +315 -167
  139. package/api/src/routes/{webhook-attempts.ts → hono/webhook-attempts.ts} +17 -13
  140. package/api/src/routes/hono/webhook-endpoints.ts +126 -0
  141. package/api/src/service.ts +814 -0
  142. package/api/src/store/migrations/20230911-seeding.ts +2 -1
  143. package/api/src/store/migrations/20260609-remove-did-space-jobs.ts +23 -0
  144. package/api/src/store/migrations/20260610-tenant-columns.ts +40 -0
  145. package/api/src/store/migrations/20260611-tenant-backfill.ts +33 -0
  146. package/api/src/store/models/auto-recharge-config.ts +22 -10
  147. package/api/src/store/models/checkout-session.ts +15 -14
  148. package/api/src/store/models/coupon.ts +29 -20
  149. package/api/src/store/models/credit-grant.ts +38 -29
  150. package/api/src/store/models/credit-transaction.ts +32 -21
  151. package/api/src/store/models/customer.ts +19 -17
  152. package/api/src/store/models/discount.ts +11 -2
  153. package/api/src/store/models/entitlement-grant.ts +21 -9
  154. package/api/src/store/models/entitlement-product.ts +21 -9
  155. package/api/src/store/models/entitlement.ts +19 -10
  156. package/api/src/store/models/event.ts +18 -9
  157. package/api/src/store/models/exchange-rate-provider.ts +17 -4
  158. package/api/src/store/models/invoice-item.ts +18 -9
  159. package/api/src/store/models/invoice.ts +16 -8
  160. package/api/src/store/models/meter-event.ts +27 -9
  161. package/api/src/store/models/meter.ts +31 -22
  162. package/api/src/store/models/payment-currency.ts +25 -8
  163. package/api/src/store/models/payment-intent.ts +15 -6
  164. package/api/src/store/models/payment-link.ts +15 -6
  165. package/api/src/store/models/payment-method.ts +38 -22
  166. package/api/src/store/models/payment-stat.ts +18 -9
  167. package/api/src/store/models/payout.ts +15 -6
  168. package/api/src/store/models/price-quote.ts +17 -8
  169. package/api/src/store/models/price.ts +24 -12
  170. package/api/src/store/models/pricing-table.ts +29 -20
  171. package/api/src/store/models/product-vendor.ts +20 -10
  172. package/api/src/store/models/product.ts +15 -6
  173. package/api/src/store/models/promotion-code.ts +14 -6
  174. package/api/src/store/models/refund.ts +15 -6
  175. package/api/src/store/models/revenue-snapshot.ts +21 -9
  176. package/api/src/store/models/setting.ts +18 -9
  177. package/api/src/store/models/setup-intent.ts +36 -27
  178. package/api/src/store/models/subscription-item.ts +21 -9
  179. package/api/src/store/models/subscription-schedule.ts +21 -9
  180. package/api/src/store/models/subscription.ts +21 -10
  181. package/api/src/store/models/tax-rate.ts +29 -21
  182. package/api/src/store/models/usage-record.ts +11 -2
  183. package/api/src/store/models/webhook-attempt.ts +18 -9
  184. package/api/src/store/models/webhook-endpoint.ts +18 -9
  185. package/api/src/store/scoped-core.ts +55 -0
  186. package/api/src/store/scoped.ts +247 -0
  187. package/api/src/store/sequelize.ts +82 -23
  188. package/api/src/store/sql-migrations.ts +20 -0
  189. package/api/src/store/tenant-backfill.ts +260 -0
  190. package/api/src/store/tenant-model.ts +124 -0
  191. package/api/src/store/tenant-tables.ts +50 -0
  192. package/api/tests/bootstrap/bootstrap.spec.ts +162 -0
  193. package/api/tests/crons/tenant-fanout.spec.ts +158 -0
  194. package/api/tests/embedded/embedded-multi-mode-d3.spec.ts +257 -0
  195. package/api/tests/fixtures/bare-query-violation.ts +13 -0
  196. package/api/tests/fixtures/core-env-violation.ts +10 -0
  197. package/api/tests/fixtures/host-read-violation.ts +19 -0
  198. package/api/tests/fixtures/tenants.ts +4 -0
  199. package/api/tests/integrations/iap-tenant.spec.ts +284 -0
  200. package/api/tests/libs/archive-query.spec.ts +26 -0
  201. package/api/tests/libs/audit-tenant.spec.ts +153 -0
  202. package/api/tests/libs/context.spec.ts +204 -0
  203. package/api/tests/libs/core-config.spec.ts +115 -0
  204. package/api/tests/libs/cron-driver-d2.spec.ts +237 -0
  205. package/api/tests/libs/crons-conservation-d2.spec.ts +52 -0
  206. package/api/tests/libs/did-connect-runtime-js.spec.ts +98 -0
  207. package/api/tests/libs/did-connect-tenant-identity.spec.ts +159 -0
  208. package/api/tests/libs/lock-tenant.spec.ts +66 -0
  209. package/api/tests/libs/scoped.spec.ts +222 -0
  210. package/api/tests/libs/secrets-facade.spec.ts +52 -0
  211. package/api/tests/libs/service-host.spec.ts +37 -0
  212. package/api/tests/libs/tenancy-slot-authority.spec.ts +209 -0
  213. package/api/tests/libs/tenant-middleware.spec.ts +42 -0
  214. package/api/tests/libs/tenant-scanner.spec.ts +120 -0
  215. package/api/tests/middlewares/hono/cdn.spec.ts +70 -0
  216. package/api/tests/middlewares/hono/context.spec.ts +113 -0
  217. package/api/tests/middlewares/hono/csrf.spec.ts +136 -0
  218. package/api/tests/middlewares/hono/fallback.spec.ts +67 -0
  219. package/api/tests/middlewares/hono/pipeline.spec.ts +47 -0
  220. package/api/tests/middlewares/hono/security.spec.ts +181 -0
  221. package/api/tests/middlewares/hono/session.spec.ts +42 -0
  222. package/api/tests/middlewares/hono/xss.spec.ts +81 -0
  223. package/api/tests/models/tenant-backfill.spec.ts +287 -0
  224. package/api/tests/models/tenant-columns-model.spec.ts +46 -0
  225. package/api/tests/models/tenant-columns.spec.ts +161 -0
  226. package/api/tests/queues/credit-consume-batch.spec.ts +8 -1
  227. package/api/tests/queues/credit-consume.spec.ts +8 -1
  228. package/api/tests/queues/event-tenant.spec.ts +292 -0
  229. package/api/tests/queues/exchange-rate-health-tenant-d6.spec.ts +62 -0
  230. package/api/tests/queues/queue-parity.spec.ts +249 -0
  231. package/api/tests/queues/queue-runtime-surface.spec.ts +277 -0
  232. package/api/tests/queues/queue-teardown-d2.spec.ts +127 -0
  233. package/api/tests/queues/tenant-matrix-a.spec.ts +245 -0
  234. package/api/tests/queues/tenant-matrix-b.spec.ts +168 -0
  235. package/api/tests/routes/connect/hono-attach.spec.ts +107 -0
  236. package/api/tests/service/collapse.spec.ts +96 -0
  237. package/api/tests/service/didconnect-storage-slot.spec.ts +60 -0
  238. package/api/tests/service/fail-closed-http.spec.ts +79 -0
  239. package/api/tests/service/static-arc-handler.spec.ts +101 -0
  240. package/api/tests/service/static-externalized.spec.ts +48 -0
  241. package/api/tests/store/tenant-crosscut.spec.ts +202 -0
  242. package/api/tests/store/tenant-model-spike.spec.ts +177 -0
  243. package/api/tests/store/tenant-model.spec.ts +162 -0
  244. package/api/tests/store/tenant-residual.spec.ts +196 -0
  245. package/api/third.d.ts +4 -0
  246. package/blocklet.yml +1 -1
  247. package/cloudflare/MIGRATION-RUNBOOK.md +3 -8
  248. package/cloudflare/README.md +34 -27
  249. package/cloudflare/STAGING-MIGRATION-GUIDE.md +3 -15
  250. package/cloudflare/build.ts +33 -13
  251. package/cloudflare/cf-adapter.ts +419 -0
  252. package/cloudflare/did-connect-runtime.ts +96 -0
  253. package/cloudflare/did-connect-token-storage.ts +151 -0
  254. package/cloudflare/esbuild-cf-config.cjs +407 -0
  255. package/cloudflare/migrations/0006_tenant_columns.sql +46 -0
  256. package/cloudflare/migrations/0007_tenant_backfill_indexes.sql +65 -0
  257. package/cloudflare/migrations/0008_schema_parity.sql +16 -0
  258. package/cloudflare/migrations/0009_remove_did_space_jobs.sql +5 -0
  259. package/cloudflare/queue-runtime-mode.ts +13 -0
  260. package/cloudflare/run-build.js +33 -403
  261. package/cloudflare/scripts/cf-package-import-probe.mjs +90 -0
  262. package/cloudflare/scripts/didconnect-mock-smoke.mjs +140 -0
  263. package/cloudflare/shims/blocklet-sdk/asset-host-transformer.ts +20 -0
  264. package/cloudflare/shims/blocklet-sdk/config.ts +8 -1
  265. package/cloudflare/shims/blocklet-sdk/login.ts +12 -0
  266. package/cloudflare/shims/blocklet-sdk/service-api.ts +14 -0
  267. package/cloudflare/shims/blocklet-sdk/session.ts +4 -2
  268. package/cloudflare/shims/blocklet-sdk/util-constants.ts +8 -0
  269. package/cloudflare/shims/blocklet-sdk/wallet-authenticator.ts +16 -1
  270. package/cloudflare/shims/blocklet-sdk/wallet-handler.ts +18 -3
  271. package/cloudflare/shims/cron.ts +38 -158
  272. package/cloudflare/shims/events.ts +124 -0
  273. package/cloudflare/shims/fastq.ts +15 -1
  274. package/cloudflare/shims/nedb-storage.ts +16 -8
  275. package/cloudflare/shims/xss.ts +8 -0
  276. package/cloudflare/tenant-middleware.ts +36 -0
  277. package/cloudflare/tests/cf-adapter.spec.ts +244 -0
  278. package/cloudflare/tests/did-connect-token-storage.spec.ts +105 -0
  279. package/cloudflare/tests/tenant-middleware.spec.ts +160 -0
  280. package/cloudflare/tests/worker-handler-gate.spec.ts +69 -0
  281. package/cloudflare/vite.config.ts +53 -45
  282. package/cloudflare/worker.ts +261 -448
  283. package/cloudflare/wrangler.json +0 -6
  284. package/cloudflare/wrangler.jsonc +0 -6
  285. package/cloudflare/wrangler.local-e2e.jsonc +25 -0
  286. package/cloudflare/wrangler.staging.json +0 -6
  287. package/jest.config.js +3 -1
  288. package/package.json +33 -38
  289. package/scripts/bootstrap-inject.ts +166 -0
  290. package/scripts/core-env-whitelist.json +1 -0
  291. package/scripts/e2e-12b-runtime.ts +149 -0
  292. package/scripts/e2e-core-config.ts +125 -0
  293. package/scripts/e2e-d1-tenancy.ts +116 -0
  294. package/scripts/e2e-d2-cron-queue.ts +139 -0
  295. package/scripts/e2e-d3-embedded-multi.ts +171 -0
  296. package/scripts/e2e-hono-s2.ts +125 -0
  297. package/scripts/e2e-hono-s3e.ts +135 -0
  298. package/scripts/e2e-hono-s4.ts +114 -0
  299. package/scripts/e2e-migration-contract.ts +100 -0
  300. package/scripts/e2e-s0.ts +61 -0
  301. package/scripts/e2e-s1.ts +107 -0
  302. package/scripts/e2e-s2.ts +178 -0
  303. package/scripts/e2e-s3.ts +110 -0
  304. package/scripts/e2e-s4.ts +191 -0
  305. package/scripts/e2e-s5.ts +139 -0
  306. package/scripts/e2e-s6.ts +127 -0
  307. package/scripts/e2e-tenant-model.ts +119 -0
  308. package/scripts/e2e-tenant-worker.ts +199 -0
  309. package/scripts/gen-sql-migrations.js +46 -0
  310. package/scripts/phase8-codemod.js +219 -0
  311. package/scripts/phase9a-env-getters-codemod.js +82 -0
  312. package/scripts/scan-core-env.js +109 -0
  313. package/scripts/scan-tenant-queries.js +235 -0
  314. package/scripts/schema-drift-guard.ts +210 -0
  315. package/scripts/tenant-scan-whitelist.json +1 -0
  316. package/src/app.tsx +2 -1
  317. package/src/env.d.ts +13 -1
  318. package/src/libs/service-host.ts +13 -0
  319. package/tsconfig.json +1 -1
  320. package/vite.arc.config.ts +159 -0
  321. package/api/src/libs/did-space.ts +0 -235
  322. package/api/src/libs/middleware.ts +0 -50
  323. package/api/src/libs/security.ts +0 -192
  324. package/api/src/queues/space.ts +0 -662
  325. package/api/src/routes/credit-tokens.ts +0 -38
  326. package/api/src/routes/exchange-rates.ts +0 -87
  327. package/api/src/routes/index.ts +0 -142
  328. package/api/src/routes/integrations/stripe.ts +0 -61
  329. package/api/src/routes/meters.ts +0 -274
  330. package/api/src/routes/passports.ts +0 -68
  331. package/api/src/routes/redirect.ts +0 -20
  332. package/api/src/routes/tool.ts +0 -65
  333. package/api/src/routes/webhook-endpoints.ts +0 -126
  334. package/api/tests/routes/credit-grants.spec.ts +0 -1261
  335. package/cloudflare/did-connect-auth.ts +0 -527
  336. package/cloudflare/shims/did-space-js.ts +0 -17
  337. package/cloudflare/shims/did-space.ts +0 -11
  338. package/cloudflare/shims/express-compat/index.ts +0 -80
  339. package/cloudflare/shims/express-compat/types.ts +0 -41
  340. package/cloudflare/shims/lock.ts +0 -115
  341. package/cloudflare/shims/queue.ts +0 -611
  342. package/cloudflare/tests/shims/queue-delayed-persist.spec.ts +0 -87
  343. package/cloudflare/tests/shims/queue-scheduled.spec.ts +0 -186
@@ -1,23 +1,27 @@
1
+ // Phase 3 (express→hono) — hono fork of routes/payment-methods.ts. Sub-app with
2
+ // routes relative to /api/payment-methods (mounted via mountResourceGroup). The
3
+ // business logic is unchanged; only the express plumbing becomes hono:
4
+ // req.body → c.get('sanitizedBody'); res.status(n).json(x) → c.json(x, n).
1
5
  import { getUrl } from '@blocklet/sdk/lib/component';
2
6
  import { fromTokenToUnit } from '@ocap/util';
3
7
  import { ethers } from 'ethers';
4
- import { Router } from 'express';
8
+ import { Hono } from 'hono';
5
9
  import pick from 'lodash/pick';
6
10
  import { InferAttributes, Op, WhereOptions } from 'sequelize';
7
11
  import cloneDeep from 'lodash/cloneDeep';
8
12
  import merge from 'lodash/merge';
9
13
  import Joi from 'joi';
10
- import { ensureWebhookRegistered, cleanupStripeWebhook, validateStripeKeys } from '../integrations/stripe/setup';
11
- import logger from '../libs/logger';
12
- import { authenticate } from '../libs/security';
13
- import { PaymentCurrency } from '../store/models/payment-currency';
14
- import { PaymentMethod, TPaymentMethod } from '../store/models/payment-method';
15
- import type { EVMChainType, PaymentMethodSettings } from '../store/models/types';
16
- import { ethWallet, wallet } from '../libs/auth';
17
- import { EVM_CHAIN_TYPES } from '../libs/constants';
18
- import { getTokenSummaryByDid } from '../integrations/arcblock/stake';
19
-
20
- const router = Router();
14
+ import { ensureWebhookRegistered, cleanupStripeWebhook, validateStripeKeys } from '../../integrations/stripe/setup';
15
+ import logger from '../../libs/logger';
16
+ import { authenticate } from '../../middlewares/hono/security';
17
+ import { PaymentCurrency } from '../../store/models/payment-currency';
18
+ import { PaymentMethod, TPaymentMethod } from '../../store/models/payment-method';
19
+ import type { EVMChainType, PaymentMethodSettings } from '../../store/models/types';
20
+ import { ethWallet, wallet } from '../../libs/auth';
21
+ import { EVM_CHAIN_TYPES } from '../../libs/constants';
22
+ import { getTokenSummaryByDid } from '../../integrations/arcblock/stake';
23
+
24
+ const app = new Hono();
21
25
 
22
26
  const auth = authenticate<PaymentMethod>({ component: true, roles: ['owner', 'admin'] });
23
27
 
@@ -26,43 +30,44 @@ const paymentMethodCreateSchema = Joi.object({
26
30
  description: Joi.string().max(255).required(),
27
31
  }).unknown(true);
28
32
 
29
- router.post('/', auth, async (req, res) => {
30
- const raw: Partial<TPaymentMethod> = req.body;
33
+ app.post('/', auth, async (c) => {
34
+ const body = c.get('sanitizedBody') ?? {};
35
+ const raw: Partial<TPaymentMethod> = body;
31
36
 
32
- raw.livemode = req.livemode;
37
+ raw.livemode = c.get('livemode');
33
38
  raw.locked = false;
34
39
  raw.active = true;
35
- const { error } = paymentMethodCreateSchema.validate(pick(req.body, ['name', 'description']));
40
+ const { error } = paymentMethodCreateSchema.validate(pick(body, ['name', 'description']));
36
41
  if (error) {
37
- return res.status(400).json({ error: error.message });
42
+ return c.json({ error: error.message }, 400);
38
43
  }
39
44
 
40
45
  if (!raw.name) {
41
- return res.status(400).json({ error: 'payment method name is required' });
46
+ return c.json({ error: 'payment method name is required' }, 400);
42
47
  }
43
48
  if (!raw.description) {
44
- return res.status(400).json({ error: 'payment method description is required' });
49
+ return c.json({ error: 'payment method description is required' }, 400);
45
50
  }
46
51
 
47
52
  if (!raw.settings) {
48
- return res.status(400).json({ error: 'payment method settings is required' });
53
+ return c.json({ error: 'payment method settings is required' }, 400);
49
54
  }
50
55
 
51
56
  if (raw.type === 'stripe') {
52
57
  const exist = await PaymentMethod.findOne({ where: { type: 'stripe', livemode: raw.livemode } });
53
58
  if (exist) {
54
- return res.status(400).json({ error: 'stripe payment method already exist' });
59
+ return c.json({ error: 'stripe payment method already exist' }, 400);
55
60
  }
56
61
 
57
62
  if (!raw.settings.stripe?.publishable_key) {
58
- return res.status(400).json({ error: 'stripe publishable key is required' });
63
+ return c.json({ error: 'stripe publishable key is required' }, 400);
59
64
  }
60
65
  if (!raw.settings.stripe?.secret_key) {
61
- return res.status(400).json({ error: 'stripe secret key is required' });
66
+ return c.json({ error: 'stripe secret key is required' }, 400);
62
67
  }
63
68
  const isValid = await validateStripeKeys(raw.settings.stripe.secret_key);
64
69
  if (!isValid) {
65
- return res.status(400).json({ error: 'Invalid Stripe API keys' });
70
+ return c.json({ error: 'Invalid Stripe API keys' }, 400);
66
71
  }
67
72
 
68
73
  raw.settings = pick(PaymentMethod.encryptSettings(raw.settings), ['stripe']) as PaymentMethodSettings;
@@ -106,19 +111,19 @@ router.post('/', auth, async (req, res) => {
106
111
 
107
112
  ensureWebhookRegistered().catch(console.error);
108
113
 
109
- return res.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
114
+ return c.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
110
115
  }
111
116
 
112
117
  if (EVM_CHAIN_TYPES.includes(raw.type as string)) {
113
118
  const paymentType = raw.type as EVMChainType;
114
119
  if (!raw.settings[paymentType]?.api_host) {
115
- return res.status(400).json({ error: `${paymentType} api_host is required` });
120
+ return c.json({ error: `${paymentType} api_host is required` }, 400);
116
121
  }
117
122
  if (!raw.settings[paymentType]?.explorer_host) {
118
- return res.status(400).json({ error: `${paymentType} explorer_host is required` });
123
+ return c.json({ error: `${paymentType} explorer_host is required` }, 400);
119
124
  }
120
125
  if (!raw.settings[paymentType]?.native_symbol) {
121
- return res.status(400).json({ error: `${paymentType} native_symbol is required` });
126
+ return c.json({ error: `${paymentType} native_symbol is required` }, 400);
122
127
  }
123
128
 
124
129
  try {
@@ -132,14 +137,14 @@ router.post('/', auth, async (req, res) => {
132
137
  });
133
138
  } catch (err) {
134
139
  logger.error(`verify ${paymentType} api endpoint failed`, err);
135
- return res.status(400).json({ error: err.message });
140
+ return c.json({ error: (err as any).message }, 400);
136
141
  }
137
142
 
138
143
  const exist = await PaymentMethod.findOne({
139
144
  where: { type: paymentType, [`settings.${paymentType}.chain_id`]: raw.settings[paymentType]?.chain_id },
140
145
  });
141
146
  if (exist) {
142
- return res.status(400).json({ error: `${paymentType} payment method already exist` });
147
+ return c.json({ error: `${paymentType} payment method already exist` }, 400);
143
148
  }
144
149
 
145
150
  raw.settings = pick(PaymentMethod.encryptSettings(raw.settings), [paymentType]) as PaymentMethodSettings;
@@ -180,30 +185,40 @@ router.post('/', auth, async (req, res) => {
180
185
  metadata: {},
181
186
  });
182
187
  await method.update({ default_currency_id: currency.id });
183
- return res.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
188
+ return c.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
184
189
  }
185
190
 
186
191
  if (raw.type === 'google_play') {
187
192
  if (!raw.settings.google_play?.package_name) {
188
- return res.status(400).json({ error: 'google_play package_name is required' });
193
+ return c.json({ error: 'google_play package_name is required' }, 400);
189
194
  }
190
195
  if (!raw.settings.google_play?.service_account_json) {
191
- return res.status(400).json({ error: 'google_play service_account_json is required' });
196
+ return c.json({ error: 'google_play service_account_json is required' }, 400);
192
197
  }
193
198
  try {
194
199
  const parsed = JSON.parse(raw.settings.google_play.service_account_json);
195
200
  if (!parsed.client_email || !parsed.private_key) {
196
- return res.status(400).json({ error: 'service_account_json missing client_email or private_key' });
201
+ return c.json({ error: 'service_account_json missing client_email or private_key' }, 400);
197
202
  }
198
203
  } catch {
199
- return res.status(400).json({ error: 'service_account_json is not valid JSON' });
204
+ return c.json({ error: 'service_account_json is not valid JSON' }, 400);
200
205
  }
201
206
 
202
- const exist = await PaymentMethod.findOne({
203
- where: { type: 'google_play', livemode: raw.livemode },
207
+ // Phase 6 (W1-4b): a channel identifier (package_name) must be unique
208
+ // across the WHOLE deployment regardless of tenant — the S2S webhook
209
+ // reverse-maps package_name -> tenant and ambiguity would misroute
210
+ // notifications. Per-tenant duplicates of the same identifier are
211
+ // therefore refused at registration time.
212
+ const sameType = await PaymentMethod.findAll({ where: { type: 'google_play', livemode: raw.livemode } });
213
+ const identifierTaken = sameType.some((m) => {
214
+ const settings = PaymentMethod.decryptSettings(m.settings);
215
+ return settings.google_play?.package_name === raw.settings?.google_play?.package_name;
204
216
  });
205
- if (exist) {
206
- return res.status(400).json({ error: 'google_play payment method already exists for this livemode' });
217
+ if (identifierTaken) {
218
+ return c.json(
219
+ { error: 'this package_name is already registered in this deployment', code: 'CHANNEL_ID_TAKEN' },
220
+ 400
221
+ );
207
222
  }
208
223
 
209
224
  raw.settings = pick(PaymentMethod.encryptSettings(raw.settings), ['google_play']) as PaymentMethodSettings;
@@ -234,16 +249,16 @@ router.post('/', auth, async (req, res) => {
234
249
  });
235
250
  await method.update({ default_currency_id: currency.id });
236
251
 
237
- return res.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
252
+ return c.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
238
253
  }
239
254
 
240
255
  if (raw.type === 'app_store') {
241
256
  if (!raw.settings.app_store?.bundle_id) {
242
- return res.status(400).json({ error: 'app_store bundle_id is required' });
257
+ return c.json({ error: 'app_store bundle_id is required' }, 400);
243
258
  }
244
259
  const env = raw.settings.app_store?.environment;
245
260
  if (env !== 'production' && env !== 'sandbox') {
246
- return res.status(400).json({ error: 'app_store environment must be production or sandbox' });
261
+ return c.json({ error: 'app_store environment must be production or sandbox' }, 400);
247
262
  }
248
263
  // Server API credentials are optional — StoreKit 2 JWS verify doesn't need them.
249
264
  // But if any of the three is set, all three must be set together.
@@ -258,17 +273,33 @@ router.post('/', auth, async (req, res) => {
258
273
  !raw.settings.app_store?.key_id ||
259
274
  !raw.settings.app_store?.private_key_pem
260
275
  ) {
261
- return res.status(400).json({
262
- error: 'app_store Server API credentials must include all of issuer_id, key_id, private_key_pem',
263
- });
276
+ return c.json(
277
+ {
278
+ error: 'app_store Server API credentials must include all of issuer_id, key_id, private_key_pem',
279
+ },
280
+ 400
281
+ );
264
282
  }
265
283
  }
266
284
 
267
- const exist = await PaymentMethod.findOne({
268
- where: { type: 'app_store', livemode: raw.livemode },
285
+ // Phase 6 (W1-4b): bundle_id (+environment) must be deployment-unique —
286
+ // see the google_play comment above for why.
287
+ const sameType = await PaymentMethod.findAll({ where: { type: 'app_store', livemode: raw.livemode } });
288
+ const identifierTaken = sameType.some((m) => {
289
+ const settings = PaymentMethod.decryptSettings(m.settings);
290
+ return (
291
+ settings.app_store?.bundle_id === raw.settings?.app_store?.bundle_id &&
292
+ settings.app_store?.environment === raw.settings?.app_store?.environment
293
+ );
269
294
  });
270
- if (exist) {
271
- return res.status(400).json({ error: 'app_store payment method already exists for this livemode' });
295
+ if (identifierTaken) {
296
+ return c.json(
297
+ {
298
+ error: 'this bundle_id/environment is already registered in this deployment',
299
+ code: 'CHANNEL_ID_TAKEN',
300
+ },
301
+ 400
302
+ );
272
303
  }
273
304
 
274
305
  raw.settings = pick(PaymentMethod.encryptSettings(raw.settings), ['app_store']) as PaymentMethodSettings;
@@ -298,16 +329,16 @@ router.post('/', auth, async (req, res) => {
298
329
  });
299
330
  await method.update({ default_currency_id: currency.id });
300
331
 
301
- return res.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
332
+ return c.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
302
333
  }
303
334
 
304
335
  // FIXME: support bitcoin payment methods
305
336
 
306
- return res.status(400).json({ error: 'payment method type is not supported' });
337
+ return c.json({ error: 'payment method type is not supported' }, 400);
307
338
  });
308
339
 
309
- router.get('/', auth, async (req, res) => {
310
- const { query } = req;
340
+ app.get('/', auth, async (c) => {
341
+ const query = c.req.query();
311
342
  const where: WhereOptions<InferAttributes<PaymentMethod>> = {};
312
343
 
313
344
  if (typeof query.active === 'string') {
@@ -325,34 +356,35 @@ router.get('/', auth, async (req, res) => {
325
356
  if (query.addresses === 'true') {
326
357
  try {
327
358
  const [arcblock, ethereum] = await Promise.all([
328
- getTokenSummaryByDid(wallet.address, !!req.livemode, 'arcblock'),
329
- getTokenSummaryByDid(ethWallet.address, !!req.livemode, EVM_CHAIN_TYPES),
359
+ getTokenSummaryByDid(wallet.address, !!c.get('livemode'), 'arcblock'),
360
+ getTokenSummaryByDid(ethWallet.address, !!c.get('livemode'), EVM_CHAIN_TYPES),
330
361
  ]);
331
- res.json({
362
+ return c.json({
332
363
  list,
333
364
  addresses: { arcblock: wallet.address, ethereum: ethWallet.address },
334
365
  balances: { ...arcblock, ...ethereum },
335
366
  });
336
367
  } catch (err) {
337
- logger.error('get token summary failed', err.message);
338
- res.json({
368
+ logger.error('get token summary failed', (err as any).message);
369
+ return c.json({
339
370
  list,
340
371
  addresses: { arcblock: wallet.address, ethereum: ethWallet.address },
341
372
  balances: {},
342
- error: `get token summary failed: ${err.message}`,
373
+ error: `get token summary failed: ${(err as any).message}`,
343
374
  });
344
375
  }
345
376
  } else {
346
- res.json(list);
377
+ return c.json(list);
347
378
  }
348
379
  } catch (err) {
349
380
  logger.error('get payment methods failed', err);
350
- res.status(400).json({ error: err.message });
381
+ return c.json({ error: (err as any).message }, 400);
351
382
  }
352
383
  });
353
384
 
354
- router.get('/types', auth, (_, res) => {
355
- res.json([
385
+ // registered before /:id so the static segment wins
386
+ app.get('/types', auth, (c) => {
387
+ return c.json([
356
388
  {
357
389
  type: 'arcblock',
358
390
  name: 'ArcBlock',
@@ -392,38 +424,36 @@ router.get('/types', auth, (_, res) => {
392
424
  ]);
393
425
  });
394
426
 
395
- router.get('/:id', auth, async (req, res) => {
427
+ app.get('/:id', auth, async (c) => {
396
428
  const doc = await PaymentMethod.findOne({
397
- where: { [Op.or]: [{ id: req.params.id }, { name: req.params.id }] },
429
+ where: { [Op.or]: [{ id: c.req.param('id') }, { name: c.req.param('id') }] },
398
430
  });
399
431
 
400
432
  if (doc) {
401
- res.json(doc);
402
- } else {
403
- res.status(404).json(null);
433
+ return c.json(doc);
404
434
  }
435
+ return c.json(null, 404);
405
436
  });
406
437
 
407
- router.put('/:id/settings', auth, async (req, res) => {
408
- const { id } = req.params;
409
- const settings = req.body;
438
+ // registered before /:id so the static segment '/settings' wins
439
+ app.put('/:id/settings', auth, async (c) => {
440
+ const id = c.req.param('id');
441
+ const settings = c.get('sanitizedBody') ?? {};
410
442
  try {
411
443
  const paymentMethod = await PaymentMethod.findOne({ where: { id } });
412
444
  if (!paymentMethod) {
413
- return res.status(400).json({ error: 'payment method not found' });
445
+ return c.json({ error: 'payment method not found' }, 400);
414
446
  }
415
447
  if (paymentMethod.type !== 'arcblock') {
416
- return res
417
- .status(400)
418
- .json({ error: `Updating settings is not supported for the ${paymentMethod.type} payment method` });
448
+ return c.json({ error: `Updating settings is not supported for the ${paymentMethod.type} payment method` }, 400);
419
449
  }
420
450
  const updateSettings = merge(cloneDeep(paymentMethod.settings), settings);
421
451
  const doc = await paymentMethod.update({
422
452
  settings: updateSettings,
423
453
  });
424
- return res.json(doc);
454
+ return c.json(doc);
425
455
  } catch (err) {
426
- return res.status(400).json({ error: err.message });
456
+ return c.json({ error: (err as any).message }, 400);
427
457
  }
428
458
  });
429
459
 
@@ -432,17 +462,19 @@ const updateMethodSchema = Joi.object({
432
462
  description: Joi.string().empty('').max(255).optional(),
433
463
  logo: Joi.string().empty('').optional(),
434
464
  }).unknown(true);
435
- router.put('/:id', auth, async (req, res) => {
436
- const { id } = req.params;
437
- const { error, value: raw } = updateMethodSchema.validate(pick(req.body, ['name', 'description', 'logo']));
465
+
466
+ app.put('/:id', auth, async (c) => {
467
+ const id = c.req.param('id');
468
+ const body = c.get('sanitizedBody') ?? {};
469
+ const { error, value: raw } = updateMethodSchema.validate(pick(body, ['name', 'description', 'logo']));
438
470
  if (error) {
439
- return res.status(400).json({ error: error.message });
471
+ return c.json({ error: error.message }, 400);
440
472
  }
441
473
 
442
474
  try {
443
475
  const method = await PaymentMethod.findByPk(id);
444
476
  if (!method) {
445
- return res.status(404).json({ error: 'Payment method not found' });
477
+ return c.json({ error: 'Payment method not found' }, 404);
446
478
  }
447
479
  const updateData: Partial<TPaymentMethod> = {
448
480
  name: raw.name ?? method.name,
@@ -452,17 +484,17 @@ router.put('/:id', auth, async (req, res) => {
452
484
  if ('logo' in method.dataValues || raw.logo !== undefined) {
453
485
  updateData.logo = raw.logo ?? method.logo;
454
486
  }
455
- let updateSettings = 'settings' in req.body ? req.body.settings : null;
487
+ let updateSettings = 'settings' in body ? body.settings : null;
456
488
  if (EVM_CHAIN_TYPES.includes(method.type as string) && updateSettings) {
457
489
  const paymentType = method.type as EVMChainType;
458
490
  if (!updateSettings[paymentType]?.api_host) {
459
- return res.status(400).json({ error: `${paymentType} api_host is required` });
491
+ return c.json({ error: `${paymentType} api_host is required` }, 400);
460
492
  }
461
493
  if (!updateSettings[paymentType]?.explorer_host) {
462
- return res.status(400).json({ error: `${paymentType} explorer_host is required` });
494
+ return c.json({ error: `${paymentType} explorer_host is required` }, 400);
463
495
  }
464
496
  if (!updateSettings[paymentType]?.native_symbol) {
465
- return res.status(400).json({ error: `${paymentType} native_symbol is required` });
497
+ return c.json({ error: `${paymentType} native_symbol is required` }, 400);
466
498
  }
467
499
  try {
468
500
  const provider = new ethers.JsonRpcProvider(updateSettings[paymentType]?.api_host);
@@ -475,21 +507,21 @@ router.put('/:id', auth, async (req, res) => {
475
507
  });
476
508
  } catch (err) {
477
509
  logger.error(`verify ${paymentType} api endpoint failed`, err);
478
- return res.status(400).json({ error: err.message });
510
+ return c.json({ error: (err as any).message }, 400);
479
511
  }
480
512
  updateData.settings = pick(PaymentMethod.encryptSettings(updateSettings), [paymentType]) as PaymentMethodSettings;
481
513
  }
482
514
  if (method.type === 'stripe') {
483
515
  if (!updateSettings.stripe?.publishable_key) {
484
- return res.status(400).json({ error: 'stripe publishable key is required' });
516
+ return c.json({ error: 'stripe publishable key is required' }, 400);
485
517
  }
486
518
  if (!updateSettings.stripe?.secret_key) {
487
- return res.status(400).json({ error: 'stripe secret key is required' });
519
+ return c.json({ error: 'stripe secret key is required' }, 400);
488
520
  }
489
521
  if (method.settings?.stripe?.secret_key !== updateSettings.stripe.secret_key) {
490
522
  const isValid = await validateStripeKeys(updateSettings.stripe.secret_key);
491
523
  if (!isValid) {
492
- return res.status(400).json({ error: 'Invalid Stripe API keys' });
524
+ return c.json({ error: 'Invalid Stripe API keys' }, 400);
493
525
  }
494
526
  updateSettings.stripe.webhook_signing_secret = null;
495
527
  updateSettings = PaymentMethod.encryptSettings(updateSettings);
@@ -502,10 +534,10 @@ router.put('/:id', auth, async (req, res) => {
502
534
  if (method.type === 'stripe') {
503
535
  ensureWebhookRegistered().catch(console.error);
504
536
  }
505
- return res.json(updatedMethod);
537
+ return c.json(updatedMethod);
506
538
  } catch (err) {
507
- return res.status(400).json({ error: err.message });
539
+ return c.json({ error: (err as any).message }, 400);
508
540
  }
509
541
  });
510
542
 
511
- export default router;
543
+ export default app;
@@ -1,15 +1,19 @@
1
- import { Router } from 'express';
1
+ // Phase 3a (express→hono) hono fork of routes/payment-stats.ts. Sub-app with
2
+ // routes relative to /api/payment-stats (mounted via mountResourceGroup). The
3
+ // business logic is unchanged; only the express plumbing becomes hono:
4
+ // req.query → c.req.query(); req.livemode → c.get('livemode'); res.json(x) → return c.json(x).
5
+ import { Hono } from 'hono';
2
6
  import Joi from 'joi';
3
7
  import { Op, type WhereOptions } from 'sequelize';
4
8
  import { joinURL } from 'ufo';
5
9
 
6
10
  import { BN } from '@ocap/util';
7
- import { getPaymentStat } from '../crons/payment-stat';
8
- import { getTokenSummaryByDid } from '../integrations/arcblock/stake';
9
- import { createListParamSchema, getOrder } from '../libs/api';
10
- import { ethWallet, wallet } from '../libs/auth';
11
- import dayjs from '../libs/dayjs';
12
- import { authenticate } from '../libs/security';
11
+ import { getPaymentStat } from '../../crons/payment-stat';
12
+ import { getTokenSummaryByDid } from '../../integrations/arcblock/stake';
13
+ import { createListParamSchema, getOrder } from '../../libs/api';
14
+ import { ethWallet, wallet } from '../../libs/auth';
15
+ import dayjs from '../../libs/dayjs';
16
+ import { authenticate } from '../../middlewares/hono/security';
13
17
  import {
14
18
  CreditGrant,
15
19
  EVMChainType,
@@ -23,11 +27,11 @@ import {
23
27
  Refund,
24
28
  RevenueSnapshot,
25
29
  Subscription,
26
- } from '../store/models';
27
- import { EVM_CHAIN_TYPES } from '../libs/constants';
28
- import logger from '../libs/logger';
30
+ } from '../../store/models';
31
+ import { EVM_CHAIN_TYPES } from '../../libs/constants';
32
+ import logger from '../../libs/logger';
29
33
 
30
- const router = Router();
34
+ const app = new Hono();
31
35
  const auth = authenticate<PaymentStat>({ component: true, roles: ['owner', 'admin'] });
32
36
  const BILLING_REASON_EXCLUSIONS = ['stake', 'stake_overdraft_protection', 'recharge'];
33
37
 
@@ -42,8 +46,9 @@ const summaryQuerySchema = Joi.object({
42
46
  start: Joi.number().positive().optional().empty(''),
43
47
  end: Joi.number().positive().optional().empty(''),
44
48
  });
45
- router.get('/', auth, async (req, res) => {
46
- const { page, pageSize, ...query } = await schema.validateAsync(req.query, { stripUnknown: true });
49
+
50
+ app.get('/', auth, async (c) => {
51
+ const { page, pageSize, ...query } = await schema.validateAsync(c.req.query(), { stripUnknown: true });
47
52
  const where: WhereOptions = {};
48
53
 
49
54
  if (typeof query.livemode === 'boolean') {
@@ -66,7 +71,7 @@ router.get('/', auth, async (req, res) => {
66
71
  try {
67
72
  const { rows: list, count } = await PaymentStat.findAndCountAll({
68
73
  where,
69
- order: getOrder(req.query, [['created_at', 'ASC']]),
74
+ order: getOrder(c.req.query(), [['created_at', 'ASC']]),
70
75
  include: [],
71
76
  });
72
77
 
@@ -76,7 +81,7 @@ router.get('/', auth, async (req, res) => {
76
81
  list.push(
77
82
  // @ts-ignore
78
83
  ...currencies
79
- .filter((x) => x.livemode === !!req.livemode)
84
+ .filter((x) => x.livemode === !!c.get('livemode'))
80
85
  .map((currency) => ({
81
86
  livemode: currency.livemode,
82
87
  timestamp,
@@ -88,10 +93,10 @@ router.get('/', auth, async (req, res) => {
88
93
  );
89
94
  }
90
95
 
91
- res.json({ count, list });
96
+ return c.json({ count, list });
92
97
  } catch (err) {
93
98
  logger.error(err);
94
- res.json({ count: 0, list: [] });
99
+ return c.json({ count: 0, list: [] });
95
100
  }
96
101
  });
97
102
 
@@ -472,23 +477,23 @@ async function getRevenueStats(livemode: boolean, currencyId?: string, start?: n
472
477
  return byCurrency;
473
478
  }
474
479
 
475
- router.get('/summary', auth, async (req, res) => {
480
+ app.get('/summary', auth, async (c) => {
476
481
  try {
477
482
  const {
478
483
  currency_id: currencyId,
479
484
  start,
480
485
  end,
481
- } = await summaryQuerySchema.validateAsync(req.query, {
486
+ } = await summaryQuerySchema.validateAsync(c.req.query(), {
482
487
  stripUnknown: true,
483
488
  });
484
- const livemode = !!req.livemode;
489
+ const livemode = !!c.get('livemode');
485
490
  const [arcblock, ethereum, links, revenueByCurrency] = await Promise.all([
486
- getTokenSummaryByDid(wallet.address, !!req.livemode, 'arcblock'),
487
- getTokenSummaryByDid(ethWallet.address, !!req.livemode, EVM_CHAIN_TYPES),
491
+ getTokenSummaryByDid(wallet.address, !!c.get('livemode'), 'arcblock'),
492
+ getTokenSummaryByDid(ethWallet.address, !!c.get('livemode'), EVM_CHAIN_TYPES),
488
493
  getCurrencyLinks(livemode),
489
494
  getRevenueStats(livemode, currencyId, start, end),
490
495
  ]);
491
- res.json({
496
+ return c.json({
492
497
  links,
493
498
  balances: { ...arcblock, ...ethereum },
494
499
  addresses: { arcblock: wallet.address, ethereum: ethWallet.address },
@@ -503,8 +508,8 @@ router.get('/summary', auth, async (req, res) => {
503
508
  });
504
509
  } catch (err) {
505
510
  logger.error(err);
506
- res.json(null);
511
+ return c.json(null);
507
512
  }
508
513
  });
509
514
 
510
- export default router;
515
+ export default app;