tapimo 0.1.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 (520) hide show
  1. package/README.md +57 -16
  2. package/dist/ApiKey.d.ts +4 -1
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +6 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +98 -3
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +150 -1
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +7917 -2315
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +141 -329
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +20 -4
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +23 -4
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/Webhooks.d.ts +2 -2
  19. package/dist/Webhooks.d.ts.map +1 -1
  20. package/dist/Webhooks.js +2 -2
  21. package/dist/Webhooks.js.map +1 -1
  22. package/dist/admin/App.d.ts +203 -120
  23. package/dist/admin/App.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.d.ts +111 -6
  25. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  26. package/dist/admin/apps/api-keys.js +67 -0
  27. package/dist/admin/apps/api-keys.js.map +1 -1
  28. package/dist/admin/apps/scopes.d.ts +12 -1
  29. package/dist/admin/apps/scopes.d.ts.map +1 -1
  30. package/dist/admin/apps/scopes.js +3 -0
  31. package/dist/admin/apps/scopes.js.map +1 -1
  32. package/dist/admin/apps/verified-tokens.d.ts +116 -116
  33. package/dist/admin/apps/verified-tokens.js +1 -1
  34. package/dist/admin/apps/verified-tokens.js.map +1 -1
  35. package/dist/admin/ui.generated.d.ts +1 -1
  36. package/dist/admin/ui.generated.js +13 -13
  37. package/dist/admin/ui.generated.js.map +1 -1
  38. package/dist/analytics/Analytics.d.ts +151 -0
  39. package/dist/analytics/Analytics.d.ts.map +1 -0
  40. package/dist/analytics/Analytics.js +212 -0
  41. package/dist/analytics/Analytics.js.map +1 -0
  42. package/dist/analytics/tables/requestEvents.d.ts +215 -0
  43. package/dist/analytics/tables/requestEvents.d.ts.map +1 -0
  44. package/dist/analytics/tables/requestEvents.js +264 -0
  45. package/dist/analytics/tables/requestEvents.js.map +1 -0
  46. package/dist/apps/data/App.d.ts +19576 -0
  47. package/dist/apps/data/App.d.ts.map +1 -0
  48. package/dist/apps/data/App.js +272 -0
  49. package/dist/apps/data/App.js.map +1 -0
  50. package/dist/apps/data/index.d.ts +3 -0
  51. package/dist/apps/data/index.d.ts.map +1 -0
  52. package/dist/apps/data/index.js +3 -0
  53. package/dist/apps/data/index.js.map +1 -0
  54. package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
  55. package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
  56. package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
  57. package/dist/apps/data/routes/activities.js.map +1 -0
  58. package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
  59. package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
  60. package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
  61. package/dist/apps/data/routes/addresses.js.map +1 -0
  62. package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +4 -4
  63. package/dist/apps/data/routes/balances.d.ts.map +1 -0
  64. package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
  65. package/dist/apps/data/routes/balances.js.map +1 -0
  66. package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
  67. package/dist/apps/data/routes/blocks.d.ts.map +1 -0
  68. package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
  69. package/dist/apps/data/routes/blocks.js.map +1 -0
  70. package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +8 -8
  71. package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
  72. package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
  73. package/dist/apps/data/routes/coingecko.js.map +1 -0
  74. package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +108 -108
  75. package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
  76. package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
  77. package/dist/apps/data/routes/exchanges.js.map +1 -0
  78. package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +39 -39
  79. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
  80. package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
  81. package/dist/apps/data/routes/fee-amm.js.map +1 -0
  82. package/dist/apps/data/routes/funding.d.ts +765 -0
  83. package/dist/apps/data/routes/funding.d.ts.map +1 -0
  84. package/dist/apps/data/routes/funding.js +383 -0
  85. package/dist/apps/data/routes/funding.js.map +1 -0
  86. package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
  87. package/dist/apps/data/routes/indexer.d.ts.map +1 -0
  88. package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
  89. package/dist/apps/data/routes/indexer.js.map +1 -0
  90. package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +49 -49
  91. package/dist/apps/data/routes/receipts.d.ts.map +1 -0
  92. package/dist/apps/{receipts.js → data/routes/receipts.js} +14 -20
  93. package/dist/apps/data/routes/receipts.js.map +1 -0
  94. package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +33 -40
  95. package/dist/apps/data/routes/rpc.d.ts.map +1 -0
  96. package/dist/apps/{rpc.js → data/routes/rpc.js} +35 -7
  97. package/dist/apps/data/routes/rpc.js.map +1 -0
  98. package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +40 -40
  99. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
  100. package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
  101. package/dist/apps/data/routes/tokenlist.js.map +1 -0
  102. package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +468 -468
  103. package/dist/apps/data/routes/tokens.d.ts.map +1 -0
  104. package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
  105. package/dist/apps/data/routes/tokens.js.map +1 -0
  106. package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +304 -304
  107. package/dist/apps/data/routes/transactions.d.ts.map +1 -0
  108. package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
  109. package/dist/apps/data/routes/transactions.js.map +1 -0
  110. package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +62 -62
  111. package/dist/apps/data/routes/transfers.d.ts.map +1 -0
  112. package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
  113. package/dist/apps/data/routes/transfers.js.map +1 -0
  114. package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +6 -6
  115. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
  116. package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
  117. package/dist/apps/data/routes/verified-tokens.js.map +1 -0
  118. package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +17 -17
  119. package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
  120. package/dist/apps/{webhooks.js → data/routes/webhooks.js} +38 -34
  121. package/dist/apps/data/routes/webhooks.js.map +1 -0
  122. package/dist/apps/docs/App.d.ts +29 -0
  123. package/dist/apps/docs/App.d.ts.map +1 -0
  124. package/dist/apps/docs/App.js +54 -0
  125. package/dist/apps/docs/App.js.map +1 -0
  126. package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
  127. package/dist/apps/docs/fonts.d.ts.map +1 -0
  128. package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
  129. package/dist/apps/docs/fonts.js.map +1 -0
  130. package/dist/apps/docs/index.d.ts +2 -0
  131. package/dist/apps/docs/index.d.ts.map +1 -0
  132. package/dist/apps/docs/index.js +2 -0
  133. package/dist/apps/docs/index.js.map +1 -0
  134. package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
  135. package/dist/apps/docs/logo.d.ts.map +1 -0
  136. package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
  137. package/dist/apps/docs/logo.js.map +1 -0
  138. package/dist/apps/docs/reference.d.ts +21 -0
  139. package/dist/apps/docs/reference.d.ts.map +1 -0
  140. package/dist/apps/docs/reference.js +112 -0
  141. package/dist/apps/docs/reference.js.map +1 -0
  142. package/dist/apps/index.d.ts +5 -0
  143. package/dist/apps/index.d.ts.map +1 -0
  144. package/dist/apps/index.js +5 -0
  145. package/dist/apps/index.js.map +1 -0
  146. package/dist/apps/mcp.d.ts +76 -0
  147. package/dist/apps/mcp.d.ts.map +1 -0
  148. package/dist/apps/mcp.js +188 -0
  149. package/dist/apps/mcp.js.map +1 -0
  150. package/dist/apps/metadata.d.ts +7 -0
  151. package/dist/apps/metadata.d.ts.map +1 -0
  152. package/dist/apps/metadata.js +15 -0
  153. package/dist/apps/metadata.js.map +1 -0
  154. package/dist/apps/platform/App.d.ts +5262 -0
  155. package/dist/apps/platform/App.d.ts.map +1 -0
  156. package/dist/apps/platform/App.js +84 -0
  157. package/dist/apps/platform/App.js.map +1 -0
  158. package/dist/apps/platform/Billing.d.ts +279 -0
  159. package/dist/apps/platform/Billing.d.ts.map +1 -0
  160. package/dist/apps/platform/Billing.js +477 -0
  161. package/dist/apps/platform/Billing.js.map +1 -0
  162. package/dist/apps/platform/index.d.ts +3 -0
  163. package/dist/apps/platform/index.d.ts.map +1 -0
  164. package/dist/apps/platform/index.js +3 -0
  165. package/dist/apps/platform/index.js.map +1 -0
  166. package/dist/apps/platform/routes/api-keys.d.ts +973 -0
  167. package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
  168. package/dist/apps/platform/routes/api-keys.js +430 -0
  169. package/dist/apps/platform/routes/api-keys.js.map +1 -0
  170. package/dist/apps/platform/routes/billing.d.ts +1520 -0
  171. package/dist/apps/platform/routes/billing.d.ts.map +1 -0
  172. package/dist/apps/platform/routes/billing.js +795 -0
  173. package/dist/apps/platform/routes/billing.js.map +1 -0
  174. package/dist/apps/platform/routes/invitations.d.ts +851 -0
  175. package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
  176. package/dist/apps/platform/routes/invitations.js +471 -0
  177. package/dist/apps/platform/routes/invitations.js.map +1 -0
  178. package/dist/apps/platform/routes/me.d.ts +95 -0
  179. package/dist/apps/platform/routes/me.d.ts.map +1 -0
  180. package/dist/apps/platform/routes/me.js +81 -0
  181. package/dist/apps/platform/routes/me.js.map +1 -0
  182. package/dist/apps/platform/routes/members.d.ts +554 -0
  183. package/dist/apps/platform/routes/members.d.ts.map +1 -0
  184. package/dist/apps/platform/routes/members.js +251 -0
  185. package/dist/apps/platform/routes/members.js.map +1 -0
  186. package/dist/apps/platform/routes/orgs.d.ts +596 -0
  187. package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
  188. package/dist/apps/platform/routes/orgs.js +276 -0
  189. package/dist/apps/platform/routes/orgs.js.map +1 -0
  190. package/dist/apps/platform/routes/projects.d.ts +740 -0
  191. package/dist/apps/platform/routes/projects.d.ts.map +1 -0
  192. package/dist/apps/platform/routes/projects.js +286 -0
  193. package/dist/apps/platform/routes/projects.js.map +1 -0
  194. package/dist/apps/platform/routes/scopes.d.ts +107 -0
  195. package/dist/apps/platform/routes/scopes.d.ts.map +1 -0
  196. package/dist/apps/platform/routes/scopes.js +66 -0
  197. package/dist/apps/platform/routes/scopes.js.map +1 -0
  198. package/dist/apps/platform/routes/usage.d.ts +588 -0
  199. package/dist/apps/platform/routes/usage.d.ts.map +1 -0
  200. package/dist/apps/platform/routes/usage.js +391 -0
  201. package/dist/apps/platform/routes/usage.js.map +1 -0
  202. package/dist/apps/relay/App.d.ts +44 -0
  203. package/dist/apps/relay/App.d.ts.map +1 -0
  204. package/dist/apps/relay/App.js +211 -0
  205. package/dist/apps/relay/App.js.map +1 -0
  206. package/dist/apps/relay/Sponsorships.d.ts +107 -0
  207. package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
  208. package/dist/apps/relay/Sponsorships.js +194 -0
  209. package/dist/apps/relay/Sponsorships.js.map +1 -0
  210. package/dist/apps/relay/index.d.ts +3 -0
  211. package/dist/apps/relay/index.d.ts.map +1 -0
  212. package/dist/apps/relay/index.js +3 -0
  213. package/dist/apps/relay/index.js.map +1 -0
  214. package/dist/cli/Cli.d.ts +9 -2
  215. package/dist/cli/Cli.d.ts.map +1 -1
  216. package/dist/cli/Cli.js +12 -4
  217. package/dist/cli/Cli.js.map +1 -1
  218. package/dist/cli/commands/admin.d.ts +5 -1
  219. package/dist/cli/commands/admin.d.ts.map +1 -1
  220. package/dist/cli/commands/admin.js +82 -3
  221. package/dist/cli/commands/admin.js.map +1 -1
  222. package/dist/db/Db.d.ts +17 -0
  223. package/dist/db/Db.d.ts.map +1 -1
  224. package/dist/db/Db.js +254 -0
  225. package/dist/db/Db.js.map +1 -1
  226. package/dist/db/Schema.d.ts +159 -0
  227. package/dist/db/Schema.d.ts.map +1 -1
  228. package/dist/db/Schema.js +187 -2
  229. package/dist/db/Schema.js.map +1 -1
  230. package/dist/db/tables/billingSettings.d.ts +55 -0
  231. package/dist/db/tables/billingSettings.d.ts.map +1 -0
  232. package/dist/db/tables/billingSettings.js +70 -0
  233. package/dist/db/tables/billingSettings.js.map +1 -0
  234. package/dist/db/tables/invitations.d.ts +84 -0
  235. package/dist/db/tables/invitations.d.ts.map +1 -0
  236. package/dist/db/tables/invitations.js +165 -0
  237. package/dist/db/tables/invitations.js.map +1 -0
  238. package/dist/db/tables/memberships.d.ts +108 -0
  239. package/dist/db/tables/memberships.d.ts.map +1 -0
  240. package/dist/db/tables/memberships.js +153 -0
  241. package/dist/db/tables/memberships.js.map +1 -0
  242. package/dist/db/tables/organizations.d.ts +48 -0
  243. package/dist/db/tables/organizations.d.ts.map +1 -1
  244. package/dist/db/tables/organizations.js +97 -2
  245. package/dist/db/tables/organizations.js.map +1 -1
  246. package/dist/db/tables/projects.d.ts +65 -0
  247. package/dist/db/tables/projects.d.ts.map +1 -0
  248. package/dist/db/tables/projects.js +75 -0
  249. package/dist/db/tables/projects.js.map +1 -0
  250. package/dist/db/tables/requestUsage.d.ts +121 -0
  251. package/dist/db/tables/requestUsage.d.ts.map +1 -0
  252. package/dist/db/tables/requestUsage.js +150 -0
  253. package/dist/db/tables/requestUsage.js.map +1 -0
  254. package/dist/db/tables/sponsoredTransactions.d.ts +239 -0
  255. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
  256. package/dist/db/tables/sponsoredTransactions.js +314 -0
  257. package/dist/db/tables/sponsoredTransactions.js.map +1 -0
  258. package/dist/db/tables/stripeCustomers.d.ts +81 -0
  259. package/dist/db/tables/stripeCustomers.d.ts.map +1 -0
  260. package/dist/db/tables/stripeCustomers.js +120 -0
  261. package/dist/db/tables/stripeCustomers.js.map +1 -0
  262. package/dist/db/tables/users.d.ts +48 -0
  263. package/dist/db/tables/users.d.ts.map +1 -0
  264. package/dist/db/tables/users.js +65 -0
  265. package/dist/db/tables/users.js.map +1 -0
  266. package/dist/handlers/internal/executionError.d.ts.map +1 -1
  267. package/dist/handlers/internal/executionError.js +2 -0
  268. package/dist/handlers/internal/executionError.js.map +1 -1
  269. package/dist/handlers/internal/multisig.d.ts +2 -6
  270. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  271. package/dist/handlers/internal/multisig.js +11 -36
  272. package/dist/handlers/internal/multisig.js.map +1 -1
  273. package/dist/handlers/internal/sponsorship.d.ts +35 -2
  274. package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
  275. package/dist/handlers/internal/sponsorship.js +53 -14
  276. package/dist/handlers/internal/sponsorship.js.map +1 -1
  277. package/dist/handlers/internal/utils.d.ts +10 -3
  278. package/dist/handlers/internal/utils.d.ts.map +1 -1
  279. package/dist/handlers/internal/utils.js +14 -6
  280. package/dist/handlers/internal/utils.js.map +1 -1
  281. package/dist/handlers/relay.d.ts +6 -2
  282. package/dist/handlers/relay.d.ts.map +1 -1
  283. package/dist/handlers/relay.js +16 -2
  284. package/dist/handlers/relay.js.map +1 -1
  285. package/dist/index.d.ts +1 -0
  286. package/dist/index.d.ts.map +1 -1
  287. package/dist/index.js +1 -0
  288. package/dist/index.js.map +1 -1
  289. package/dist/internal/Auth.d.ts +222 -6
  290. package/dist/internal/Auth.d.ts.map +1 -1
  291. package/dist/internal/Auth.js +625 -74
  292. package/dist/internal/Auth.js.map +1 -1
  293. package/dist/internal/Cache.d.ts.map +1 -1
  294. package/dist/internal/Cache.js +4 -1
  295. package/dist/internal/Cache.js.map +1 -1
  296. package/dist/internal/EdgeCache.d.ts +10 -0
  297. package/dist/internal/EdgeCache.d.ts.map +1 -1
  298. package/dist/internal/EdgeCache.js +39 -8
  299. package/dist/internal/EdgeCache.js.map +1 -1
  300. package/dist/internal/Fees.d.ts +27 -0
  301. package/dist/internal/Fees.d.ts.map +1 -0
  302. package/dist/internal/Fees.js +48 -0
  303. package/dist/internal/Fees.js.map +1 -0
  304. package/dist/internal/FundingRoutes.d.ts +183 -0
  305. package/dist/internal/FundingRoutes.d.ts.map +1 -0
  306. package/dist/internal/FundingRoutes.js +490 -0
  307. package/dist/internal/FundingRoutes.js.map +1 -0
  308. package/dist/internal/Id.d.ts +15 -0
  309. package/dist/internal/Id.d.ts.map +1 -0
  310. package/dist/internal/Id.js +22 -0
  311. package/dist/internal/Id.js.map +1 -0
  312. package/dist/internal/Log.d.ts +9 -3
  313. package/dist/internal/Log.d.ts.map +1 -1
  314. package/dist/internal/Log.js +7 -0
  315. package/dist/internal/Log.js.map +1 -1
  316. package/dist/internal/OpenApi.d.ts +10 -20
  317. package/dist/internal/OpenApi.d.ts.map +1 -1
  318. package/dist/internal/OpenApi.js +8 -58
  319. package/dist/internal/OpenApi.js.map +1 -1
  320. package/dist/internal/RateLimit.d.ts +25 -0
  321. package/dist/internal/RateLimit.d.ts.map +1 -1
  322. package/dist/internal/RateLimit.js +51 -0
  323. package/dist/internal/RateLimit.js.map +1 -1
  324. package/dist/internal/Response.d.ts +1 -1
  325. package/dist/internal/Response.d.ts.map +1 -1
  326. package/dist/internal/Schema.d.ts +8 -0
  327. package/dist/internal/Schema.d.ts.map +1 -1
  328. package/dist/internal/Schema.js +7 -0
  329. package/dist/internal/Schema.js.map +1 -1
  330. package/dist/internal/Store.d.ts +7 -1
  331. package/dist/internal/Store.d.ts.map +1 -1
  332. package/dist/internal/Store.js +16 -2
  333. package/dist/internal/Store.js.map +1 -1
  334. package/dist/internal/Viem.d.ts +84 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Webhooks.d.ts +1 -1
  337. package/dist/internal/Webhooks.d.ts.map +1 -1
  338. package/dist/internal/Webhooks.js +3 -3
  339. package/dist/internal/Webhooks.js.map +1 -1
  340. package/package.json +33 -6
  341. package/src/ApiKey.ts +10 -2
  342. package/src/ApiKeys.test.ts +155 -1
  343. package/src/ApiKeys.ts +203 -1
  344. package/src/App.test.ts +64 -75741
  345. package/src/App.ts +218 -420
  346. package/src/Client.test-d.ts +657 -15
  347. package/src/Scope.ts +26 -4
  348. package/src/Webhooks.ts +2 -2
  349. package/src/admin/apps/api-keys.test.ts +51 -0
  350. package/src/admin/apps/api-keys.ts +84 -0
  351. package/src/admin/apps/scopes.test.ts +11 -1
  352. package/src/admin/apps/scopes.ts +3 -0
  353. package/src/admin/apps/verified-tokens.ts +1 -1
  354. package/src/admin/ui/src/components/Page.tsx +2 -3
  355. package/src/admin/ui/src/routes/__root.tsx +2 -2
  356. package/src/admin/ui/src/routes/api-keys.tsx +2 -2
  357. package/src/admin/ui.generated.ts +13 -13
  358. package/src/analytics/Analytics.test.ts +527 -0
  359. package/src/analytics/Analytics.ts +318 -0
  360. package/src/analytics/tables/requestEvents.ts +523 -0
  361. package/src/apps/composition.test.ts +66 -0
  362. package/src/apps/data/App.test.ts +72 -0
  363. package/src/apps/data/App.ts +330 -0
  364. package/src/apps/data/index.ts +2 -0
  365. package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
  366. package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
  367. package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
  368. package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +2 -2
  369. package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
  370. package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +3 -3
  371. package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
  372. package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
  373. package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
  374. package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +1 -1
  375. package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
  376. package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
  377. package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
  378. package/src/apps/data/routes/funding.test.ts +214 -0
  379. package/src/apps/data/routes/funding.ts +584 -0
  380. package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +26 -5
  381. package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
  382. package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +3 -3
  383. package/src/apps/{receipts.ts → data/routes/receipts.ts} +15 -22
  384. package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +122 -7
  385. package/src/apps/{rpc.ts → data/routes/rpc.ts} +38 -8
  386. package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +3 -3
  387. package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
  388. package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +2 -2
  389. package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
  390. package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +3 -3
  391. package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
  392. package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +2 -2
  393. package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
  394. package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +3 -3
  395. package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
  396. package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +7 -7
  397. package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +50 -43
  398. package/src/apps/docs/App.ts +65 -0
  399. package/src/apps/docs/index.ts +1 -0
  400. package/src/apps/docs/reference.ts +132 -0
  401. package/src/apps/index.ts +4 -0
  402. package/src/apps/mcp.test.ts +206 -0
  403. package/src/apps/mcp.ts +250 -0
  404. package/src/apps/metadata.ts +23 -0
  405. package/src/apps/platform/App.ts +169 -0
  406. package/src/apps/platform/Billing.test.ts +530 -0
  407. package/src/apps/platform/Billing.ts +682 -0
  408. package/src/apps/platform/index.ts +2 -0
  409. package/src/apps/platform/routes/api-keys.test.ts +493 -0
  410. package/src/apps/platform/routes/api-keys.ts +543 -0
  411. package/src/apps/platform/routes/billing.test.ts +1100 -0
  412. package/src/apps/platform/routes/billing.ts +966 -0
  413. package/src/apps/platform/routes/invitations.test.ts +409 -0
  414. package/src/apps/platform/routes/invitations.ts +587 -0
  415. package/src/apps/platform/routes/me.test.ts +351 -0
  416. package/src/apps/platform/routes/me.ts +106 -0
  417. package/src/apps/platform/routes/members.test.ts +195 -0
  418. package/src/apps/platform/routes/members.ts +313 -0
  419. package/src/apps/platform/routes/orgs.test.ts +313 -0
  420. package/src/apps/platform/routes/orgs.ts +365 -0
  421. package/src/apps/platform/routes/projects.test.ts +181 -0
  422. package/src/apps/platform/routes/projects.ts +367 -0
  423. package/src/apps/platform/routes/scopes.test.ts +29 -0
  424. package/src/apps/platform/routes/scopes.ts +85 -0
  425. package/src/apps/platform/routes/usage.test.ts +422 -0
  426. package/src/apps/platform/routes/usage.ts +527 -0
  427. package/src/apps/relay/App.test.ts +933 -0
  428. package/src/apps/relay/App.ts +236 -0
  429. package/src/apps/relay/Sponsorships.test.ts +375 -0
  430. package/src/apps/relay/Sponsorships.ts +306 -0
  431. package/src/apps/relay/index.ts +2 -0
  432. package/src/cli/Cli.test.ts +25 -2
  433. package/src/cli/Cli.ts +18 -3
  434. package/src/cli/commands/admin.test.ts +83 -0
  435. package/src/cli/commands/admin.ts +91 -3
  436. package/src/db/Db.ts +296 -0
  437. package/src/db/Schema.ts +241 -2
  438. package/src/db/tables/billingSettings.test.ts +87 -0
  439. package/src/db/tables/billingSettings.ts +108 -0
  440. package/src/db/tables/invitations.ts +198 -0
  441. package/src/db/tables/memberships.ts +208 -0
  442. package/src/db/tables/organizations.test.ts +38 -2
  443. package/src/db/tables/organizations.ts +117 -2
  444. package/src/db/tables/projects.ts +107 -0
  445. package/src/db/tables/requestUsage.ts +231 -0
  446. package/src/db/tables/sponsoredTransactions.test.ts +325 -0
  447. package/src/db/tables/sponsoredTransactions.ts +464 -0
  448. package/src/db/tables/stripeCustomers.test.ts +109 -0
  449. package/src/db/tables/stripeCustomers.ts +162 -0
  450. package/src/db/tables/users.ts +85 -0
  451. package/src/handlers/internal/executionError.ts +2 -0
  452. package/src/handlers/internal/multisig.test.ts +84 -10
  453. package/src/handlers/internal/multisig.ts +15 -50
  454. package/src/handlers/internal/sponsorship.ts +106 -20
  455. package/src/handlers/internal/utils.ts +19 -7
  456. package/src/handlers/{internal/relay.localnet.test.ts → relay.test.ts} +2 -2
  457. package/src/handlers/relay.ts +23 -5
  458. package/src/index.ts +1 -0
  459. package/src/internal/Auth.test.ts +491 -25
  460. package/src/internal/Auth.ts +839 -84
  461. package/src/internal/Cache.ts +5 -1
  462. package/src/internal/Cursor.test.ts +3 -2
  463. package/src/internal/EdgeCache.test.ts +27 -4
  464. package/src/internal/EdgeCache.ts +47 -9
  465. package/src/internal/Fees.test.ts +32 -0
  466. package/src/internal/Fees.ts +51 -0
  467. package/src/internal/FundingRoutes.ts +583 -0
  468. package/src/internal/Id.test.ts +17 -0
  469. package/src/internal/Id.ts +24 -0
  470. package/src/internal/Log.test.ts +2 -1
  471. package/src/internal/Log.ts +16 -3
  472. package/src/internal/MetricSink.ts +1 -1
  473. package/src/internal/OpenApi.ts +12 -60
  474. package/src/internal/RateLimit.test.ts +84 -0
  475. package/src/internal/RateLimit.ts +70 -0
  476. package/src/internal/Response.ts +1 -1
  477. package/src/internal/Schema.ts +8 -0
  478. package/src/internal/Store.test.ts +52 -0
  479. package/src/internal/Store.ts +24 -5
  480. package/src/internal/Tidx.local.test.ts +1 -1
  481. package/src/internal/VerifiedTokens.test.ts +1 -1
  482. package/src/internal/WebhookDestination.test.ts +1 -1
  483. package/src/internal/Webhooks.test.ts +7 -7
  484. package/src/internal/Webhooks.ts +4 -4
  485. package/dist/apps/activities.js.map +0 -1
  486. package/dist/apps/addresses.js.map +0 -1
  487. package/dist/apps/balances.d.ts.map +0 -1
  488. package/dist/apps/balances.js.map +0 -1
  489. package/dist/apps/blocks.d.ts.map +0 -1
  490. package/dist/apps/blocks.js.map +0 -1
  491. package/dist/apps/coingecko.d.ts.map +0 -1
  492. package/dist/apps/coingecko.js.map +0 -1
  493. package/dist/apps/exchanges.d.ts.map +0 -1
  494. package/dist/apps/exchanges.js.map +0 -1
  495. package/dist/apps/fee-amm.d.ts.map +0 -1
  496. package/dist/apps/fee-amm.js.map +0 -1
  497. package/dist/apps/indexer.d.ts.map +0 -1
  498. package/dist/apps/indexer.js.map +0 -1
  499. package/dist/apps/receipts.d.ts.map +0 -1
  500. package/dist/apps/receipts.js.map +0 -1
  501. package/dist/apps/rpc.d.ts.map +0 -1
  502. package/dist/apps/rpc.js.map +0 -1
  503. package/dist/apps/tokenlist.d.ts.map +0 -1
  504. package/dist/apps/tokenlist.js.map +0 -1
  505. package/dist/apps/tokens.d.ts.map +0 -1
  506. package/dist/apps/tokens.js.map +0 -1
  507. package/dist/apps/transactions.d.ts.map +0 -1
  508. package/dist/apps/transactions.js.map +0 -1
  509. package/dist/apps/transfers.d.ts.map +0 -1
  510. package/dist/apps/transfers.js.map +0 -1
  511. package/dist/apps/verified-tokens.d.ts.map +0 -1
  512. package/dist/apps/verified-tokens.js.map +0 -1
  513. package/dist/apps/webhooks.js.map +0 -1
  514. package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
  515. package/dist/internal/OpenApi.fonts.js.map +0 -1
  516. package/dist/internal/OpenApi.logo.d.ts.map +0 -1
  517. package/dist/internal/OpenApi.logo.js.map +0 -1
  518. package/src/handlers/internal/multisig.localnet.test.ts +0 -146
  519. /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
  520. /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
