tapimo 0.2.0 → 0.3.0

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 (313) hide show
  1. package/README.md +31 -3
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +5 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +28 -1
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +34 -1
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +7167 -4507
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +8 -0
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +11 -2
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +14 -3
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +128 -118
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/apps/api-keys.d.ts +7 -0
  21. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  22. package/dist/admin/apps/scopes.d.ts +8 -0
  23. package/dist/admin/apps/scopes.d.ts.map +1 -1
  24. package/dist/admin/apps/scopes.js +3 -0
  25. package/dist/admin/apps/scopes.js.map +1 -1
  26. package/dist/admin/apps/verified-tokens.d.ts +57 -57
  27. package/dist/admin/ui.generated.d.ts +1 -1
  28. package/dist/admin/ui.generated.js +13 -13
  29. package/dist/admin/ui.generated.js.map +1 -1
  30. package/dist/analytics/Analytics.d.ts +151 -0
  31. package/dist/analytics/Analytics.d.ts.map +1 -0
  32. package/dist/analytics/Analytics.js +212 -0
  33. package/dist/analytics/Analytics.js.map +1 -0
  34. package/dist/analytics/tables/requestEvents.d.ts +215 -0
  35. package/dist/analytics/tables/requestEvents.d.ts.map +1 -0
  36. package/dist/analytics/tables/requestEvents.js +264 -0
  37. package/dist/analytics/tables/requestEvents.js.map +1 -0
  38. package/dist/apps/data/App.d.ts +1024 -624
  39. package/dist/apps/data/App.d.ts.map +1 -1
  40. package/dist/apps/data/App.js +36 -0
  41. package/dist/apps/data/App.js.map +1 -1
  42. package/dist/apps/data/routes/balances.d.ts +45 -45
  43. package/dist/apps/data/routes/coingecko.d.ts +176 -176
  44. package/dist/apps/data/routes/exchanges.d.ts +455 -455
  45. package/dist/apps/data/routes/fee-amm.d.ts +101 -101
  46. package/dist/apps/data/routes/funding.d.ts +765 -0
  47. package/dist/apps/data/routes/funding.d.ts.map +1 -0
  48. package/dist/apps/data/routes/funding.js +383 -0
  49. package/dist/apps/data/routes/funding.js.map +1 -0
  50. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  51. package/dist/apps/data/routes/receipts.js +2 -8
  52. package/dist/apps/data/routes/receipts.js.map +1 -1
  53. package/dist/apps/data/routes/rpc.d.ts +29 -36
  54. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  55. package/dist/apps/data/routes/rpc.js +29 -1
  56. package/dist/apps/data/routes/rpc.js.map +1 -1
  57. package/dist/apps/data/routes/tokenlist.d.ts +36 -36
  58. package/dist/apps/data/routes/transfers.d.ts +56 -56
  59. package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
  60. package/dist/apps/data/routes/webhooks.d.ts +45 -45
  61. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  62. package/dist/apps/data/routes/webhooks.js +8 -8
  63. package/dist/apps/data/routes/webhooks.js.map +1 -1
  64. package/dist/apps/docs/App.d.ts +4 -2
  65. package/dist/apps/docs/App.d.ts.map +1 -1
  66. package/dist/apps/docs/App.js +27 -95
  67. package/dist/apps/docs/App.js.map +1 -1
  68. package/dist/apps/docs/reference.d.ts +21 -0
  69. package/dist/apps/docs/reference.d.ts.map +1 -0
  70. package/dist/apps/docs/reference.js +112 -0
  71. package/dist/apps/docs/reference.js.map +1 -0
  72. package/dist/apps/index.d.ts +1 -0
  73. package/dist/apps/index.d.ts.map +1 -1
  74. package/dist/apps/index.js +1 -0
  75. package/dist/apps/index.js.map +1 -1
  76. package/dist/apps/mcp.d.ts +76 -0
  77. package/dist/apps/mcp.d.ts.map +1 -0
  78. package/dist/apps/mcp.js +188 -0
  79. package/dist/apps/mcp.js.map +1 -0
  80. package/dist/apps/platform/App.d.ts +3005 -728
  81. package/dist/apps/platform/App.d.ts.map +1 -1
  82. package/dist/apps/platform/App.js +13 -3
  83. package/dist/apps/platform/App.js.map +1 -1
  84. package/dist/apps/platform/Billing.d.ts +279 -0
  85. package/dist/apps/platform/Billing.d.ts.map +1 -0
  86. package/dist/apps/platform/Billing.js +477 -0
  87. package/dist/apps/platform/Billing.js.map +1 -0
  88. package/dist/apps/platform/index.d.ts +1 -0
  89. package/dist/apps/platform/index.d.ts.map +1 -1
  90. package/dist/apps/platform/index.js +1 -0
  91. package/dist/apps/platform/index.js.map +1 -1
  92. package/dist/apps/platform/routes/api-keys.d.ts +341 -49
  93. package/dist/apps/platform/routes/api-keys.d.ts.map +1 -1
  94. package/dist/apps/platform/routes/api-keys.js +115 -13
  95. package/dist/apps/platform/routes/api-keys.js.map +1 -1
  96. package/dist/apps/platform/routes/billing.d.ts +1520 -0
  97. package/dist/apps/platform/routes/billing.d.ts.map +1 -0
  98. package/dist/apps/platform/routes/billing.js +795 -0
  99. package/dist/apps/platform/routes/billing.js.map +1 -0
  100. package/dist/apps/platform/routes/invitations.d.ts +201 -83
  101. package/dist/apps/platform/routes/invitations.d.ts.map +1 -1
  102. package/dist/apps/platform/routes/invitations.js +58 -0
  103. package/dist/apps/platform/routes/invitations.js.map +1 -1
  104. package/dist/apps/platform/routes/me.d.ts +17 -17
  105. package/dist/apps/platform/routes/orgs.d.ts +50 -36
  106. package/dist/apps/platform/routes/orgs.d.ts.map +1 -1
  107. package/dist/apps/platform/routes/orgs.js +14 -3
  108. package/dist/apps/platform/routes/orgs.js.map +1 -1
  109. package/dist/apps/platform/routes/projects.d.ts +97 -97
  110. package/dist/apps/platform/routes/scopes.d.ts +107 -0
  111. package/dist/apps/platform/routes/scopes.d.ts.map +1 -0
  112. package/dist/apps/platform/routes/scopes.js +66 -0
  113. package/dist/apps/platform/routes/scopes.js.map +1 -0
  114. package/dist/apps/platform/routes/usage.d.ts +588 -0
  115. package/dist/apps/platform/routes/usage.d.ts.map +1 -0
  116. package/dist/apps/platform/routes/usage.js +391 -0
  117. package/dist/apps/platform/routes/usage.js.map +1 -0
  118. package/dist/apps/relay/App.d.ts +4 -1
  119. package/dist/apps/relay/App.d.ts.map +1 -1
  120. package/dist/apps/relay/App.js +118 -10
  121. package/dist/apps/relay/App.js.map +1 -1
  122. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  123. package/dist/apps/relay/Sponsorships.js +2 -1
  124. package/dist/apps/relay/Sponsorships.js.map +1 -1
  125. package/dist/cli/Cli.d.ts +8 -1
  126. package/dist/cli/Cli.d.ts.map +1 -1
  127. package/dist/cli/Cli.js +11 -3
  128. package/dist/cli/Cli.js.map +1 -1
  129. package/dist/cli/commands/admin.d.ts +4 -0
  130. package/dist/cli/commands/admin.d.ts.map +1 -1
  131. package/dist/cli/commands/admin.js +80 -1
  132. package/dist/cli/commands/admin.js.map +1 -1
  133. package/dist/db/Db.d.ts +7 -0
  134. package/dist/db/Db.d.ts.map +1 -1
  135. package/dist/db/Db.js +126 -0
  136. package/dist/db/Db.js.map +1 -1
  137. package/dist/db/Schema.d.ts +79 -0
  138. package/dist/db/Schema.d.ts.map +1 -1
  139. package/dist/db/Schema.js +88 -2
  140. package/dist/db/Schema.js.map +1 -1
  141. package/dist/db/tables/billingSettings.d.ts +55 -0
  142. package/dist/db/tables/billingSettings.d.ts.map +1 -0
  143. package/dist/db/tables/billingSettings.js +70 -0
  144. package/dist/db/tables/billingSettings.js.map +1 -0
  145. package/dist/db/tables/invitations.js +2 -2
  146. package/dist/db/tables/invitations.js.map +1 -1
  147. package/dist/db/tables/organizations.d.ts +6 -2
  148. package/dist/db/tables/organizations.d.ts.map +1 -1
  149. package/dist/db/tables/organizations.js +10 -4
  150. package/dist/db/tables/organizations.js.map +1 -1
  151. package/dist/db/tables/projects.js +2 -2
  152. package/dist/db/tables/projects.js.map +1 -1
  153. package/dist/db/tables/requestUsage.d.ts +121 -0
  154. package/dist/db/tables/requestUsage.d.ts.map +1 -0
  155. package/dist/db/tables/requestUsage.js +150 -0
  156. package/dist/db/tables/requestUsage.js.map +1 -0
  157. package/dist/db/tables/sponsoredTransactions.d.ts +119 -0
  158. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  159. package/dist/db/tables/sponsoredTransactions.js +155 -2
  160. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  161. package/dist/db/tables/stripeCustomers.d.ts +81 -0
  162. package/dist/db/tables/stripeCustomers.d.ts.map +1 -0
  163. package/dist/db/tables/stripeCustomers.js +120 -0
  164. package/dist/db/tables/stripeCustomers.js.map +1 -0
  165. package/dist/db/tables/users.js +2 -2
  166. package/dist/db/tables/users.js.map +1 -1
  167. package/dist/handlers/internal/sponsorship.d.ts +5 -2
  168. package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
  169. package/dist/handlers/internal/sponsorship.js +19 -5
  170. package/dist/handlers/internal/sponsorship.js.map +1 -1
  171. package/dist/handlers/internal/utils.d.ts +10 -3
  172. package/dist/handlers/internal/utils.d.ts.map +1 -1
  173. package/dist/handlers/internal/utils.js +14 -6
  174. package/dist/handlers/internal/utils.js.map +1 -1
  175. package/dist/index.d.ts +1 -0
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +1 -0
  178. package/dist/index.js.map +1 -1
  179. package/dist/internal/Auth.d.ts +18 -4
  180. package/dist/internal/Auth.d.ts.map +1 -1
  181. package/dist/internal/Auth.js +148 -76
  182. package/dist/internal/Auth.js.map +1 -1
  183. package/dist/internal/Cache.d.ts.map +1 -1
  184. package/dist/internal/Cache.js +4 -1
  185. package/dist/internal/Cache.js.map +1 -1
  186. package/dist/internal/EdgeCache.d.ts +10 -0
  187. package/dist/internal/EdgeCache.d.ts.map +1 -1
  188. package/dist/internal/EdgeCache.js +39 -8
  189. package/dist/internal/EdgeCache.js.map +1 -1
  190. package/dist/internal/Fees.d.ts +27 -0
  191. package/dist/internal/Fees.d.ts.map +1 -0
  192. package/dist/internal/Fees.js +48 -0
  193. package/dist/internal/Fees.js.map +1 -0
  194. package/dist/internal/FundingRoutes.d.ts +183 -0
  195. package/dist/internal/FundingRoutes.d.ts.map +1 -0
  196. package/dist/internal/FundingRoutes.js +490 -0
  197. package/dist/internal/FundingRoutes.js.map +1 -0
  198. package/dist/internal/Id.d.ts +15 -0
  199. package/dist/internal/Id.d.ts.map +1 -0
  200. package/dist/internal/Id.js +22 -0
  201. package/dist/internal/Id.js.map +1 -0
  202. package/dist/internal/Log.d.ts +2 -0
  203. package/dist/internal/Log.d.ts.map +1 -1
  204. package/dist/internal/Log.js +3 -0
  205. package/dist/internal/Log.js.map +1 -1
  206. package/dist/internal/OpenApi.d.ts +10 -1
  207. package/dist/internal/OpenApi.d.ts.map +1 -1
  208. package/dist/internal/OpenApi.js +8 -1
  209. package/dist/internal/OpenApi.js.map +1 -1
  210. package/dist/internal/RateLimit.d.ts +25 -0
  211. package/dist/internal/RateLimit.d.ts.map +1 -1
  212. package/dist/internal/RateLimit.js +51 -0
  213. package/dist/internal/RateLimit.js.map +1 -1
  214. package/dist/internal/Response.d.ts +1 -1
  215. package/dist/internal/Response.d.ts.map +1 -1
  216. package/dist/internal/Schema.d.ts +8 -0
  217. package/dist/internal/Schema.d.ts.map +1 -1
  218. package/dist/internal/Schema.js +7 -0
  219. package/dist/internal/Schema.js.map +1 -1
  220. package/dist/internal/Webhooks.d.ts.map +1 -1
  221. package/dist/internal/Webhooks.js +3 -3
  222. package/dist/internal/Webhooks.js.map +1 -1
  223. package/package.json +4 -3
  224. package/src/ApiKey.ts +9 -2
  225. package/src/ApiKeys.test.ts +51 -0
  226. package/src/ApiKeys.ts +50 -1
  227. package/src/App.test.ts +33 -86718
  228. package/src/App.ts +18 -0
  229. package/src/Client.test-d.ts +351 -0
  230. package/src/Scope.ts +16 -3
  231. package/src/admin/apps/scopes.test.ts +6 -0
  232. package/src/admin/apps/scopes.ts +3 -0
  233. package/src/admin/ui/src/components/Page.tsx +2 -3
  234. package/src/admin/ui/src/routes/__root.tsx +2 -2
  235. package/src/admin/ui/src/routes/api-keys.tsx +2 -2
  236. package/src/admin/ui.generated.ts +13 -13
  237. package/src/analytics/Analytics.test.ts +527 -0
  238. package/src/analytics/Analytics.ts +318 -0
  239. package/src/analytics/tables/requestEvents.ts +523 -0
  240. package/src/apps/data/App.test.ts +72 -0
  241. package/src/apps/data/App.ts +35 -0
  242. package/src/apps/data/routes/funding.test.ts +214 -0
  243. package/src/apps/data/routes/funding.ts +584 -0
  244. package/src/apps/data/routes/receipts.ts +2 -9
  245. package/src/apps/data/routes/rpc.test.ts +78 -2
  246. package/src/apps/data/routes/rpc.ts +31 -1
  247. package/src/apps/data/routes/webhooks.test.ts +1 -1
  248. package/src/apps/data/routes/webhooks.ts +11 -8
  249. package/src/apps/docs/App.ts +29 -100
  250. package/src/apps/docs/reference.ts +132 -0
  251. package/src/apps/index.ts +1 -0
  252. package/src/apps/mcp.test.ts +206 -0
  253. package/src/apps/mcp.ts +250 -0
  254. package/src/apps/platform/App.ts +43 -4
  255. package/src/apps/platform/Billing.test.ts +530 -0
  256. package/src/apps/platform/Billing.ts +682 -0
  257. package/src/apps/platform/index.ts +1 -0
  258. package/src/apps/platform/routes/api-keys.test.ts +172 -9
  259. package/src/apps/platform/routes/api-keys.ts +136 -20
  260. package/src/apps/platform/routes/billing.test.ts +1100 -0
  261. package/src/apps/platform/routes/billing.ts +966 -0
  262. package/src/apps/platform/routes/invitations.test.ts +55 -7
  263. package/src/apps/platform/routes/invitations.ts +68 -0
  264. package/src/apps/platform/routes/me.test.ts +230 -0
  265. package/src/apps/platform/routes/orgs.ts +26 -4
  266. package/src/apps/platform/routes/scopes.test.ts +29 -0
  267. package/src/apps/platform/routes/scopes.ts +85 -0
  268. package/src/apps/platform/routes/usage.test.ts +422 -0
  269. package/src/apps/platform/routes/usage.ts +527 -0
  270. package/src/apps/relay/App.test.ts +457 -8
  271. package/src/apps/relay/App.ts +120 -12
  272. package/src/apps/relay/Sponsorships.test.ts +1 -1
  273. package/src/apps/relay/Sponsorships.ts +2 -1
  274. package/src/cli/Cli.test.ts +25 -2
  275. package/src/cli/Cli.ts +17 -2
  276. package/src/cli/commands/admin.test.ts +83 -0
  277. package/src/cli/commands/admin.ts +89 -1
  278. package/src/db/Db.ts +137 -0
  279. package/src/db/Schema.ts +104 -2
  280. package/src/db/tables/billingSettings.test.ts +87 -0
  281. package/src/db/tables/billingSettings.ts +108 -0
  282. package/src/db/tables/invitations.ts +2 -2
  283. package/src/db/tables/organizations.test.ts +1 -1
  284. package/src/db/tables/organizations.ts +15 -5
  285. package/src/db/tables/projects.ts +2 -2
  286. package/src/db/tables/requestUsage.ts +231 -0
  287. package/src/db/tables/sponsoredTransactions.test.ts +108 -1
  288. package/src/db/tables/sponsoredTransactions.ts +230 -2
  289. package/src/db/tables/stripeCustomers.test.ts +109 -0
  290. package/src/db/tables/stripeCustomers.ts +162 -0
  291. package/src/db/tables/users.ts +2 -2
  292. package/src/handlers/internal/sponsorship.ts +34 -7
  293. package/src/handlers/internal/utils.ts +19 -7
  294. package/src/index.ts +1 -0
  295. package/src/internal/Auth.test.ts +175 -25
  296. package/src/internal/Auth.ts +175 -86
  297. package/src/internal/Cache.ts +5 -1
  298. package/src/internal/EdgeCache.test.ts +27 -4
  299. package/src/internal/EdgeCache.ts +47 -9
  300. package/src/internal/Fees.test.ts +32 -0
  301. package/src/internal/Fees.ts +51 -0
  302. package/src/internal/FundingRoutes.ts +583 -0
  303. package/src/internal/Id.test.ts +17 -0
  304. package/src/internal/Id.ts +24 -0
  305. package/src/internal/Log.test.ts +1 -0
  306. package/src/internal/Log.ts +5 -0
  307. package/src/internal/OpenApi.ts +12 -1
  308. package/src/internal/RateLimit.test.ts +84 -0
  309. package/src/internal/RateLimit.ts +70 -0
  310. package/src/internal/Response.ts +1 -1
  311. package/src/internal/Schema.ts +8 -0
  312. package/src/internal/Webhooks.test.ts +3 -3
  313. package/src/internal/Webhooks.ts +3 -3
