tapimo 0.15.1 → 0.18.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 (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -1,14 +1,14 @@
1
1
  import { nanoid } from 'nanoid'
2
2
 
3
+ import * as TestApp from '../../../test/App.js'
3
4
  import * as Runtime from '../../../test/runtime.js'
4
5
  import * as Db from '../Db.js'
6
+ import * as ApiKeyOwnerTombstones from './apiKeyOwnerTombstones.js'
5
7
  import * as Organizations from './organizations.js'
6
8
  import * as Projects from './projects.js'
7
9
  import * as SponsorshipAttributions from './sponsorshipAttributions.js'
8
10
  import * as SponsoredTransactions from './sponsoredTransactions.js'
9
11
 
10
- const create = () => Db.postgres({ connectionString: Runtime.postgresUrl, schema: `t_${nanoid()}` })
11
-
12
12
  /** Baseline insert input; tests override per case. */
13
13
  const input = {
14
14
  apiKeyId: 'key_1',
@@ -33,9 +33,22 @@ function redact(record: SponsoredTransactions.Record) {
33
33
  }
34
34
 
35
35
  describe('upsert', () => {
36
+ test('behavior: a deleted organization cannot reopen a non-billable commitment', async () => {
37
+ const db = TestApp.database()
38
+ await Organizations.create(db, { id: input.orgId, name: 'One' })
39
+ const row = await SponsoredTransactions.upsert(db, { ...input, billable: false })
40
+ await SponsoredTransactions.fail(db, row.id, new Date().toISOString())
41
+ await db.transaction((tx) => ApiKeyOwnerTombstones.markDeleted(tx, { orgId: input.orgId }))
42
+
43
+ await expect(SponsoredTransactions.upsert(db, input)).rejects.toThrow(
44
+ SponsoredTransactions.OrganizationDeletedError,
45
+ )
46
+ expect((await SponsoredTransactions.get(db, row.id))?.status).toMatchInlineSnapshot(`"failed"`)
47
+ await db.close()
48
+ })
49
+
36
50
  test('behavior: records a pending sponsorship with a generated id', async () => {
37
- const db = create()
38
- await db.migrate()
51
+ const db = TestApp.database()
39
52
  const record = await SponsoredTransactions.upsert(db, input)
40
53
  expect(record.id).toMatch(/^stx_/)
41
54
  expect(redact(record)).toMatchInlineSnapshot(`
@@ -52,6 +65,8 @@ describe('upsert', () => {
52
65
  "finalizationAttemptedAt": null,
53
66
  "finalizedAt": null,
54
67
  "id": "stx_<id>",
68
+ "meterEventFirstAttemptedAt": null,
69
+ "meterReportAttemptedAt": null,
55
70
  "meterReportedAt": null,
56
71
  "orgId": "org_1",
57
72
  "projectId": "prj_1",
@@ -60,6 +75,7 @@ describe('upsert', () => {
60
75
  "status": "pending",
61
76
  "transaction": "0x76cccccccccccccccccccccccccccccccc",
62
77
  "transactionHash": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
78
+ "transactionHashReconciled": false,
63
79
  }
64
80
  `)
65
81
  expect(await SponsoredTransactions.get(db, record.id)).toStrictEqual(record)
@@ -67,8 +83,7 @@ describe('upsert', () => {
67
83
  })
68
84
 
69
85
  test('behavior: records organization-level sponsorship without a project', async () => {
70
- const db = create()
71
- await db.migrate()
86
+ const db = TestApp.database()
72
87
  const { projectId: _, ...organization } = input
73
88
  const record = await SponsoredTransactions.upsert(db, organization)
74
89
 
@@ -78,16 +93,14 @@ describe('upsert', () => {
78
93
  })
79
94
 
80
95
  test('behavior: preserves an explicit fee token', async () => {
81
- const db = create()
82
- await db.migrate()
96
+ const db = TestApp.database()
83
97
  const record = await SponsoredTransactions.upsert(db, { ...input, feeToken: `0x${'fe'.repeat(20)}` }) // prettier-ignore
84
98
  expect(record.feeToken).toMatchInlineSnapshot(`"0xfefefefefefefefefefefefefefefefefefefefe"`)
85
99
  await db.close()
86
100
  })
87
101
 
88
102
  test('behavior: records fill intents without a transaction hash', async () => {
89
- const db = create()
90
- await db.migrate()
103
+ const db = TestApp.database()
91
104
  const { transactionHash: _, ...intent } = input
92
105
  const record = await SponsoredTransactions.upsert(db, intent)
93
106
  expect(record.transactionHash).toBeNull()
@@ -96,8 +109,7 @@ describe('upsert', () => {
96
109
  })
97
110
 
98
111
  test('behavior: a raw submission upgrades a fill intent in place', async () => {
99
- const db = create()
100
- await db.migrate()
112
+ const db = TestApp.database()
101
113
  const { transactionHash: _, ...intent } = input
102
114
  const first = await SponsoredTransactions.upsert(db, intent)
103
115
  const second = await SponsoredTransactions.upsert(db, input)
@@ -112,8 +124,7 @@ describe('upsert', () => {
112
124
  })
113
125
 
114
126
  test('behavior: rejects a sign payload already attributed to another org', async () => {
115
- const db = create()
116
- await db.migrate()
127
+ const db = TestApp.database()
117
128
  const first = await SponsoredTransactions.upsert(db, input)
118
129
 
119
130
  await expect(
@@ -129,8 +140,7 @@ describe('upsert', () => {
129
140
  })
130
141
 
131
142
  test('behavior: rejects a sign payload already attributed to another project', async () => {
132
- const db = create()
133
- await db.migrate()
143
+ const db = TestApp.database()
134
144
  const { transactionHash: _, ...intent } = input
135
145
  const first = await SponsoredTransactions.upsert(db, intent)
136
146
 
@@ -143,8 +153,7 @@ describe('upsert', () => {
143
153
  })
144
154
 
145
155
  test('behavior: a raw submission reopens a failed fill intent', async () => {
146
- const db = create()
147
- await db.migrate()
156
+ const db = TestApp.database()
148
157
  const { transactionHash: _, ...intent } = input
149
158
  const first = await SponsoredTransactions.upsert(db, intent)
150
159
  await SponsoredTransactions.fail(db, first.id, '2026-01-01T00:00:00.000Z')
@@ -162,8 +171,7 @@ describe('upsert', () => {
162
171
  })
163
172
 
164
173
  test('behavior: a duplicate intent never clears a known hash', async () => {
165
- const db = create()
166
- await db.migrate()
174
+ const db = TestApp.database()
167
175
  const first = await SponsoredTransactions.upsert(db, input)
168
176
  const { transactionHash: _, ...intent } = input
169
177
  const second = await SponsoredTransactions.upsert(db, intent)
@@ -174,12 +182,50 @@ describe('upsert', () => {
174
182
  )
175
183
  await db.close()
176
184
  })
185
+
186
+ test('behavior: a raw retry never replaces a reconciled hash', async () => {
187
+ const db = TestApp.database()
188
+ const record = await SponsoredTransactions.upsert(db, input)
189
+ const reconciledHash = `0x${'ab'.repeat(32)}`
190
+ await SponsoredTransactions.assignTransactionHash(db, record.id, reconciledHash)
191
+
192
+ const pending = await SponsoredTransactions.upsert(db, input)
193
+ expect(pending.transactionHash).toBe(reconciledHash)
194
+ expect(pending.transactionHashReconciled).toBe(true)
195
+ await SponsoredTransactions.finalize(db, record.id, {
196
+ feeAmount: '1',
197
+ finalizedAt: new Date().toISOString(),
198
+ transactionHash: reconciledHash,
199
+ })
200
+
201
+ expect((await SponsoredTransactions.upsert(db, input)).transactionHash).toBe(reconciledHash)
202
+ await db.close()
203
+ })
204
+
205
+ test('behavior: a raw retry never replaces a legacy finalized hash', async () => {
206
+ const db = TestApp.database()
207
+ const record = await SponsoredTransactions.upsert(db, input)
208
+ await SponsoredTransactions.finalize(db, record.id, {
209
+ feeAmount: '1',
210
+ finalizedAt: new Date().toISOString(),
211
+ })
212
+
213
+ const retried = await SponsoredTransactions.upsert(db, {
214
+ ...input,
215
+ transactionHash: `0x${'ab'.repeat(32)}`,
216
+ })
217
+ expect(retried).toMatchObject({
218
+ status: 'finalized',
219
+ transactionHash: input.transactionHash,
220
+ transactionHashReconciled: false,
221
+ })
222
+ await db.close()
223
+ })
177
224
  })
178
225
 
179
226
  describe('listPending', () => {
180
227
  test('behavior: returns only pending rows, capped by limit', async () => {
181
- const db = create()
182
- await db.migrate()
228
+ const db = TestApp.database()
183
229
  await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b1'.repeat(32)}`, transactionHash: `0x${'a1'.repeat(32)}` }) // prettier-ignore
184
230
  const second = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b2'.repeat(32)}`, transactionHash: `0x${'a2'.repeat(32)}` }) // prettier-ignore
185
231
  await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'b3'.repeat(32)}`, transactionHash: `0x${'a3'.repeat(32)}` }) // prettier-ignore
@@ -204,8 +250,7 @@ describe('listPending', () => {
204
250
 
205
251
  describe('claimPending', () => {
206
252
  test('behavior: rotates through a bounded backlog before retrying rows', async () => {
207
- const db = create()
208
- await db.migrate()
253
+ const db = TestApp.database()
209
254
  for (let index = 1; index <= 5; index++)
210
255
  await SponsoredTransactions.upsert(db, {
211
256
  ...input,
@@ -234,10 +279,9 @@ describe('claimPending', () => {
234
279
  })
235
280
  })
236
281
 
237
- describe('listIntents', () => {
238
- test('behavior: returns active hash-less intents without failed rows', async () => {
239
- const db = create()
240
- await db.migrate()
282
+ describe('listReconciliationCandidates', () => {
283
+ test('behavior: returns pending sponsorships without failed rows', async () => {
284
+ const db = TestApp.database()
241
285
  const { transactionHash: _, ...intent } = input
242
286
  const failed = await SponsoredTransactions.upsert(db, intent)
243
287
  await SponsoredTransactions.fail(db, failed.id, new Date().toISOString())
@@ -245,18 +289,33 @@ describe('listIntents', () => {
245
289
  ...intent,
246
290
  signPayload: `0x${'bc'.repeat(32)}`,
247
291
  })
292
+ const submitted = await SponsoredTransactions.upsert(db, {
293
+ ...input,
294
+ signPayload: `0x${'bd'.repeat(32)}`,
295
+ })
296
+ const confirmed = await SponsoredTransactions.upsert(db, {
297
+ ...input,
298
+ signPayload: `0x${'be'.repeat(32)}`,
299
+ })
300
+ await SponsoredTransactions.assignTransactionHash(db, confirmed.id, input.transactionHash)
248
301
 
249
- expect((await SponsoredTransactions.listIntents(db)).map((record) => record.id)).toStrictEqual([
250
- pending.id,
251
- ])
302
+ expect(
303
+ (await SponsoredTransactions.listReconciliationCandidates(db))
304
+ .map((record) => record.id)
305
+ .sort(),
306
+ ).toStrictEqual([pending.id, submitted.id].sort())
307
+ expect(
308
+ (await SponsoredTransactions.listReconciliationCandidates(db, { limit: 1 })).map(
309
+ (record) => record.transactionHash === null,
310
+ ),
311
+ ).toStrictEqual([true, false])
252
312
  await db.close()
253
313
  })
254
314
  })
255
315
 
256
316
  describe('listRecoveryWindows', () => {
257
317
  test('behavior: returns each chain with its oldest eligible failed intent', async () => {
258
- const db = create()
259
- await db.migrate()
318
+ const db = TestApp.database()
260
319
  const { transactionHash: _, ...intent } = input
261
320
  vi.useFakeTimers({ now: new Date('2026-01-01T00:00:00.000Z') })
262
321
  try {
@@ -293,12 +352,24 @@ describe('listRecoveryWindows', () => {
293
352
  await db.close()
294
353
  }
295
354
  })
355
+
356
+ test('behavior: includes recently failed sponsorships with recorded hashes', async () => {
357
+ const db = TestApp.database()
358
+ const record = await SponsoredTransactions.upsert(db, input)
359
+ await SponsoredTransactions.fail(db, record.id, '2026-01-02T00:00:00.000Z')
360
+
361
+ expect(
362
+ await SponsoredTransactions.listRecoveryWindows(db, {
363
+ failedSince: '2026-01-01T12:00:00.000Z',
364
+ }),
365
+ ).toMatchObject([{ chainId: input.chainId }])
366
+ await db.close()
367
+ })
296
368
  })
297
369
 
298
370
  describe('listRecoverableIntents', () => {
299
371
  test('behavior: returns pending and eligible failed intents matching candidate payloads', async () => {
300
- const db = create()
301
- await db.migrate()
372
+ const db = TestApp.database()
302
373
  const { transactionHash: _, ...intent } = input
303
374
  const pending = await SponsoredTransactions.upsert(db, {
304
375
  ...intent,
@@ -324,12 +395,25 @@ describe('listRecoverableIntents', () => {
324
395
  ).toStrictEqual([eligible.id, pending.id].sort())
325
396
  await db.close()
326
397
  })
398
+
399
+ test('behavior: returns eligible failed sponsorships with recorded hashes', async () => {
400
+ const db = TestApp.database()
401
+ const record = await SponsoredTransactions.upsert(db, input)
402
+ await SponsoredTransactions.fail(db, record.id, '2026-01-02T00:00:00.000Z')
403
+
404
+ expect(
405
+ await SponsoredTransactions.listRecoverableIntents(db, {
406
+ failedSince: '2026-01-01T12:00:00.000Z',
407
+ signPayloads: [record.signPayload],
408
+ }),
409
+ ).toMatchObject([{ id: record.id, transactionHash: input.transactionHash }])
410
+ await db.close()
411
+ })
327
412
  })
328
413
 
329
414
  describe('assignTransactionHash', () => {
330
415
  test('behavior: reopens a failed intent when reconciliation finds its hash', async () => {
331
- const db = create()
332
- await db.migrate()
416
+ const db = TestApp.database()
333
417
  await Organizations.create(db, { id: 'org_1', name: 'One' })
334
418
  const { transactionHash: _, ...intent } = input
335
419
  const record = await SponsoredTransactions.upsert(db, intent)
@@ -346,9 +430,24 @@ describe('assignTransactionHash', () => {
346
430
  await db.close()
347
431
  })
348
432
 
433
+ test('behavior: reopens a failed sponsorship under its mined replacement hash', async () => {
434
+ const db = TestApp.database()
435
+ await Organizations.create(db, { id: 'org_1', name: 'One' })
436
+ const record = await SponsoredTransactions.upsert(db, input)
437
+ await SponsoredTransactions.fail(db, record.id, new Date().toISOString())
438
+ const replacementHash = `0x${'ab'.repeat(32)}`
439
+
440
+ await SponsoredTransactions.assignTransactionHash(db, record.id, replacementHash)
441
+
442
+ expect(await SponsoredTransactions.get(db, record.id)).toMatchObject({
443
+ status: 'pending',
444
+ transactionHash: replacementHash,
445
+ })
446
+ await db.close()
447
+ })
448
+
349
449
  test('behavior: does not reopen failed intents after the recovery window', async () => {
350
- const db = create()
351
- await db.migrate()
450
+ const db = TestApp.database()
352
451
  await Organizations.create(db, { id: 'org_1', name: 'One' })
353
452
  const { transactionHash: _, ...intent } = input
354
453
  const record = await SponsoredTransactions.upsert(db, intent)
@@ -367,8 +466,7 @@ describe('assignTransactionHash', () => {
367
466
  })
368
467
 
369
468
  test('behavior: does not reopen failed intents for deleted orgs', async () => {
370
- const db = create()
371
- await db.migrate()
469
+ const db = TestApp.database()
372
470
  const { transactionHash: _, ...intent } = input
373
471
  const record = await SponsoredTransactions.upsert(db, intent)
374
472
  await SponsoredTransactions.fail(db, record.id, new Date().toISOString())
@@ -382,8 +480,7 @@ describe('assignTransactionHash', () => {
382
480
  })
383
481
 
384
482
  test('behavior: keeps an over-limit failed intent retryable across a period rollover', async () => {
385
- const db = create()
386
- await db.migrate()
483
+ const db = TestApp.database()
387
484
  await Organizations.create(db, { id: 'org_1', name: 'One' })
388
485
  const { transactionHash: _, ...intent } = input
389
486
  vi.useFakeTimers({ now: new Date('2026-01-31T23:59:00.000Z') })
@@ -427,8 +524,7 @@ describe('assignTransactionHash', () => {
427
524
 
428
525
  describe('finalize', () => {
429
526
  test('behavior: transitions pending → finalized with the actual fee', async () => {
430
- const db = create()
431
- await db.migrate()
527
+ const db = TestApp.database()
432
528
  const record = await SponsoredTransactions.upsert(db, input)
433
529
  await SponsoredTransactions.finalize(db, record.id, {
434
530
  feeAmount: '21000',
@@ -441,9 +537,58 @@ describe('finalize', () => {
441
537
  await db.close()
442
538
  })
443
539
 
540
+ test('behavior: stale finalization cannot settle or fail a reconciled hash', async () => {
541
+ const db = TestApp.database()
542
+ const record = await SponsoredTransactions.upsert(db, input)
543
+ const reconciledHash = `0x${'ab'.repeat(32)}`
544
+ await SponsoredTransactions.assignTransactionHash(db, record.id, reconciledHash)
545
+
546
+ await SponsoredTransactions.finalize(db, record.id, {
547
+ feeAmount: '1',
548
+ finalizedAt: new Date().toISOString(),
549
+ transactionHash: input.transactionHash,
550
+ })
551
+ await SponsoredTransactions.fail(db, record.id, new Date().toISOString(), {
552
+ transactionHash: input.transactionHash,
553
+ })
554
+ expect(await SponsoredTransactions.get(db, record.id)).toMatchObject({
555
+ status: 'pending',
556
+ transactionHash: reconciledHash,
557
+ transactionHashReconciled: true,
558
+ })
559
+
560
+ await SponsoredTransactions.finalize(db, record.id, {
561
+ feeAmount: '1',
562
+ finalizedAt: new Date().toISOString(),
563
+ transactionHash: reconciledHash,
564
+ })
565
+ expect((await SponsoredTransactions.get(db, record.id))?.status).toBe('finalized')
566
+ await db.close()
567
+ })
568
+
569
+ test('behavior: a receipt-fenced finalization preserves its hash against raw retries', async () => {
570
+ const db = TestApp.database()
571
+ const record = await SponsoredTransactions.upsert(db, input)
572
+ await SponsoredTransactions.finalize(db, record.id, {
573
+ feeAmount: '1',
574
+ finalizedAt: new Date().toISOString(),
575
+ transactionHash: input.transactionHash,
576
+ })
577
+
578
+ const retried = await SponsoredTransactions.upsert(db, {
579
+ ...input,
580
+ transactionHash: `0x${'ab'.repeat(32)}`,
581
+ })
582
+ expect(retried).toMatchObject({
583
+ status: 'finalized',
584
+ transactionHash: input.transactionHash,
585
+ transactionHashReconciled: true,
586
+ })
587
+ await db.close()
588
+ })
589
+
444
590
  test('behavior: no-op on rows that are no longer pending', async () => {
445
- const db = create()
446
- await db.migrate()
591
+ const db = TestApp.database()
447
592
  const record = await SponsoredTransactions.upsert(db, input)
448
593
  await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
449
594
  await SponsoredTransactions.finalize(db, record.id, {
@@ -459,8 +604,7 @@ describe('finalize', () => {
459
604
 
460
605
  describe('fail', () => {
461
606
  test('behavior: transitions pending → failed without a fee', async () => {
462
- const db = create()
463
- await db.migrate()
607
+ const db = TestApp.database()
464
608
  const record = await SponsoredTransactions.upsert(db, input)
465
609
  await SponsoredTransactions.fail(db, record.id, '2026-01-01T00:00:00.000Z')
466
610
  const failed = await SponsoredTransactions.get(db, record.id)
@@ -473,7 +617,7 @@ describe('fail', () => {
473
617
 
474
618
  describe('migration 0032', () => {
475
619
  test('behavior: rescales legacy attodollar fee amounts idempotently', async () => {
476
- const db = create()
620
+ const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema: `t_${nanoid()}` })
477
621
  await db.migrate()
478
622
  // A pre-scaling row stored raw attodollars: 2.1e18 + 1, non-divisible so
479
623
  // the rescale must round up.
@@ -502,8 +646,7 @@ describe('migration 0032', () => {
502
646
 
503
647
  describe('spend', () => {
504
648
  test('behavior: sums finalized fees plus pending caps within scope', async () => {
505
- const db = create()
506
- await db.migrate()
649
+ const db = TestApp.database()
507
650
  const chainIds = [input.chainId]
508
651
  // Finalized in scope: counts its actual fee, never its cap.
509
652
  const finalized = await SponsoredTransactions.upsert(db, { ...input, feeMax: '900000', signPayload: `0x${'01'.repeat(32)}` }) // prettier-ignore
@@ -529,8 +672,7 @@ describe('spend', () => {
529
672
  })
530
673
 
531
674
  test('behavior: rows created before the window start are out of scope', async () => {
532
- const db = create()
533
- await db.migrate()
675
+ const db = TestApp.database()
534
676
  await SponsoredTransactions.upsert(db, { ...input, feeMax: '250000', signPayload: `0x${'08'.repeat(32)}` }) // prettier-ignore
535
677
  const future = new Date(Date.now() + 60_000).toISOString()
536
678
  expect(await SponsoredTransactions.spend(db, { chainIds: [input.chainId], orgId: 'org_1', since: future })).toBe(0n) // prettier-ignore
@@ -538,8 +680,7 @@ describe('spend', () => {
538
680
  })
539
681
 
540
682
  test('behavior: promotional spend is isolated by project', async () => {
541
- const db = create()
542
- await db.migrate()
683
+ const db = TestApp.database()
543
684
  await SponsoredTransactions.upsert(db, {
544
685
  ...input,
545
686
  billable: false,
@@ -570,8 +711,7 @@ describe('spend', () => {
570
711
 
571
712
  describe('reserve', () => {
572
713
  test('behavior: enforces promotional limits independently per project', async () => {
573
- const db = create()
574
- await db.migrate()
714
+ const db = TestApp.database()
575
715
  const limit = {
576
716
  billable: false,
577
717
  chainIds: [input.chainId],
@@ -627,8 +767,7 @@ describe('reservePromotion', () => {
627
767
  }
628
768
 
629
769
  test('behavior: atomically records the first sponsorship and immutable window', async () => {
630
- const db = create()
631
- await db.migrate()
770
+ const db = TestApp.database()
632
771
  await configure(db, '0.000001')
633
772
  const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
634
773
  const attribution = await SponsorshipAttributions.resolveProject(db, {
@@ -668,8 +807,7 @@ describe('reservePromotion', () => {
668
807
  })
669
808
 
670
809
  test('behavior: records an uncapped promotion', async () => {
671
- const db = create()
672
- await db.migrate()
810
+ const db = TestApp.database()
673
811
  await configure(db, null)
674
812
  const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
675
813
  const attribution = await SponsorshipAttributions.resolveProject(db, {
@@ -720,8 +858,7 @@ describe('reservePromotion', () => {
720
858
  })
721
859
 
722
860
  test('behavior: reads the current organization policy when activating', async () => {
723
- const db = create()
724
- await db.migrate()
861
+ const db = TestApp.database()
725
862
  await configure(db, '0.000001')
726
863
  const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
727
864
  const attribution = await SponsorshipAttributions.resolveProject(db, {
@@ -756,8 +893,7 @@ describe('reservePromotion', () => {
756
893
  })
757
894
 
758
895
  test('behavior: conflicting envelopes do not activate another project', async () => {
759
- const db = create()
760
- await db.migrate()
896
+ const db = TestApp.database()
761
897
  await configure(db, null)
762
898
  const first = await Projects.create(db, { name: 'First', orgId: 'org_1' })
763
899
  const second = await Projects.create(db, { name: 'Second', orgId: 'org_1' })
@@ -790,8 +926,7 @@ describe('reservePromotion', () => {
790
926
  })
791
927
 
792
928
  test('behavior: policy changes preserve unattributed retry snapshots', async () => {
793
- const db = create()
794
- await db.migrate()
929
+ const db = TestApp.database()
795
930
  await configure(db, null)
796
931
  const existing = await SponsoredTransactions.upsert(db, { ...input, billable: true })
797
932
  const attribution = await SponsorshipAttributions.resolveExternal(db, {
@@ -826,8 +961,7 @@ describe('reservePromotion', () => {
826
961
  })
827
962
 
828
963
  test('behavior: later policy changes cannot raise an activated project cap', async () => {
829
- const db = create()
830
- await db.migrate()
964
+ const db = TestApp.database()
831
965
  await configure(db, '0.000001')
832
966
  const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
833
967
  const attribution = await SponsorshipAttributions.resolveProject(db, {
@@ -873,8 +1007,7 @@ describe('reservePromotion', () => {
873
1007
  })
874
1008
 
875
1009
  test('behavior: preserves activation when the first sponsorship exceeds the cap', async () => {
876
- const db = create()
877
- await db.migrate()
1010
+ const db = TestApp.database()
878
1011
  await configure(db, '0')
879
1012
  const project = await Projects.create(db, { name: 'App', orgId: 'org_1' })
880
1013
  const attribution = await SponsorshipAttributions.resolveProject(db, {
@@ -950,8 +1083,7 @@ describe('reservePromotion', () => {
950
1083
 
951
1084
  describe('listUnreported', () => {
952
1085
  test('behavior: lists finalized billable in-scope rows, oldest first', async () => {
953
- const db = create()
954
- await db.migrate()
1086
+ const db = TestApp.database()
955
1087
  const chainIds = [input.chainId]
956
1088
  const first = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'11'.repeat(32)}` }) // prettier-ignore
957
1089
  await SponsoredTransactions.finalize(db, first.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
@@ -980,10 +1112,98 @@ describe('listUnreported', () => {
980
1112
  })
981
1113
  })
982
1114
 
1115
+ describe('claimUnreported', () => {
1116
+ test('reserves retry capacity while untouched sponsorships keep progressing', async () => {
1117
+ const db = TestApp.database()
1118
+ const rows = []
1119
+ for (const [seed, day] of [
1120
+ ['31', 1],
1121
+ ['32', 2],
1122
+ ['33', 3],
1123
+ ['34', 4],
1124
+ ] as const) {
1125
+ const row = await SponsoredTransactions.upsert(db, {
1126
+ ...input,
1127
+ signPayload: `0x${seed.repeat(32)}`,
1128
+ })
1129
+ await SponsoredTransactions.finalize(db, row.id, {
1130
+ feeAmount: '100',
1131
+ finalizedAt: `2026-01-0${day}T00:00:00.000Z`,
1132
+ })
1133
+ rows.push(row)
1134
+ }
1135
+ await SponsoredTransactions.beginMeterEvent(db, rows[0]!.id, '2026-01-02T00:00:00.000Z')
1136
+
1137
+ const first = await SponsoredTransactions.claimUnreported(db, {
1138
+ attemptedAt: '2026-01-03T00:00:00.000Z',
1139
+ limit: 2,
1140
+ })
1141
+ expect(first.map((row) => row.id)).toStrictEqual([rows[0]!.id, rows[1]!.id])
1142
+ const second = await SponsoredTransactions.claimUnreported(db, {
1143
+ attemptedAt: '2026-01-04T00:00:00.000Z',
1144
+ limit: 2,
1145
+ })
1146
+ expect(second.map((row) => row.id)).toStrictEqual([rows[0]!.id, rows[2]!.id])
1147
+ await db.close()
1148
+ })
1149
+
1150
+ test('rotates failed claims behind untouched rows across historical chains', async () => {
1151
+ const db = TestApp.database()
1152
+ const rows = []
1153
+ for (const [seed, chainId, finalizedAt] of [
1154
+ ['21', input.chainId, '2026-01-01T00:00:00.000Z'],
1155
+ ['22', 421700099, '2026-01-02T00:00:00.000Z'],
1156
+ ['23', input.chainId, '2026-01-03T00:00:00.000Z'],
1157
+ ] as const) {
1158
+ const row = await SponsoredTransactions.upsert(db, {
1159
+ ...input,
1160
+ chainId,
1161
+ signPayload: `0x${seed.repeat(32)}`,
1162
+ })
1163
+ await SponsoredTransactions.finalize(db, row.id, { feeAmount: '100', finalizedAt })
1164
+ rows.push(row)
1165
+ }
1166
+
1167
+ for (const [day, expected] of [
1168
+ [4, rows[0]],
1169
+ [5, rows[1]],
1170
+ [6, rows[2]],
1171
+ [7, rows[0]],
1172
+ ] as const) {
1173
+ const attemptedAt = `2026-01-0${day}T00:00:00.000Z`
1174
+ const claimed = await SponsoredTransactions.claimUnreported(db, { attemptedAt, limit: 1 })
1175
+ expect(claimed.map((row) => row.id)).toStrictEqual([expected!.id])
1176
+ expect(claimed[0]?.meterReportAttemptedAt).toBe(attemptedAt)
1177
+ }
1178
+
1179
+ await SponsoredTransactions.markReported(db, rows[0]!.id, '2026-01-08T00:00:00.000Z')
1180
+ const remaining = await SponsoredTransactions.claimUnreported(db, {
1181
+ attemptedAt: '2026-01-08T00:00:00.000Z',
1182
+ limit: 1,
1183
+ })
1184
+ expect(remaining.map((row) => row.id)).toStrictEqual([rows[1]!.id])
1185
+ await db.close()
1186
+ })
1187
+ })
1188
+
983
1189
  describe('markReported', () => {
1190
+ test.each(['pending', 'failed'] as const)(
1191
+ 'behavior: cannot discharge a %s commitment',
1192
+ async (status) => {
1193
+ const db = TestApp.database()
1194
+ const row = await SponsoredTransactions.upsert(db, input)
1195
+ if (status === 'failed')
1196
+ await SponsoredTransactions.fail(db, row.id, new Date().toISOString())
1197
+
1198
+ await SponsoredTransactions.markReported(db, row.id, new Date().toISOString())
1199
+
1200
+ expect((await SponsoredTransactions.get(db, row.id))?.meterReportedAt).toBeNull()
1201
+ await db.close()
1202
+ },
1203
+ )
1204
+
984
1205
  test('behavior: marks once; re-marking never overwrites the first timestamp', async () => {
985
- const db = create()
986
- await db.migrate()
1206
+ const db = TestApp.database()
987
1207
  const record = await SponsoredTransactions.upsert(db, { ...input, signPayload: `0x${'15'.repeat(32)}` }) // prettier-ignore
988
1208
  await SponsoredTransactions.finalize(db, record.id, { feeAmount: '100', finalizedAt: '2026-01-01T00:00:00.000Z' }) // prettier-ignore
989
1209
  await SponsoredTransactions.markReported(db, record.id, '2026-01-02T00:00:00.000Z')
@@ -993,3 +1213,58 @@ describe('markReported', () => {
993
1213
  await db.close()
994
1214
  })
995
1215
  })
1216
+
1217
+ describe.each(['upsert', 'reserve', 'reservePromotion'] as const)('%s deletion fence', (method) => {
1218
+ test('behavior: waits for deletion to commit and rejects the late commitment', async () => {
1219
+ const schema = `t_${nanoid()}`
1220
+ const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
1221
+ const concurrent = Db.postgres({ connectionString: Runtime.postgresUrl, schema })
1222
+ await db.migrate()
1223
+ const locked = Promise.withResolvers<void>()
1224
+ const release = Promise.withResolvers<void>()
1225
+ const deletion = db.transaction(async (tx) => {
1226
+ await ApiKeyOwnerTombstones.markDeleted(tx, { orgId: input.orgId })
1227
+ locked.resolve()
1228
+ await release.promise
1229
+ })
1230
+ await locked.promise
1231
+ const reservation = (() => {
1232
+ if (method === 'reserve')
1233
+ return SponsoredTransactions.reserve(concurrent, input, {
1234
+ chainIds: [input.chainId],
1235
+ max: 1_000n,
1236
+ since: '2026-01-01T00:00:00.000Z',
1237
+ })
1238
+ if (method === 'reservePromotion')
1239
+ return SponsoredTransactions.reservePromotion(
1240
+ concurrent,
1241
+ {
1242
+ ...input,
1243
+ sponsorshipAttributionId: 'sat_1',
1244
+ },
1245
+ {
1246
+ at: new Date().toISOString(),
1247
+ chainIds: [input.chainId],
1248
+ },
1249
+ )
1250
+ return SponsoredTransactions.upsert(concurrent, input)
1251
+ })()
1252
+ try {
1253
+ expect(
1254
+ await Promise.race([
1255
+ reservation.then(
1256
+ () => 'recorded',
1257
+ () => 'rejected',
1258
+ ),
1259
+ new Promise((resolve) => setTimeout(() => resolve('waiting'), 100)),
1260
+ ]),
1261
+ ).toBe('waiting')
1262
+ } finally {
1263
+ release.resolve()
1264
+ }
1265
+ await deletion
1266
+ await expect(reservation).rejects.toThrow(SponsoredTransactions.OrganizationDeletedError)
1267
+ expect(await SponsoredTransactions.listPending(db)).toEqual([])
1268
+ await Promise.all([db.close(), concurrent.close()])
1269
+ })
1270
+ })