@@ -0,0 +1,325 @@
1
+ import { nanoid } from 'nanoid'
2
+
3
+ import { postgresUrl } from '../../../test/containers.js'
4
+ import * as Db from '../Db.js'
5
+ import * as SponsoredTransactions from './sponsoredTransactions.js'
6
+
7
+ const create = () => Db.postgres({ connectionString: postgresUrl, schema: `t_${nanoid()}` })
8
+
9
+ /** Baseline insert input; tests override per case. */
10
+ const input = {
11
+ apiKeyId: 'key_1',
12
+ billable: true,
13
+ chainId: 42431,
14
+ environment: 'production',
15
+ orgId: 'org_1',
16
+ projectId: 'prj_1',
17
+ signPayload: `0x${'bb'.repeat(32)}`,
18
+ transaction: `0x76${'cc'.repeat(16)}`,
19
+ transactionHash: `0x${'aa'.repeat(32)}`,
20
+ } satisfies SponsoredTransactions.upsert.Input
21
+
22
+ /** Redacts nondeterministic row fields (generated nanoid ids, timestamps). */
23
+ function redact(record: SponsoredTransactions.Record) {
24
+ return {
25
+ ...record,
26
+ createdAt: '<timestamp>',
27
+ finalizedAt: record.finalizedAt === null ? null : '<timestamp>',
28
+ id: /^stx_[0-9A-Za-z]{24}$/.test(record.id) ? 'stx_<id>' : record.id,
29
+ }
30
+ }
31
+
32
+ describe('upsert', () => {
33
+ test('behavior: records a pending sponsorship with a generated id', async () => {
34
+ const db = create()
35
+ await db.migrate()
36
+ const record = await SponsoredTransactions.upsert(db, input)
37
+ expect(record.id).toMatch(/^stx_/)
38
+ expect(redact(record)).toMatchInlineSnapshot(`
39
+ {
40
+ "apiKeyId": "key_1",
41
+ "billable": true,
42
+ "chainId": 42431,
43
+ "createdAt": "<timestamp>",
44
+ "currency": null,
45
+ "environment": "production",
46
+ "feeAmount": null,
47
+ "feeMax": null,
48
+ "feeToken": null,
49
+ "finalizedAt": null,
50
+ "id": "stx_<id>",
51
+ "meterReportedAt": null,
52
+ "orgId": "org_1",
53
+ "projectId": "prj_1",
54
+ "signPayload": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
55
+ "status": "pending",
56
+ "transaction": "0x76cccccccccccccccccccccccccccccccc",
57
+ "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
58
+ }
59
+ `)
60
+ expect(await SponsoredTransactions.get(db, record.id)).toStrictEqual(record)
61
+ await db.close()
62
+ })
63
+
64
+ test('behavior: preserves an explicit fee token', async () => {
65
+ const db = create()
66
+ await db.migrate()
67
+ const record = await SponsoredTransactions.upsert(db, { ...input, feeToken: `0x${'fe'.repeat(20)}` }) // prettier-ignore
68
+ expect(record.feeToken).toMatchInlineSnapshot(`"0xfefefefefefefefefefefefefefefefefefefefe"`)
69
+ await db.close()
70
+ })
71
+
72
+ test('behavior: records fill intents without a transaction hash', async () => {
73
+ const db = create()
74
+ await db.migrate()
75
+ const { transactionHash: _, ...intent } = input
76
+ const record = await SponsoredTransactions.upsert(db, intent)
77
+ expect(record.transactionHash).toBeNull()
78
+ expect(record.status).toMatchInlineSnapshot(`"pending"`)
79
+ await db.close()
80
+ })
81
+
82
+ test('behavior: a raw submission upgrades a fill intent in place', async () => {
83
+ const db = create()
84
+ await db.migrate()
85
+ const { transactionHash: _, ...intent } = input
86
+ const first = await SponsoredTransactions.upsert(db, intent)
87
+ const second = await SponsoredTransactions.upsert(db, input)
88
+
89
+ // Same commitment, one row: the raw record fills the intent's hash.
90
+ expect(second.id).toBe(first.id)
91
+ expect(second.transactionHash).toMatchInlineSnapshot(
92
+ `"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"`,
93
+ )
94
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(1)
95
+ await db.close()
96
+ })
97
+
98
+ test('behavior: a raw submission reopens a failed fill intent', async () => {
99
+ const db = create()
100
+ await db.migrate()
101
+ const { transactionHash: _, ...intent } = input
102
+ const first = await SponsoredTransactions.upsert(db, intent)
103
+ await SponsoredTransactions.fail(db, first.id, '2026-01-01T00:00:00.000Z')
104
+
105
+ const second = await SponsoredTransactions.upsert(db, input)
106
+
107
+ expect(second.id).toBe(first.id)
108
+ expect(second.status).toMatchInlineSnapshot(`"pending"`)
109
+ expect(second.finalizedAt).toBeNull()
110
+ expect(second.transactionHash).toMatchInlineSnapshot(
111
+ `"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"`,
112
+ )
113
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(1)
114
+ await db.close()
115
+ })
116
+
117
+ test('behavior: a duplicate intent never clears a known hash', async () => {
118
+ const db = create()
119
+ await db.migrate()
120
+ const first = await SponsoredTransactions.upsert(db, input)
121
+ const { transactionHash: _, ...intent } = input
122
+ const second = await SponsoredTransactions.upsert(db, intent)
123
+
124
+ expect(second.id).toBe(first.id)
125
+ expect(second.transactionHash).toMatchInlineSnapshot(
126
+ `"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"`,
127
+ )
128
+ await db.close()
129
+ })
130
+ })
131
+
132
+ describe('listPending', () => {
133
+ test('behavior: returns only pending rows, capped by limit', async () => {
134
+ const db = create()
135
+ await db.migrate()
136
+ await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b1'.repeat(32)}`, transactionHash: `0x${'a1'.repeat(32)}` }) // prettier-ignore
137
+ const second = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b2'.repeat(32)}`, transactionHash: `0x${'a2'.repeat(32)}` }) // prettier-ignore
138
+ await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b3'.repeat(32)}`, transactionHash: `0x${'a3'.repeat(32)}` }) // prettier-ignore
139
+ await SponsoredTransactions.finalize(db, second.id, {
140
+ feeAmount: '100',
141
+ finalizedAt: new Date().toISOString(),
142
+ })
143
+
144
+ const pending = await SponsoredTransactions.listPending(db)
145
+ // Inserts can share a millisecond, so assert membership, not order.
146
+ expect(pending.map((row) => row.transactionHash).sort()).toMatchInlineSnapshot(`
147
+ [
148
+ "0xa1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1",
149
+ "0xa3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3",
150
+ ]
151
+ `)
152
+ expect(await SponsoredTransactions.listPending(db, { limit: 1 })).toHaveLength(1)
153
+ await db.close()
154
+ })
155
+ })
156
+
157
+ describe('assignTransactionHash', () => {
158
+ test('behavior: reopens a failed intent when reconciliation finds its hash', async () => {
159
+ const db = create()
160
+ await db.migrate()
161
+ const { transactionHash: _, ...intent } = input
162
+ const record = await SponsoredTransactions.upsert(db, intent)
163
+ await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
164
+
165
+ await SponsoredTransactions.assignTransactionHash(db, record.id, input.transactionHash)
166
+
167
+ const assigned = await SponsoredTransactions.get(db, record.id)
168
+ expect(assigned?.status).toMatchInlineSnapshot(`"pending"`)
169
+ expect(assigned?.finalizedAt).toBeNull()
170
+ expect(assigned?.transactionHash).toMatchInlineSnapshot(
171
+ `"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"`,
172
+ )
173
+ await db.close()
174
+ })
175
+ })
176
+
177
+ describe('finalize', () => {
178
+ test('behavior: transitions pending → finalized with the actual fee', async () => {
179
+ const db = create()
180
+ await db.migrate()
181
+ const record = await SponsoredTransactions.upsert(db, input)
182
+ await SponsoredTransactions.finalize(db, record.id, {
183
+ feeAmount: '21000',
184
+ finalizedAt: '2026-01-01T00:00:00.000Z',
185
+ })
186
+ const finalized = await SponsoredTransactions.get(db, record.id)
187
+ expect(finalized?.status).toMatchInlineSnapshot(`"finalized"`)
188
+ expect(finalized?.feeAmount).toMatchInlineSnapshot(`"21000"`)
189
+ expect(finalized?.finalizedAt).toMatchInlineSnapshot(`"2026-01-01T00:00:00.000Z"`)
190
+ await db.close()
191
+ })
192
+
193
+ test('behavior: no-op on rows that are no longer pending', async () => {
194
+ const db = create()
195
+ await db.migrate()
196
+ const record = await SponsoredTransactions.upsert(db, input)
197
+ await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
198
+ await SponsoredTransactions.finalize(db, record.id, {
199
+ feeAmount: '21000',
200
+ finalizedAt: '2026-01-02T00:00:00.000Z',
201
+ })
202
+ const row = await SponsoredTransactions.get(db, record.id)
203
+ expect(row?.status).toMatchInlineSnapshot(`"failed"`)
204
+ expect(row?.feeAmount).toBeNull()
205
+ await db.close()
206
+ })
207
+ })
208
+
209
+ describe('fail', () => {
210
+ test('behavior: transitions pending → failed without a fee', async () => {
211
+ const db = create()
212
+ await db.migrate()
213
+ const record = await SponsoredTransactions.upsert(db, input)
214
+ await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
215
+ const failed = await SponsoredTransactions.get(db, record.id)
216
+ expect(failed?.status).toMatchInlineSnapshot(`"failed"`)
217
+ expect(failed?.feeAmount).toBeNull()
218
+ expect(failed?.finalizedAt).toMatchInlineSnapshot(`"2026-01-01T00:00:00.000Z"`)
219
+ await db.close()
220
+ })
221
+ })
222
+
223
+ describe('migration 0032', () => {
224
+ test('behavior: rescales legacy attodollar fee amounts idempotently', async () => {
225
+ const db = create()
226
+ await db.migrate()
227
+ // A pre-scaling row stored raw attodollars: 2.1e18 + 1, non-divisible so
228
+ // the rescale must round up.
229
+ const legacy = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'31'.repeat(32)}` }) // prettier-ignore
230
+ await SponsoredTransactions.finalize(db, legacy.id, {
231
+ feeAmount: '2100000000000000001',
232
+ finalizedAt: new Date().toISOString(),
233
+ })
234
+ // An already-scaled row sits far below the threshold and stays untouched.
235
+ const scaled = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'32'.repeat(32)}` }) // prettier-ignore
236
+ await SponsoredTransactions.finalize(db, scaled.id, {
237
+ feeAmount: '420000',
238
+ finalizedAt: new Date().toISOString(),
239
+ })
240
+
241
+ const rescale = Db.migrations.find((migration) => migration.name === '0032_sponsored_transactions_fee_amount_rescale') // prettier-ignore
242
+ // Applying twice proves the threshold guard: a re-run never rescales again.
243
+ for (let run = 0; run < 2; run++) {
244
+ await rescale!.up(db.kysely).execute()
245
+ expect((await SponsoredTransactions.get(db, legacy.id))?.feeAmount).toBe('2100001')
246
+ expect((await SponsoredTransactions.get(db, scaled.id))?.feeAmount).toBe('420000')
247
+ }
248
+ await db.close()
249
+ })
250
+ })
251
+
252
+ describe('spend', () => {
253
+ test('behavior: sums finalized fees plus pending caps within scope', async () => {
254
+ const db = create()
255
+ await db.migrate()
256
+ const chainIds = [input.chainId]
257
+ // Finalized in scope: counts its actual fee, never its cap.
258
+ const finalized = await SponsoredTransactions.upsert(db, { ...input, feeMax: '900000', signPayload: `0x${'01'.repeat(32)}` }) // prettier-ignore
259
+ await SponsoredTransactions.finalize(db, finalized.id, {
260
+ feeAmount: '100000',
261
+ finalizedAt: new Date().toISOString(),
262
+ })
263
+ // Pending in scope: counts its signed cap.
264
+ await SponsoredTransactions.upsert(db, { ...input, feeMax: '250000', signPayload: `0x${'02'.repeat(32)}` }) // prettier-ignore
265
+ // Pending without a recorded cap (pre-column row): contributes nothing.
266
+ await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'03'.repeat(32)}` })
267
+ // Failed: out of scope regardless of cap.
268
+ const failed = await SponsoredTransactions.upsert(db, { ...input, feeMax: '700000', signPayload: `0x${'04'.repeat(32)}` }) // prettier-ignore
269
+ await SponsoredTransactions.fail(db, failed.id, new Date().toISOString())
270
+ // Non-billable and foreign-chain rows: out of scope.
271
+ await SponsoredTransactions.upsert(db, { ...input, billable: false, environment: 'sandbox', feeMax: '500000', signPayload: `0x${'05'.repeat(32)}` }) // prettier-ignore
272
+ await SponsoredTransactions.upsert(db, { ...input, chainId: 1337, feeMax: '500000', signPayload: `0x${'06'.repeat(32)}` }) // prettier-ignore
273
+ // Other orgs: out of scope.
274
+ await SponsoredTransactions.upsert(db, { ...input, feeMax: '500000', orgId: 'org_2', signPayload: `0x${'07'.repeat(32)}` }) // prettier-ignore
275
+
276
+ expect(await SponsoredTransactions.spend(db, { chainIds, orgId: 'org_1', since: '2000-01-01T00:00:00.000Z' })).toBe(350000n) // prettier-ignore
277
+ await db.close()
278
+ })
279
+
280
+ test('behavior: rows created before the window start are out of scope', async () => {
281
+ const db = create()
282
+ await db.migrate()
283
+ await SponsoredTransactions.upsert(db, { ...input, feeMax: '250000', signPayload: `0x${'08'.repeat(32)}` }) // prettier-ignore
284
+ const future = new Date(Date.now() + 60_000).toISOString()
285
+ expect(await SponsoredTransactions.spend(db, { chainIds: [input.chainId], orgId: 'org_1', since: future })).toBe(0n) // prettier-ignore
286
+ await db.close()
287
+ })
288
+ })
289
+
290
+ describe('listUnreported', () => {
291
+ test('behavior: lists finalized billable in-scope rows, oldest first', async () => {
292
+ const db = create()
293
+ await db.migrate()
294
+ const chainIds = [input.chainId]
295
+ const first = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'11'.repeat(32)}` }) // prettier-ignore
296
+ await SponsoredTransactions.finalize(db, first.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
297
+ const second = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'12'.repeat(32)}` }) // prettier-ignore
298
+ await SponsoredTransactions.finalize(db, second.id, { feeAmount: '200', finalizedAt: '2026-01-02T00:00:00.000Z' }) // prettier-ignore
299
+ // Pending, sandbox, and foreign-chain rows never report.
300
+ await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'13'.repeat(32)}` })
301
+ await SponsoredTransactions.upsert(db, { ...input, billable: false, environment: 'sandbox', signPayload: `0x${'14'.repeat(32)}` }) // prettier-ignore
302
+
303
+ const rows = await SponsoredTransactions.listUnreported(db, { chainIds })
304
+ expect(rows.map((row) => row.id)).toStrictEqual([first.id, second.id])
305
+
306
+ await SponsoredTransactions.markReported(db, first.id, new Date().toISOString())
307
+ const remaining = await SponsoredTransactions.listUnreported(db, { chainIds })
308
+ expect(remaining.map((row) => row.id)).toStrictEqual([second.id])
309
+ await db.close()
310
+ })
311
+ })
312
+
313
+ describe('markReported', () => {
314
+ test('behavior: marks once; re-marking never overwrites the first timestamp', async () => {
315
+ const db = create()
316
+ await db.migrate()
317
+ const record = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'15'.repeat(32)}` }) // prettier-ignore
318
+ await SponsoredTransactions.finalize(db, record.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
319
+ await SponsoredTransactions.markReported(db, record.id, '2026-01-02T00:00:00.000Z')
320
+ await SponsoredTransactions.markReported(db, record.id, '2026-01-03T00:00:00.000Z')
321
+ const row = await SponsoredTransactions.get(db, record.id)
322
+ expect(row?.meterReportedAt).toMatchInlineSnapshot(`"2026-01-02T00:00:00.000Z"`)
323
+ await db.close()
324
+ })
325
+ })