@@ -0,0 +1,121 @@
1
+ import { type ColumnType } from 'kysely';
2
+ import type * as Db from '../Db.js';
3
+ import type * as db_Schema from '../Schema.js';
4
+ /** A `bigint` count column: read as a string from pg, written as a number. */
5
+ type Count = ColumnType<string, number, number>;
6
+ /** Environment a request-usage row attributes to. */
7
+ export type Environment = db_Schema.RequestUsageBucket['environment'];
8
+ /** Exactly-once state of a meter event. */
9
+ export type State = db_Schema.RequestUsageMeterEvent['state'];
10
+ /** Columns of the `request_usage_buckets` table (pg representation). */
11
+ export type BucketTable = {
12
+ bucketStart: string;
13
+ environment: Environment;
14
+ orgId: string;
15
+ reportedCount: Count;
16
+ updatedAt: string;
17
+ };
18
+ /** Columns of the `request_usage_meter_events` table (pg representation). */
19
+ export type MeterEventTable = {
20
+ bucketStart: string;
21
+ deltaCount: Count;
22
+ environment: Environment;
23
+ error: string | null;
24
+ firstAttemptedAt: string;
25
+ identifier: string;
26
+ orgId: string;
27
+ reason: string | null;
28
+ reportedAt: string | null;
29
+ sequence: number;
30
+ state: State;
31
+ stripeCustomerId: string;
32
+ };
33
+ /** A stored per-hour request-count watermark. */
34
+ export type Bucket = db_Schema.RequestUsageBucket;
35
+ /** A stored request-count meter event. */
36
+ export type MeterEvent = db_Schema.RequestUsageMeterEvent;
37
+ /** Identifies one hourly bucket for an org in an environment. */
38
+ export type BucketKey = {
39
+ /** UTC hour start (ISO 8601). */
40
+ bucketStart: string;
41
+ /** Environment the requests were served under. */
42
+ environment: Environment;
43
+ /** Organization id (`org_…`). */
44
+ orgId: string;
45
+ };
46
+ /**
47
+ * Reads a bucket watermark.
48
+ *
49
+ * @param db - The database.
50
+ * @param key - The bucket key.
51
+ * @returns The watermark, or `undefined` when none has been reported yet.
52
+ */
53
+ export declare function getBucket(db: Db.Db, key: BucketKey): Promise<Bucket | undefined>;
54
+ /**
55
+ * Lists the meter events still awaiting a Stripe acknowledgement in an
56
+ * environment, oldest first — the reporter's crash-recovery drive.
57
+ *
58
+ * @param db - The database.
59
+ * @param environment - The environment to scan.
60
+ * @returns The pending meter events.
61
+ */
62
+ export declare function listPending(db: Db.Db, environment: Environment): Promise<MeterEvent[]>;
63
+ /**
64
+ * Counts the meter events already reported for a bucket — the next delta's
65
+ * `sequence`, so a new seal never collides with a settled one.
66
+ *
67
+ * @param db - The database.
68
+ * @param key - The bucket key.
69
+ * @returns The count of reported events for the bucket.
70
+ */
71
+ export declare function countReported(db: Db.Db, key: BucketKey): Promise<number>;
72
+ /**
73
+ * Inserts a frozen `pending` meter event, claiming a delta. Idempotent on the
74
+ * deterministic `identifier`: a re-seal after a crash resolves to the existing
75
+ * row rather than duplicating the delta.
76
+ *
77
+ * @param db - The database.
78
+ * @param input - The event to insert.
79
+ * @returns Whether this call inserted the row.
80
+ */
81
+ export declare function insertPending(db: Db.Db, input: insertPending.Input): Promise<boolean>;
82
+ export declare namespace insertPending {
83
+ /** Fields accepted when sealing a pending meter event. */
84
+ type Input = {
85
+ /** UTC hour start the delta bills for (ISO 8601). */
86
+ bucketStart: string;
87
+ /** Frozen request count this event bills (positive). */
88
+ deltaCount: number;
89
+ /** Environment the requests were served under. */
90
+ environment: Environment;
91
+ /** Deterministic id; also the Stripe identifier and idempotency key. */
92
+ identifier: string;
93
+ /** Organization id (`org_…`). */
94
+ orgId: string;
95
+ /** Delta sequence within the bucket. */
96
+ sequence: number;
97
+ /** Stripe customer id the event bills against. */
98
+ stripeCustomerId: string;
99
+ };
100
+ }
101
+ /**
102
+ * Marks a pending event reported and advances its bucket watermark by the
103
+ * event's frozen delta, atomically. A no-op once reported, so a retry after a
104
+ * crash between the Stripe ack and this write never double-advances.
105
+ *
106
+ * @param db - The database.
107
+ * @param identifier - The event identifier.
108
+ * @param at - When Stripe acknowledged the event (ISO 8601).
109
+ * @returns Whether this call settled the event (false when already reported).
110
+ */
111
+ export declare function settle(db: Db.Db, identifier: string, at: string): Promise<boolean>;
112
+ /**
113
+ * Records a transient failure on a pending event; it stays pending for retry.
114
+ *
115
+ * @param db - The database.
116
+ * @param identifier - The event identifier.
117
+ * @param error - The failure detail.
118
+ */
119
+ export declare function markError(db: Db.Db, identifier: string, error: string): Promise<void>;
120
+ export {};
121
+ //# sourceMappingURL=requestUsage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestUsage.d.ts","sourceRoot":"","sources":["../../../src/db/tables/requestUsage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { sql } from 'kysely';
2
+ /**
3
+ * Reads a bucket watermark.
4
+ *
5
+ * @param db - The database.
6
+ * @param key - The bucket key.
7
+ * @returns The watermark, or `undefined` when none has been reported yet.
8
+ */
9
+ export async function getBucket(db, key) {
10
+ const row = await db.kysely
11
+ .selectFrom('request_usage_buckets')
12
+ .selectAll()
13
+ .where('orgId', '=', key.orgId)
14
+ .where('environment', '=', key.environment)
15
+ .where('bucketStart', '=', key.bucketStart)
16
+ .executeTakeFirst();
17
+ return row ? toBucket(row) : undefined;
18
+ }
19
+ /**
20
+ * Lists the meter events still awaiting a Stripe acknowledgement in an
21
+ * environment, oldest first — the reporter's crash-recovery drive.
22
+ *
23
+ * @param db - The database.
24
+ * @param environment - The environment to scan.
25
+ * @returns The pending meter events.
26
+ */
27
+ export async function listPending(db, environment) {
28
+ const rows = await db.kysely
29
+ .selectFrom('request_usage_meter_events')
30
+ .selectAll()
31
+ .where('environment', '=', environment)
32
+ .where('state', '=', 'pending')
33
+ .orderBy('firstAttemptedAt', 'asc')
34
+ .orderBy('identifier', 'asc')
35
+ .execute();
36
+ return rows.map(toMeterEvent);
37
+ }
38
+ /**
39
+ * Counts the meter events already reported for a bucket — the next delta's
40
+ * `sequence`, so a new seal never collides with a settled one.
41
+ *
42
+ * @param db - The database.
43
+ * @param key - The bucket key.
44
+ * @returns The count of reported events for the bucket.
45
+ */
46
+ export async function countReported(db, key) {
47
+ const row = await db.kysely
48
+ .selectFrom('request_usage_meter_events')
49
+ .select((eb) => eb.fn.countAll().as('count'))
50
+ .where('orgId', '=', key.orgId)
51
+ .where('environment', '=', key.environment)
52
+ .where('bucketStart', '=', key.bucketStart)
53
+ .where('state', '=', 'reported')
54
+ .executeTakeFirstOrThrow();
55
+ return Number(row.count);
56
+ }
57
+ /**
58
+ * Inserts a frozen `pending` meter event, claiming a delta. Idempotent on the
59
+ * deterministic `identifier`: a re-seal after a crash resolves to the existing
60
+ * row rather than duplicating the delta.
61
+ *
62
+ * @param db - The database.
63
+ * @param input - The event to insert.
64
+ * @returns Whether this call inserted the row.
65
+ */
66
+ export async function insertPending(db, input) {
67
+ const now = new Date().toISOString();
68
+ const inserted = await db.kysely
69
+ .insertInto('request_usage_meter_events')
70
+ .values({
71
+ bucketStart: input.bucketStart,
72
+ deltaCount: input.deltaCount,
73
+ environment: input.environment,
74
+ error: null,
75
+ firstAttemptedAt: now,
76
+ identifier: input.identifier,
77
+ orgId: input.orgId,
78
+ reason: null,
79
+ reportedAt: null,
80
+ sequence: input.sequence,
81
+ state: 'pending',
82
+ stripeCustomerId: input.stripeCustomerId,
83
+ })
84
+ .onConflict((oc) => oc.doNothing())
85
+ .returning('identifier')
86
+ .executeTakeFirst();
87
+ return Boolean(inserted);
88
+ }
89
+ /**
90
+ * Marks a pending event reported and advances its bucket watermark by the
91
+ * event's frozen delta, atomically. A no-op once reported, so a retry after a
92
+ * crash between the Stripe ack and this write never double-advances.
93
+ *
94
+ * @param db - The database.
95
+ * @param identifier - The event identifier.
96
+ * @param at - When Stripe acknowledged the event (ISO 8601).
97
+ * @returns Whether this call settled the event (false when already reported).
98
+ */
99
+ export function settle(db, identifier, at) {
100
+ return db.transaction(async (tx) => {
101
+ const updated = await tx.kysely
102
+ .updateTable('request_usage_meter_events')
103
+ .set({ error: null, reportedAt: at, state: 'reported' })
104
+ .where('identifier', '=', identifier)
105
+ .where('state', '=', 'pending')
106
+ .returningAll()
107
+ .executeTakeFirst();
108
+ if (!updated)
109
+ return false;
110
+ await tx.kysely
111
+ .insertInto('request_usage_buckets')
112
+ .values({
113
+ bucketStart: updated.bucketStart,
114
+ environment: updated.environment,
115
+ orgId: updated.orgId,
116
+ reportedCount: Number(updated.deltaCount),
117
+ updatedAt: at,
118
+ })
119
+ .onConflict((oc) => oc.columns(['orgId', 'environment', 'bucketStart']).doUpdateSet({
120
+ reportedCount: sql `request_usage_buckets.reported_count + ${updated.deltaCount}`,
121
+ updatedAt: at,
122
+ }))
123
+ .execute();
124
+ return true;
125
+ });
126
+ }
127
+ /**
128
+ * Records a transient failure on a pending event; it stays pending for retry.
129
+ *
130
+ * @param db - The database.
131
+ * @param identifier - The event identifier.
132
+ * @param error - The failure detail.
133
+ */
134
+ export async function markError(db, identifier, error) {
135
+ await db.kysely
136
+ .updateTable('request_usage_meter_events')
137
+ .set({ error: error.slice(0, 500) })
138
+ .where('identifier', '=', identifier)
139
+ .where('state', '=', 'pending')
140
+ .execute();
141
+ }
142
+ /** Maps a bucket row to its domain record. */
143
+ function toBucket(row) {
144
+ return { ...row, reportedCount: Number(row.reportedCount) };
145
+ }
146
+ /** Maps a meter-event row to its domain record. */
147
+ function toMeterEvent(row) {
148
+ return { ...row, deltaCount: Number(row.deltaCount) };
149
+ }
150
+ //# sourceMappingURL=requestUsage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestUsage.js","sourceRoot":"","sources":["../../../src/db/tables/requestUsage.ts"],"names":[],"mappings":"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"}
@@ -26,8 +26,12 @@ export declare namespace upsert {
26
26
  billable: boolean;
27
27
  /** Chain the sponsored transaction targets. */
28
28
  chainId: number;
29
+ /** Lowercase fee currency snapshot (`usd`), when resolved. */
30
+ currency?: string | undefined;
29
31
  /** Key environment the sponsorship was requested under. */
30
32
  environment: Table['environment'];
33
+ /** Signed fee cap (`gas × maxFeePerGas`) in base units, when known. */
34
+ feeMax?: string | undefined;
31
35
  /** Fee token the sponsorship resolved, when known. */
32
36
  feeToken?: string | undefined;
33
37
  /** Organization id (`org_…`) the spend attributes to. */
@@ -117,4 +121,119 @@ export declare namespace finalize {
117
121
  * @param finalizedAt - When the sponsorship was marked failed (ISO 8601).
118
122
  */
119
123
  export declare function fail(db: Db.Db, id: string, finalizedAt: string): Promise<void>;
124
+ /**
125
+ * Records a sponsorship and enforces the period spend limit atomically. A
126
+ * per-org advisory lock serializes concurrent sponsorships so each one's
127
+ * signed cap is counted before the limit check; without it a burst reads
128
+ * pre-burst spend and overshoots. Throws {@link PeriodSpendLimitError} (rolling
129
+ * back the row) when the limit would be exceeded.
130
+ *
131
+ * @param db - The database (primary; never a cached replica).
132
+ * @param input - The sponsorship to record.
133
+ * @param limit - The period spend limit to enforce.
134
+ * @returns The stored record.
135
+ */
136
+ export declare function reserve(db: Db.Db, input: upsert.Input, limit: reserve.Limit): Promise<Record>;
137
+ export declare namespace reserve {
138
+ /** The period spend limit enforced by {@link reserve}. */
139
+ type Limit = {
140
+ /** Chains whose spend counts (mainnet chain ids). */
141
+ chainIds: readonly number[];
142
+ /** Limit in fee-token base units. */
143
+ max: bigint;
144
+ /** Window start (ISO 8601). */
145
+ since: string;
146
+ };
147
+ }
148
+ /**
149
+ * Billable spend committed since a cutoff, in fee-token base units: finalized
150
+ * rows at their actual fee plus pending rows at their signed fee cap, so
151
+ * in-flight sponsorships consume limit budget until receipts land.
152
+ *
153
+ * @param db - The database.
154
+ * @param options - Aggregation scope.
155
+ * @returns The committed spend in base units.
156
+ */
157
+ export declare function spend(db: Db.Db, options: spend.Options): Promise<bigint>;
158
+ export declare namespace spend {
159
+ /** Options for {@link spend}. */
160
+ type Options = {
161
+ /** Chains whose spend counts (mainnet chain ids). */
162
+ chainIds: readonly number[];
163
+ /** Environment whose spend counts; production mirrors the billing gate, sandbox is display-only. Defaults to `production`. */
164
+ environment?: Table['environment'] | undefined;
165
+ /** Organization id (`org_…`) the spend attributes to. */
166
+ orgId: string;
167
+ /** Window start (ISO 8601); rows created earlier are out of scope. */
168
+ since: string;
169
+ };
170
+ }
171
+ /**
172
+ * Sponsorship usage bucketed by time for one organization: row counts and
173
+ * committed fees per bucket. Fee semantics mirror {@link spend}: finalized
174
+ * rows at their actual fee, pending rows at their signed cap, failed rows at
175
+ * zero. Buckets with no rows are omitted.
176
+ *
177
+ * @param db - The database.
178
+ * @param options - Aggregation scope.
179
+ * @returns Time-ordered usage buckets.
180
+ */
181
+ export declare function usage(db: Db.Db, options: usage.Options): Promise<usage.Bucket[]>;
182
+ export declare namespace usage {
183
+ /** One time bucket of sponsorship usage. */
184
+ type Bucket = {
185
+ /** Sponsored transactions recorded in the bucket, any status. */
186
+ count: number;
187
+ /** Committed fees in fee-token base units: finalized fees plus pending caps. */
188
+ feeTotal: bigint;
189
+ /** Bucket start (ISO 8601), aligned to UTC calendar boundaries. */
190
+ timestamp: string;
191
+ };
192
+ /** Options for {@link usage}. */
193
+ type Options = {
194
+ /** Key environment to restrict to; omit for all. */
195
+ environment?: Table['environment'] | undefined;
196
+ /** Window start (ISO 8601), inclusive. */
197
+ from: string;
198
+ /** Bucket width, aligned to UTC calendar boundaries. */
199
+ interval: 'day' | 'hour' | 'month' | 'week';
200
+ /** Organization id (`org_…`) the usage attributes to. */
201
+ orgId: string;
202
+ /** Project id (`prj_…`) to restrict to; omit for all. */
203
+ projectId?: string | undefined;
204
+ /** Window end (ISO 8601), exclusive. */
205
+ to: string;
206
+ };
207
+ }
208
+ /**
209
+ * Lists finalized billable rows not yet reported to the billing meter, oldest
210
+ * first, for the metering job.
211
+ *
212
+ * @param db - The database.
213
+ * @param options - Reporting scope.
214
+ * @returns The unreported records.
215
+ */
216
+ export declare function listUnreported(db: Db.Db, options: listUnreported.Options): Promise<Record[]>;
217
+ export declare namespace listUnreported {
218
+ /** Options for {@link listUnreported}. */
219
+ type Options = {
220
+ /** Chains whose spend is metered (mainnet chain ids). */
221
+ chainIds: readonly number[];
222
+ /** Maximum rows to return. */
223
+ limit?: number | undefined;
224
+ };
225
+ }
226
+ /**
227
+ * Marks a row as reported to the billing meter. A no-op once marked — the
228
+ * durable exactly-once guard for the metering job.
229
+ *
230
+ * @param db - The database.
231
+ * @param id - The sponsored-transaction id (`stx_…`).
232
+ * @param at - When the report was acknowledged (ISO 8601).
233
+ */
234
+ export declare function markReported(db: Db.Db, id: string, at: string): Promise<void>;
235
+ /** Thrown by {@link reserve} when recording would exceed the org's period spend limit. */
236
+ export declare class PeriodSpendLimitError extends Error {
237
+ name: string;
238
+ }
120
239
  //# sourceMappingURL=sponsoredTransactions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sponsoredTransactions.d.ts","sourceRoot":"","sources":["../../../src/db/tables/sponsoredTransactions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAqB,UAAU,EAAE,MAAM,QAAQ,CAAA;AAI3D,OAAO,KAAK,KAAK,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,KAAK,KAAK,SAAS,MAAM,cAAc,CAAA;AAE9C,iGAAiG;AACjG,MAAM,MAAM,KAAK,GAAG,SAAS,CAAC,oBAAoB,CAAA;AAElD,0CAA0C;AAC1C,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;AAEtC;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAoC5E;AAED,MAAM,CAAC,OAAO,WAAW,MAAM,CAAC;IAC9B,mEAAmE;IACnE,KAAK,KAAK,GAAG;QACX,uDAAuD;QACvD,QAAQ,EAAE,MAAM,CAAA;QAChB,yEAAyE;QACzE,QAAQ,EAAE,OAAO,CAAA;QACjB,+CAA+C;QAC/C,OAAO,EAAE,MAAM,CAAA;QACf,2DAA2D;QAC3D,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,CAAA;QACjC,sDAAsD;QACtD,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;QAC7B,yDAAyD;QACzD,KAAK,EAAE,MAAM,CAAA;QACb,oDAAoD;QACpD,SAAS,EAAE,MAAM,CAAA;QACjB,6EAA6E;QAC7E,WAAW,EAAE,MAAM,CAAA;QACnB,qFAAqF;QACrF,WAAW,EAAE,MAAM,CAAA;QACnB,kFAAkF;QAClF,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KACrC,CAAA;CACF;AAED;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAMtE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,GAAE,WAAW,CAAC,OAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAU3F;AAED,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,uCAAuC;IACvC,KAAK,OAAO,GAAG;QACb,8BAA8B;QAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,CAAA;CACF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,OAAO,GAAE,WAAW,CAAC,OAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAY3F;AAED,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC;IACnC,uCAAuC;IACvC,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,GAAG;QACnC,yFAAyF;QACzF,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KACjC,CAAA;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,EAAE,CAAC,EAAE,EACT,EAAE,EAAE,MAAM,EACV,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1F;AAED,MAAM,CAAC,OAAO,WAAW,QAAQ,CAAC;IAChC,uDAAuD;IACvD,KAAK,KAAK,GAAG;QACX,+CAA+C;QAC/C,SAAS,EAAE,MAAM,CAAA;QACjB,iDAAiD;QACjD,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOpF"}
1
+ {"version":3,"file":"sponsoredTransactions.d.ts","sourceRoot":"","sources":["../../../src/db/tables/sponsoredTransactions.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { sql } from 'kysely';
2
- import { nanoid } from 'nanoid';
2
+ import * as Id from '../../internal/Id.js';
3
3
  /**
4
4
  * Records one sponsorship commitment as `pending`, keyed by its fee-payer
5
5
  * sign payload. Written after fee-payer signing and before any broadcast, so
@@ -17,11 +17,14 @@ export async function upsert(db, input) {
17
17
  billable: input.billable,
18
18
  chainId: input.chainId,
19
19
  createdAt: new Date().toISOString(),
20
+ currency: input.currency ?? null,
20
21
  environment: input.environment,
21
22
  feeAmount: null,
23
+ feeMax: input.feeMax ?? null,
22
24
  feeToken: input.feeToken ?? null,
23
25
  finalizedAt: null,
24
- id: `stx_${nanoid()}`,
26
+ id: Id.generate('stx'),
27
+ meterReportedAt: null,
25
28
  orgId: input.orgId,
26
29
  projectId: input.projectId,
27
30
  signPayload: input.signPayload,
@@ -33,6 +36,9 @@ export async function upsert(db, input) {
33
36
  .insertInto('sponsored_transactions')
34
37
  .values(record)
35
38
  .onConflict((oc) => oc.column('signPayload').doUpdateSet((eb) => ({
39
+ // Same sign payload = same envelope = same cap; only fills older nulls.
40
+ currency: eb.fn.coalesce(eb.ref('sponsored_transactions.currency'), eb.ref('excluded.currency')), // prettier-ignore
41
+ feeMax: eb.fn.coalesce(eb.ref('sponsored_transactions.feeMax'), eb.ref('excluded.feeMax')),
36
42
  // A raw submission fills the intent's hash; a duplicate intent never
37
43
  // clears an already-known hash.
38
44
  transactionHash: eb.fn.coalesce(eb.ref('excluded.transactionHash'), eb.ref('sponsored_transactions.transactionHash')),
@@ -147,6 +153,149 @@ export async function fail(db, id, finalizedAt) {
147
153
  .where('status', '=', 'pending')
148
154
  .execute();
149
155
  }
156
+ /**
157
+ * Records a sponsorship and enforces the period spend limit atomically. A
158
+ * per-org advisory lock serializes concurrent sponsorships so each one's
159
+ * signed cap is counted before the limit check; without it a burst reads
160
+ * pre-burst spend and overshoots. Throws {@link PeriodSpendLimitError} (rolling
161
+ * back the row) when the limit would be exceeded.
162
+ *
163
+ * @param db - The database (primary; never a cached replica).
164
+ * @param input - The sponsorship to record.
165
+ * @param limit - The period spend limit to enforce.
166
+ * @returns The stored record.
167
+ */
168
+ export async function reserve(db, input, limit) {
169
+ return db.transaction(async (tx) => {
170
+ // `hashtext` maps the org id into the advisory-lock keyspace; the class
171
+ // namespaces it against other advisory-lock users. Released at tx end.
172
+ await sql `select pg_advisory_xact_lock(${billingLockClass}, hashtext(${input.orgId}))`.execute(tx.kysely); // prettier-ignore
173
+ const record = await upsert(tx, input);
174
+ if (record.billable) {
175
+ const committed = await spend(tx, {
176
+ chainIds: limit.chainIds,
177
+ orgId: input.orgId,
178
+ since: limit.since,
179
+ });
180
+ if (committed > limit.max)
181
+ throw new PeriodSpendLimitError();
182
+ }
183
+ return record;
184
+ });
185
+ }
186
+ /** Advisory-lock class namespacing per-org sponsorship serialization. */
187
+ const billingLockClass = 1112294220;
188
+ /**
189
+ * Billable spend committed since a cutoff, in fee-token base units: finalized
190
+ * rows at their actual fee plus pending rows at their signed fee cap, so
191
+ * in-flight sponsorships consume limit budget until receipts land.
192
+ *
193
+ * @param db - The database.
194
+ * @param options - Aggregation scope.
195
+ * @returns The committed spend in base units.
196
+ */
197
+ export async function spend(db, options) {
198
+ const { chainIds, environment = 'production', orgId, since } = options;
199
+ const query = db.kysely
200
+ .selectFrom('sponsored_transactions')
201
+ .select([
202
+ sql `coalesce(sum(case when status = 'finalized' then fee_amount::numeric else 0 end), 0)`.as('finalized'), // prettier-ignore
203
+ sql `coalesce(sum(case when status = 'pending' then fee_max::numeric else 0 end), 0)`.as('pending'), // prettier-ignore
204
+ ])
205
+ .where('orgId', '=', orgId)
206
+ .where('environment', '=', environment)
207
+ // Redundant with the CASE arms, but lets the billing index's
208
+ // (org_id, status, created_at) shape serve the range scan.
209
+ .where('status', 'in', ['finalized', 'pending'])
210
+ .where('chainId', 'in', [...chainIds])
211
+ .where('createdAt', '>=', since);
212
+ // Production mirrors the sponsorship gate — only billable rows count. Sandbox
213
+ // rows are non-billable by construction, so the figure is display-only.
214
+ const row = await (environment === 'production' ? query.where('billable', '=', true) : query) //
215
+ .executeTakeFirstOrThrow();
216
+ return BigInt(row.finalized) + BigInt(row.pending);
217
+ }
218
+ /**
219
+ * Sponsorship usage bucketed by time for one organization: row counts and
220
+ * committed fees per bucket. Fee semantics mirror {@link spend}: finalized
221
+ * rows at their actual fee, pending rows at their signed cap, failed rows at
222
+ * zero. Buckets with no rows are omitted.
223
+ *
224
+ * @param db - The database.
225
+ * @param options - Aggregation scope.
226
+ * @returns Time-ordered usage buckets.
227
+ */
228
+ export async function usage(db, options) {
229
+ // TODO: convert to an OLAP-friendly approach (rollup table or columnar store)
230
+ // when per-org range scans grow slow.
231
+ const { environment, from, interval, orgId, projectId, to } = options;
232
+ // `sql.lit` inlines the enum-validated interval so the GROUP BY expression
233
+ // matches the SELECT expression textually; truncation happens in UTC wall
234
+ // time regardless of the session time zone.
235
+ const bucket = sql `date_trunc(${sql.lit(interval)}, (created_at::timestamptz) at time zone 'UTC')`;
236
+ let query = db.kysely
237
+ .selectFrom('sponsored_transactions')
238
+ .select([
239
+ sql `to_char(${bucket}, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')`.as('timestamp'),
240
+ sql `count(*)`.as('count'),
241
+ sql `coalesce(sum(case when status = 'finalized' then fee_amount::numeric when status = 'pending' then fee_max::numeric else 0 end), 0)`.as('feeTotal'), // prettier-ignore
242
+ ])
243
+ .where('orgId', '=', orgId)
244
+ // Text-range bounds keep the (org_id, created_at) index serving the scan.
245
+ .where('createdAt', '>=', from)
246
+ .where('createdAt', '<', to)
247
+ .groupBy(bucket)
248
+ .orderBy(bucket);
249
+ if (environment !== undefined)
250
+ query = query.where('environment', '=', environment);
251
+ if (projectId !== undefined)
252
+ query = query.where('projectId', '=', projectId);
253
+ const rows = await query.execute();
254
+ return rows.map((row) => ({
255
+ count: Number(row.count),
256
+ feeTotal: BigInt(row.feeTotal),
257
+ timestamp: row.timestamp,
258
+ }));
259
+ }
260
+ /**
261
+ * Lists finalized billable rows not yet reported to the billing meter, oldest
262
+ * first, for the metering job.
263
+ *
264
+ * @param db - The database.
265
+ * @param options - Reporting scope.
266
+ * @returns The unreported records.
267
+ */
268
+ export function listUnreported(db, options) {
269
+ let query = db.kysely
270
+ .selectFrom('sponsored_transactions')
271
+ .selectAll()
272
+ .where('status', '=', 'finalized')
273
+ .where('billable', '=', true)
274
+ .where('chainId', 'in', [...options.chainIds])
275
+ .where('meterReportedAt', 'is', null)
276
+ // `id` breaks same-millisecond `finalizedAt` ties for a deterministic scan.
277
+ .orderBy('finalizedAt', 'asc')
278
+ .orderBy('id', 'asc');
279
+ if (options.limit !== undefined)
280
+ query = query.limit(options.limit);
281
+ return query.execute();
282
+ }
283
+ /**
284
+ * Marks a row as reported to the billing meter. A no-op once marked — the
285
+ * durable exactly-once guard for the metering job.
286
+ *
287
+ * @param db - The database.
288
+ * @param id - The sponsored-transaction id (`stx_…`).
289
+ * @param at - When the report was acknowledged (ISO 8601).
290
+ */
291
+ export async function markReported(db, id, at) {
292
+ await db.kysely
293
+ .updateTable('sponsored_transactions')
294
+ .set({ meterReportedAt: at })
295
+ .where('id', '=', id)
296
+ .where('meterReportedAt', 'is', null)
297
+ .execute();
298
+ }
150
299
  /** Intent status predicate; failed rows are recovery candidates only briefly. */
151
300
  function intentStatus(failedSince) {
152
301
  return (eb) => {
@@ -158,4 +307,8 @@ function intentStatus(failedSince) {
158
307
  ]);
159
308
  };
160
309
  }
310
+ /** Thrown by {@link reserve} when recording would exceed the org's period spend limit. */
311
+ export class PeriodSpendLimitError extends Error {
312
+ name = 'SponsoredTransactions.PeriodSpendLimitError';
313
+ }
161
314
  //# sourceMappingURL=sponsoredTransactions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sponsoredTransactions.js","sourceRoot":"","sources":["../../../src/db/tables/sponsoredTransactions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sponsoredTransactions.js","sourceRoot":"","sources":["../../../src/db/tables/sponsoredTransactions.ts"],"names":[],"mappings":"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"}