tapimo 0.14.0 → 0.15.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 (1141) hide show
  1. package/README.md +7 -4
  2. package/dist/ApiKey.js +1 -1
  3. package/dist/ApiKey.js.map +1 -1
  4. package/dist/ApiKeys.d.ts +95 -14
  5. package/dist/ApiKeys.d.ts.map +1 -1
  6. package/dist/ApiKeys.js +360 -49
  7. package/dist/ApiKeys.js.map +1 -1
  8. package/dist/App.d.ts +12457 -10365
  9. package/dist/App.d.ts.map +1 -1
  10. package/dist/App.js +300 -22
  11. package/dist/App.js.map +1 -1
  12. package/dist/Assets.d.ts.map +1 -1
  13. package/dist/Assets.js +2 -1
  14. package/dist/Assets.js.map +1 -1
  15. package/dist/Handler.d.ts +0 -1
  16. package/dist/Handler.d.ts.map +1 -1
  17. package/dist/Handler.js +0 -1
  18. package/dist/Handler.js.map +1 -1
  19. package/dist/Scope.d.ts +13 -5
  20. package/dist/Scope.d.ts.map +1 -1
  21. package/dist/Scope.js +16 -5
  22. package/dist/Scope.js.map +1 -1
  23. package/dist/Webhooks.js +1 -1
  24. package/dist/Webhooks.js.map +1 -1
  25. package/dist/admin/App.d.ts +3057 -549
  26. package/dist/admin/App.d.ts.map +1 -1
  27. package/dist/admin/App.js +26 -5
  28. package/dist/admin/App.js.map +1 -1
  29. package/dist/admin/apps/api-keys.d.ts +159 -7
  30. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  31. package/dist/admin/apps/api-keys.js +95 -43
  32. package/dist/admin/apps/api-keys.js.map +1 -1
  33. package/dist/admin/apps/earn-vaults.d.ts +1398 -0
  34. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  35. package/dist/admin/apps/earn-vaults.js +463 -7
  36. package/dist/admin/apps/earn-vaults.js.map +1 -1
  37. package/dist/admin/apps/organizations.d.ts +267 -15
  38. package/dist/admin/apps/organizations.d.ts.map +1 -1
  39. package/dist/admin/apps/organizations.js +241 -25
  40. package/dist/admin/apps/organizations.js.map +1 -1
  41. package/dist/admin/apps/routes-support.d.ts +95 -0
  42. package/dist/admin/apps/routes-support.d.ts.map +1 -0
  43. package/dist/admin/apps/routes-support.js +151 -0
  44. package/dist/admin/apps/routes-support.js.map +1 -0
  45. package/dist/admin/apps/routes.d.ts +2764 -0
  46. package/dist/admin/apps/routes.d.ts.map +1 -0
  47. package/dist/admin/apps/routes.js +728 -0
  48. package/dist/admin/apps/routes.js.map +1 -0
  49. package/dist/admin/apps/subsidies.d.ts +501 -0
  50. package/dist/admin/apps/subsidies.d.ts.map +1 -0
  51. package/dist/admin/apps/subsidies.js +384 -0
  52. package/dist/admin/apps/subsidies.js.map +1 -0
  53. package/dist/admin/apps/verified-tokens.d.ts +88 -88
  54. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  55. package/dist/admin/apps/verified-tokens.js +3 -3
  56. package/dist/admin/apps/verified-tokens.js.map +1 -1
  57. package/dist/admin/ui.generated.d.ts +1 -1
  58. package/dist/admin/ui.generated.d.ts.map +1 -1
  59. package/dist/admin/ui.generated.js +129 -69
  60. package/dist/admin/ui.generated.js.map +1 -1
  61. package/dist/analytics/Analytics.d.ts +5 -2
  62. package/dist/analytics/Analytics.d.ts.map +1 -1
  63. package/dist/analytics/Analytics.js +31 -1
  64. package/dist/analytics/Analytics.js.map +1 -1
  65. package/dist/analytics/tables/requestEvents.d.ts +2 -1
  66. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  67. package/dist/analytics/tables/requestEvents.js +10 -1
  68. package/dist/analytics/tables/requestEvents.js.map +1 -1
  69. package/dist/analytics/tables/routesLifecycleIntervals.d.ts +72 -0
  70. package/dist/analytics/tables/routesLifecycleIntervals.d.ts.map +1 -0
  71. package/dist/analytics/tables/routesLifecycleIntervals.js +56 -0
  72. package/dist/analytics/tables/routesLifecycleIntervals.js.map +1 -0
  73. package/dist/apps/Zones.d.ts +21 -12526
  74. package/dist/apps/Zones.d.ts.map +1 -1
  75. package/dist/apps/Zones.js +37 -5
  76. package/dist/apps/Zones.js.map +1 -1
  77. package/dist/apps/data/App.d.ts +3971 -2595
  78. package/dist/apps/data/App.d.ts.map +1 -1
  79. package/dist/apps/data/App.js +76 -21
  80. package/dist/apps/data/App.js.map +1 -1
  81. package/dist/apps/data/routes/activities.d.ts +364 -34
  82. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  83. package/dist/apps/data/routes/activities.js +495 -190
  84. package/dist/apps/data/routes/activities.js.map +1 -1
  85. package/dist/apps/data/routes/addresses.d.ts +72 -0
  86. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  87. package/dist/apps/data/routes/blocks.d.ts +37 -37
  88. package/dist/apps/data/routes/coingecko.d.ts.map +1 -1
  89. package/dist/apps/data/routes/coingecko.js +47 -21
  90. package/dist/apps/data/routes/coingecko.js.map +1 -1
  91. package/dist/apps/data/routes/earn.d.ts +1450 -337
  92. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  93. package/dist/apps/data/routes/earn.js +1226 -144
  94. package/dist/apps/data/routes/earn.js.map +1 -1
  95. package/dist/apps/data/routes/fee-amm.d.ts +5 -0
  96. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  97. package/dist/apps/data/routes/fee-amm.js +31 -19
  98. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  99. package/dist/apps/data/routes/indexer.d.ts +125 -0
  100. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  101. package/dist/apps/data/routes/indexer.js +83 -27
  102. package/dist/apps/data/routes/indexer.js.map +1 -1
  103. package/dist/apps/data/routes/rpc.d.ts +507 -33
  104. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  105. package/dist/apps/data/routes/rpc.js +266 -156
  106. package/dist/apps/data/routes/rpc.js.map +1 -1
  107. package/dist/apps/data/routes/tokenlist.d.ts +47 -15
  108. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  109. package/dist/apps/data/routes/tokenlist.js +68 -11
  110. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  111. package/dist/apps/data/routes/tokens.d.ts +2 -0
  112. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  113. package/dist/apps/data/routes/tokens.js +26 -14
  114. package/dist/apps/data/routes/tokens.js.map +1 -1
  115. package/dist/apps/data/routes/transfers.d.ts +28 -12
  116. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  117. package/dist/apps/data/routes/transfers.js +9 -7
  118. package/dist/apps/data/routes/transfers.js.map +1 -1
  119. package/dist/apps/data/routes/valuation.d.ts +30 -30
  120. package/dist/apps/data/routes/verified-tokens.d.ts +9 -9
  121. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
  122. package/dist/apps/data/routes/verified-tokens.js +64 -20
  123. package/dist/apps/data/routes/verified-tokens.js.map +1 -1
  124. package/dist/apps/data/routes/webhooks.d.ts +613 -176
  125. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  126. package/dist/apps/data/routes/webhooks.js +291 -195
  127. package/dist/apps/data/routes/webhooks.js.map +1 -1
  128. package/dist/apps/data/routes/zones.d.ts.map +1 -1
  129. package/dist/apps/data/routes/zones.js +20 -12
  130. package/dist/apps/data/routes/zones.js.map +1 -1
  131. package/dist/apps/docs/reference.js +2 -2
  132. package/dist/apps/docs/reference.js.map +1 -1
  133. package/dist/apps/index.d.ts +1 -1
  134. package/dist/apps/index.d.ts.map +1 -1
  135. package/dist/apps/index.js +1 -1
  136. package/dist/apps/index.js.map +1 -1
  137. package/dist/apps/management/App.d.ts +3763 -3385
  138. package/dist/apps/management/App.d.ts.map +1 -1
  139. package/dist/apps/management/App.js +5 -14
  140. package/dist/apps/management/App.js.map +1 -1
  141. package/dist/apps/management/Billing.d.ts +48 -7
  142. package/dist/apps/management/Billing.d.ts.map +1 -1
  143. package/dist/apps/management/Billing.js +204 -25
  144. package/dist/apps/management/Billing.js.map +1 -1
  145. package/dist/apps/management/routes/api-keys.d.ts +106 -4
  146. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  147. package/dist/apps/management/routes/api-keys.js +43 -15
  148. package/dist/apps/management/routes/api-keys.js.map +1 -1
  149. package/dist/apps/management/routes/billing.d.ts +290 -4
  150. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  151. package/dist/apps/management/routes/billing.js +274 -49
  152. package/dist/apps/management/routes/billing.js.map +1 -1
  153. package/dist/apps/management/routes/faucet.d.ts +6 -6
  154. package/dist/apps/management/routes/faucet.js +1 -1
  155. package/dist/apps/management/routes/faucet.js.map +1 -1
  156. package/dist/apps/management/routes/invitations.d.ts +77 -2
  157. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  158. package/dist/apps/management/routes/invitations.js +117 -13
  159. package/dist/apps/management/routes/invitations.js.map +1 -1
  160. package/dist/apps/management/routes/invite-links.d.ts +4 -4
  161. package/dist/apps/management/routes/me.d.ts.map +1 -1
  162. package/dist/apps/management/routes/me.js +6 -2
  163. package/dist/apps/management/routes/me.js.map +1 -1
  164. package/dist/apps/management/routes/members.d.ts +30 -30
  165. package/dist/apps/management/routes/orgs.d.ts +18 -2
  166. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  167. package/dist/apps/management/routes/orgs.js +52 -12
  168. package/dist/apps/management/routes/orgs.js.map +1 -1
  169. package/dist/apps/management/routes/projects.d.ts +4 -4
  170. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  171. package/dist/apps/management/routes/projects.js +6 -1
  172. package/dist/apps/management/routes/projects.js.map +1 -1
  173. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  174. package/dist/apps/management/routes/scopes.js +4 -1
  175. package/dist/apps/management/routes/scopes.js.map +1 -1
  176. package/dist/apps/management/routes/usage.d.ts +24 -24
  177. package/dist/apps/management/routes/usage.js +21 -4
  178. package/dist/apps/management/routes/usage.js.map +1 -1
  179. package/dist/apps/management/routes/verified-token-requests.d.ts +2 -2
  180. package/dist/apps/management/routes/webhooks.d.ts +280 -214
  181. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  182. package/dist/apps/management/routes/webhooks.js +58 -12
  183. package/dist/apps/management/routes/webhooks.js.map +1 -1
  184. package/dist/apps/mcp.d.ts +1 -1
  185. package/dist/apps/mcp.js +7 -7
  186. package/dist/apps/mcp.js.map +1 -1
  187. package/dist/apps/mpp/App.d.ts.map +1 -1
  188. package/dist/apps/mpp/App.js +35 -7
  189. package/dist/apps/mpp/App.js.map +1 -1
  190. package/dist/apps/mpp/internal/Adapter.d.ts +2 -0
  191. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  192. package/dist/apps/mpp/internal/Adapter.js +30 -1
  193. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  194. package/dist/apps/mpp/internal/Policy.d.ts +22 -4
  195. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  196. package/dist/apps/mpp/internal/Policy.js +24 -6
  197. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  198. package/dist/apps/mpp/internal/Sponsorship.d.ts +3 -0
  199. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  200. package/dist/apps/mpp/internal/Sponsorship.js +6 -3
  201. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  202. package/dist/apps/relay/App.d.ts +2 -0
  203. package/dist/apps/relay/App.d.ts.map +1 -1
  204. package/dist/apps/relay/App.js +134 -75
  205. package/dist/apps/relay/App.js.map +1 -1
  206. package/dist/apps/relay/Sponsorships.d.ts +5 -3
  207. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  208. package/dist/apps/relay/Sponsorships.js +209 -28
  209. package/dist/apps/relay/Sponsorships.js.map +1 -1
  210. package/dist/apps/{funding → routes}/Access.d.ts +4 -4
  211. package/dist/apps/routes/Access.d.ts.map +1 -0
  212. package/dist/apps/{funding → routes}/Access.js +4 -4
  213. package/dist/apps/routes/Access.js.map +1 -0
  214. package/dist/apps/{funding → routes}/App.d.ts +418 -124
  215. package/dist/apps/{funding → routes}/App.d.ts.map +1 -1
  216. package/dist/apps/{funding → routes}/App.js +16 -16
  217. package/dist/apps/routes/App.js.map +1 -0
  218. package/dist/apps/routes/Inventory.d.ts.map +1 -0
  219. package/dist/apps/{funding → routes}/Inventory.js +2 -2
  220. package/dist/apps/routes/Inventory.js.map +1 -0
  221. package/dist/apps/routes/index.d.ts +2 -0
  222. package/dist/apps/routes/index.d.ts.map +1 -0
  223. package/dist/apps/routes/index.js +2 -0
  224. package/dist/apps/routes/index.js.map +1 -0
  225. package/dist/apps/{funding → routes}/routes/chains.d.ts +7 -7
  226. package/dist/apps/routes/routes/chains.d.ts.map +1 -0
  227. package/dist/apps/{funding → routes}/routes/chains.js +25 -25
  228. package/dist/apps/routes/routes/chains.js.map +1 -0
  229. package/dist/apps/{funding → routes}/routes/deposit-addresses.d.ts +107 -43
  230. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -0
  231. package/dist/apps/{funding → routes}/routes/deposit-addresses.js +497 -222
  232. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -0
  233. package/dist/apps/{funding → routes}/routes/providers.d.ts +8 -8
  234. package/dist/apps/routes/routes/providers.d.ts.map +1 -0
  235. package/dist/apps/routes/routes/providers.js +57 -0
  236. package/dist/apps/routes/routes/providers.js.map +1 -0
  237. package/dist/apps/{funding → routes}/routes/quotes.d.ts +19 -16
  238. package/dist/apps/routes/routes/quotes.d.ts.map +1 -0
  239. package/dist/apps/{funding → routes}/routes/quotes.js +55 -38
  240. package/dist/apps/routes/routes/quotes.js.map +1 -0
  241. package/dist/apps/{funding → routes}/routes/transfers.d.ts +379 -74
  242. package/dist/apps/routes/routes/transfers.d.ts.map +1 -0
  243. package/dist/apps/routes/routes/transfers.js +1140 -0
  244. package/dist/apps/routes/routes/transfers.js.map +1 -0
  245. package/dist/cli/Cli.d.ts +30 -0
  246. package/dist/cli/Cli.d.ts.map +1 -1
  247. package/dist/cli/commands/admin.d.ts +36 -0
  248. package/dist/cli/commands/admin.d.ts.map +1 -1
  249. package/dist/cli/commands/admin.js +273 -0
  250. package/dist/cli/commands/admin.js.map +1 -1
  251. package/dist/cloudflare.d.ts +16 -14
  252. package/dist/cloudflare.d.ts.map +1 -1
  253. package/dist/cloudflare.js +26 -21
  254. package/dist/cloudflare.js.map +1 -1
  255. package/dist/db/Db.d.ts +63 -21
  256. package/dist/db/Db.d.ts.map +1 -1
  257. package/dist/db/Db.js +1030 -15
  258. package/dist/db/Db.js.map +1 -1
  259. package/dist/db/Schema.d.ts +780 -133
  260. package/dist/db/Schema.d.ts.map +1 -1
  261. package/dist/db/Schema.js +575 -162
  262. package/dist/db/Schema.js.map +1 -1
  263. package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts +4 -0
  264. package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts.map +1 -0
  265. package/dist/db/tables/apiKeyAdmissionBootstraps.js +2 -0
  266. package/dist/db/tables/apiKeyAdmissionBootstraps.js.map +1 -0
  267. package/dist/db/tables/apiKeyAdmissions.d.ts +73 -0
  268. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -0
  269. package/dist/db/tables/apiKeyAdmissions.js +142 -0
  270. package/dist/db/tables/apiKeyAdmissions.js.map +1 -0
  271. package/dist/db/tables/apiKeyOwnerAdmissions.d.ts +4 -0
  272. package/dist/db/tables/apiKeyOwnerAdmissions.d.ts.map +1 -0
  273. package/dist/db/tables/apiKeyOwnerAdmissions.js +2 -0
  274. package/dist/db/tables/apiKeyOwnerAdmissions.js.map +1 -0
  275. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +20 -0
  276. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -0
  277. package/dist/db/tables/apiKeyOwnerTombstones.js +57 -0
  278. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -0
  279. package/dist/db/tables/apiKeyRevocations.d.ts +21 -0
  280. package/dist/db/tables/apiKeyRevocations.d.ts.map +1 -0
  281. package/dist/db/tables/apiKeyRevocations.js +98 -0
  282. package/dist/db/tables/apiKeyRevocations.js.map +1 -0
  283. package/dist/db/tables/authAccounts.d.ts +47 -0
  284. package/dist/db/tables/authAccounts.d.ts.map +1 -0
  285. package/dist/db/tables/authAccounts.js +72 -0
  286. package/dist/db/tables/authAccounts.js.map +1 -0
  287. package/dist/db/tables/authSessions.d.ts +12 -0
  288. package/dist/db/tables/authSessions.d.ts.map +1 -0
  289. package/dist/db/tables/authSessions.js +2 -0
  290. package/dist/db/tables/authSessions.js.map +1 -0
  291. package/dist/db/tables/authVerifications.d.ts +12 -0
  292. package/dist/db/tables/authVerifications.d.ts.map +1 -0
  293. package/dist/db/tables/authVerifications.js +2 -0
  294. package/dist/db/tables/authVerifications.js.map +1 -0
  295. package/dist/db/tables/invitations.d.ts +17 -1
  296. package/dist/db/tables/invitations.d.ts.map +1 -1
  297. package/dist/db/tables/invitations.js +123 -43
  298. package/dist/db/tables/invitations.js.map +1 -1
  299. package/dist/db/tables/memberships.d.ts +8 -0
  300. package/dist/db/tables/memberships.d.ts.map +1 -1
  301. package/dist/db/tables/memberships.js +51 -2
  302. package/dist/db/tables/memberships.js.map +1 -1
  303. package/dist/db/tables/organizations.d.ts +32 -10
  304. package/dist/db/tables/organizations.d.ts.map +1 -1
  305. package/dist/db/tables/organizations.js +110 -49
  306. package/dist/db/tables/organizations.js.map +1 -1
  307. package/dist/db/tables/projects.d.ts +2 -0
  308. package/dist/db/tables/projects.d.ts.map +1 -1
  309. package/dist/db/tables/projects.js +12 -3
  310. package/dist/db/tables/projects.js.map +1 -1
  311. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  312. package/dist/db/tables/requestUsage.js.map +1 -1
  313. package/dist/db/tables/rewardAccounts.d.ts +86 -0
  314. package/dist/db/tables/rewardAccounts.d.ts.map +1 -0
  315. package/dist/db/tables/rewardAccounts.js +88 -0
  316. package/dist/db/tables/rewardAccounts.js.map +1 -0
  317. package/dist/db/tables/rewardCampaignDistributors.d.ts +36 -0
  318. package/dist/db/tables/rewardCampaignDistributors.d.ts.map +1 -0
  319. package/dist/db/tables/rewardCampaignDistributors.js +30 -0
  320. package/dist/db/tables/rewardCampaignDistributors.js.map +1 -0
  321. package/dist/db/tables/rewardCampaigns.d.ts +171 -0
  322. package/dist/db/tables/rewardCampaigns.d.ts.map +1 -0
  323. package/dist/db/tables/rewardCampaigns.js +392 -0
  324. package/dist/db/tables/rewardCampaigns.js.map +1 -0
  325. package/dist/db/tables/rewardCredits.d.ts +53 -0
  326. package/dist/db/tables/rewardCredits.d.ts.map +1 -0
  327. package/dist/db/tables/rewardCredits.js +63 -0
  328. package/dist/db/tables/rewardCredits.js.map +1 -0
  329. package/dist/db/tables/rewardEligibilityAssociations.d.ts +61 -0
  330. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -0
  331. package/dist/db/tables/rewardEligibilityAssociations.js +103 -0
  332. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -0
  333. package/dist/db/tables/rewardRuns.d.ts +188 -0
  334. package/dist/db/tables/rewardRuns.d.ts.map +1 -0
  335. package/dist/db/tables/rewardRuns.js +278 -0
  336. package/dist/db/tables/rewardRuns.js.map +1 -0
  337. package/dist/db/tables/rewardTransactionAttempts.d.ts +100 -0
  338. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -0
  339. package/dist/db/tables/rewardTransactionAttempts.js +163 -0
  340. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -0
  341. package/dist/db/tables/routesCatalog.d.ts +58 -0
  342. package/dist/db/tables/routesCatalog.d.ts.map +1 -0
  343. package/dist/db/tables/{fundingCatalog.js → routesCatalog.js} +19 -19
  344. package/dist/db/tables/routesCatalog.js.map +1 -0
  345. package/dist/db/tables/routesDepositAddresses.d.ts +476 -0
  346. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -0
  347. package/dist/db/tables/routesDepositAddresses.js +587 -0
  348. package/dist/db/tables/routesDepositAddresses.js.map +1 -0
  349. package/dist/db/tables/{fundingDepositRequestObservations.d.ts → routesDepositRequestObservations.d.ts} +6 -6
  350. package/dist/db/tables/routesDepositRequestObservations.d.ts.map +1 -0
  351. package/dist/db/tables/{fundingDepositRequestObservations.js → routesDepositRequestObservations.js} +6 -6
  352. package/dist/db/tables/routesDepositRequestObservations.js.map +1 -0
  353. package/dist/db/tables/{fundingDeposits.d.ts → routesDeposits.d.ts} +210 -22
  354. package/dist/db/tables/routesDeposits.d.ts.map +1 -0
  355. package/dist/db/tables/routesDeposits.js +576 -0
  356. package/dist/db/tables/routesDeposits.js.map +1 -0
  357. package/dist/db/tables/routesIdempotency.d.ts +166 -0
  358. package/dist/db/tables/routesIdempotency.d.ts.map +1 -0
  359. package/dist/db/tables/routesIdempotency.js +330 -0
  360. package/dist/db/tables/routesIdempotency.js.map +1 -0
  361. package/dist/db/tables/routesSubsidies.d.ts +27 -0
  362. package/dist/db/tables/routesSubsidies.d.ts.map +1 -0
  363. package/dist/db/tables/routesSubsidies.js +45 -0
  364. package/dist/db/tables/routesSubsidies.js.map +1 -0
  365. package/dist/db/tables/{fundingTransferEvents.d.ts → routesTransferEvents.d.ts} +3 -3
  366. package/dist/db/tables/routesTransferEvents.d.ts.map +1 -0
  367. package/dist/db/tables/{fundingTransferEvents.js → routesTransferEvents.js} +3 -3
  368. package/dist/db/tables/routesTransferEvents.js.map +1 -0
  369. package/dist/db/tables/routesTransferSubsidies.d.ts +19 -0
  370. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -0
  371. package/dist/db/tables/routesTransferSubsidies.js +17 -0
  372. package/dist/db/tables/routesTransferSubsidies.js.map +1 -0
  373. package/dist/db/tables/routesTransferSubsidyNonces.d.ts +51 -0
  374. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -0
  375. package/dist/db/tables/routesTransferSubsidyNonces.js +82 -0
  376. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -0
  377. package/dist/db/tables/routesTransferTransactions.d.ts +77 -0
  378. package/dist/db/tables/routesTransferTransactions.d.ts.map +1 -0
  379. package/dist/db/tables/{fundingTransferTransactions.js → routesTransferTransactions.js} +31 -13
  380. package/dist/db/tables/routesTransferTransactions.js.map +1 -0
  381. package/dist/db/tables/routesTransfers.d.ts +319 -0
  382. package/dist/db/tables/routesTransfers.d.ts.map +1 -0
  383. package/dist/db/tables/routesTransfers.js +372 -0
  384. package/dist/db/tables/routesTransfers.js.map +1 -0
  385. package/dist/db/tables/sponsoredTransactions.d.ts +75 -20
  386. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  387. package/dist/db/tables/sponsoredTransactions.js +124 -54
  388. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  389. package/dist/db/tables/sponsorshipAttributions.d.ts +69 -0
  390. package/dist/db/tables/sponsorshipAttributions.d.ts.map +1 -0
  391. package/dist/db/tables/sponsorshipAttributions.js +77 -0
  392. package/dist/db/tables/sponsorshipAttributions.js.map +1 -0
  393. package/dist/db/tables/sponsorshipReconciliationCursors.d.ts +22 -0
  394. package/dist/db/tables/sponsorshipReconciliationCursors.d.ts.map +1 -0
  395. package/dist/db/tables/sponsorshipReconciliationCursors.js +45 -0
  396. package/dist/db/tables/sponsorshipReconciliationCursors.js.map +1 -0
  397. package/dist/db/tables/stripeCustomers.d.ts +11 -0
  398. package/dist/db/tables/stripeCustomers.d.ts.map +1 -1
  399. package/dist/db/tables/stripeCustomers.js +13 -0
  400. package/dist/db/tables/stripeCustomers.js.map +1 -1
  401. package/dist/db/tables/users.d.ts +17 -1
  402. package/dist/db/tables/users.d.ts.map +1 -1
  403. package/dist/db/tables/users.js +47 -2
  404. package/dist/db/tables/users.js.map +1 -1
  405. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  406. package/dist/db/tables/webhookQueueEvents.js +5 -1
  407. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  408. package/dist/db/tables/webhookSubscriptions.d.ts +19 -11
  409. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  410. package/dist/db/tables/webhookSubscriptions.js +45 -13
  411. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  412. package/dist/handlers/internal/executionError.d.ts +2 -2
  413. package/dist/handlers/internal/executionError.d.ts.map +1 -1
  414. package/dist/handlers/internal/executionError.js +1 -2
  415. package/dist/handlers/internal/executionError.js.map +1 -1
  416. package/dist/handlers/internal/multisig.d.ts +4 -232
  417. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  418. package/dist/handlers/internal/multisig.js +11 -537
  419. package/dist/handlers/internal/multisig.js.map +1 -1
  420. package/dist/handlers/internal/sponsorship.d.ts +19 -8
  421. package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
  422. package/dist/handlers/internal/sponsorship.js +13 -9
  423. package/dist/handlers/internal/sponsorship.js.map +1 -1
  424. package/dist/handlers/relay.d.ts +9 -12
  425. package/dist/handlers/relay.d.ts.map +1 -1
  426. package/dist/handlers/relay.js +81 -85
  427. package/dist/handlers/relay.js.map +1 -1
  428. package/dist/index.d.ts +0 -17
  429. package/dist/index.d.ts.map +1 -1
  430. package/dist/index.js +0 -17
  431. package/dist/index.js.map +1 -1
  432. package/dist/internal/AssetResponse.d.ts +12 -0
  433. package/dist/internal/AssetResponse.d.ts.map +1 -0
  434. package/dist/internal/AssetResponse.js +21 -0
  435. package/dist/internal/AssetResponse.js.map +1 -0
  436. package/dist/internal/Auth.d.ts +48 -12
  437. package/dist/internal/Auth.d.ts.map +1 -1
  438. package/dist/internal/Auth.js +603 -175
  439. package/dist/internal/Auth.js.map +1 -1
  440. package/dist/internal/BetterAuth.d.ts +1488 -0
  441. package/dist/internal/BetterAuth.d.ts.map +1 -0
  442. package/dist/internal/BetterAuth.js +253 -0
  443. package/dist/internal/BetterAuth.js.map +1 -0
  444. package/dist/internal/Cache.d.ts +2 -0
  445. package/dist/internal/Cache.d.ts.map +1 -1
  446. package/dist/internal/Cache.js +2 -0
  447. package/dist/internal/Cache.js.map +1 -1
  448. package/dist/internal/EarnRates.d.ts +26 -3
  449. package/dist/internal/EarnRates.d.ts.map +1 -1
  450. package/dist/internal/EarnRates.js +84 -19
  451. package/dist/internal/EarnRates.js.map +1 -1
  452. package/dist/internal/EarnSharePrices.d.ts +120 -0
  453. package/dist/internal/EarnSharePrices.d.ts.map +1 -0
  454. package/dist/internal/EarnSharePrices.js +179 -0
  455. package/dist/internal/EarnSharePrices.js.map +1 -0
  456. package/dist/internal/EarnVaults.d.ts +4 -0
  457. package/dist/internal/EarnVaults.d.ts.map +1 -1
  458. package/dist/internal/EarnVaults.js +27 -10
  459. package/dist/internal/EarnVaults.js.map +1 -1
  460. package/dist/internal/Email.d.ts +37 -0
  461. package/dist/internal/Email.d.ts.map +1 -0
  462. package/dist/internal/Email.js +16 -0
  463. package/dist/internal/Email.js.map +1 -0
  464. package/dist/internal/Log.d.ts +32 -28
  465. package/dist/internal/Log.d.ts.map +1 -1
  466. package/dist/internal/Log.js +18 -11
  467. package/dist/internal/Log.js.map +1 -1
  468. package/dist/internal/MetricSink.d.ts +3 -0
  469. package/dist/internal/MetricSink.d.ts.map +1 -1
  470. package/dist/internal/MetricSink.js +67 -8
  471. package/dist/internal/MetricSink.js.map +1 -1
  472. package/dist/internal/Mpp.d.ts.map +1 -1
  473. package/dist/internal/Mpp.js +20 -25
  474. package/dist/internal/Mpp.js.map +1 -1
  475. package/dist/internal/OpenApi.d.ts +26 -3
  476. package/dist/internal/OpenApi.d.ts.map +1 -1
  477. package/dist/internal/OpenApi.js +25 -10
  478. package/dist/internal/OpenApi.js.map +1 -1
  479. package/dist/internal/Provider.d.ts +1 -1
  480. package/dist/internal/Provider.d.ts.map +1 -1
  481. package/dist/internal/RateLimit.d.ts.map +1 -1
  482. package/dist/internal/RateLimit.js +13 -1
  483. package/dist/internal/RateLimit.js.map +1 -1
  484. package/dist/internal/Store.d.ts +16 -0
  485. package/dist/internal/Store.d.ts.map +1 -1
  486. package/dist/internal/Store.js +59 -8
  487. package/dist/internal/Store.js.map +1 -1
  488. package/dist/internal/Tidx.d.ts +9 -2
  489. package/dist/internal/Tidx.d.ts.map +1 -1
  490. package/dist/internal/Tidx.js +78 -11
  491. package/dist/internal/Tidx.js.map +1 -1
  492. package/dist/internal/Timing.d.ts +26 -0
  493. package/dist/internal/Timing.d.ts.map +1 -1
  494. package/dist/internal/Timing.js +63 -5
  495. package/dist/internal/Timing.js.map +1 -1
  496. package/dist/internal/VercelOidc.d.ts +94 -0
  497. package/dist/internal/VercelOidc.d.ts.map +1 -0
  498. package/dist/internal/VercelOidc.js +128 -0
  499. package/dist/internal/VercelOidc.js.map +1 -0
  500. package/dist/internal/VerifiedTokens.d.ts +2 -8
  501. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  502. package/dist/internal/VerifiedTokens.js +24 -24
  503. package/dist/internal/VerifiedTokens.js.map +1 -1
  504. package/dist/internal/Viem.d.ts +30 -2067
  505. package/dist/internal/Viem.d.ts.map +1 -1
  506. package/dist/internal/Viem.js +167 -17
  507. package/dist/internal/Viem.js.map +1 -1
  508. package/dist/internal/Webhooks.d.ts +12 -4
  509. package/dist/internal/Webhooks.d.ts.map +1 -1
  510. package/dist/internal/Webhooks.js +9 -3
  511. package/dist/internal/Webhooks.js.map +1 -1
  512. package/dist/internal/ZoneRpc.d.ts +7 -0
  513. package/dist/internal/ZoneRpc.d.ts.map +1 -0
  514. package/dist/internal/ZoneRpc.js +49 -0
  515. package/dist/internal/ZoneRpc.js.map +1 -0
  516. package/dist/internal/index.d.ts +3 -1
  517. package/dist/internal/index.d.ts.map +1 -1
  518. package/dist/internal/index.js +3 -1
  519. package/dist/internal/index.js.map +1 -1
  520. package/dist/internal/rewards/Audit.d.ts +88 -0
  521. package/dist/internal/rewards/Audit.d.ts.map +1 -0
  522. package/dist/internal/rewards/Audit.js +134 -0
  523. package/dist/internal/rewards/Audit.js.map +1 -0
  524. package/dist/internal/rewards/Campaigns.d.ts +572 -0
  525. package/dist/internal/rewards/Campaigns.d.ts.map +1 -0
  526. package/dist/internal/rewards/Campaigns.js +531 -0
  527. package/dist/internal/rewards/Campaigns.js.map +1 -0
  528. package/dist/internal/rewards/Credits.d.ts +76 -0
  529. package/dist/internal/rewards/Credits.d.ts.map +1 -0
  530. package/dist/internal/rewards/Credits.js +95 -0
  531. package/dist/internal/rewards/Credits.js.map +1 -0
  532. package/dist/internal/rewards/Events.d.ts +100 -0
  533. package/dist/internal/rewards/Events.d.ts.map +1 -0
  534. package/dist/internal/rewards/Events.js +340 -0
  535. package/dist/internal/rewards/Events.js.map +1 -0
  536. package/dist/internal/rewards/Projection.d.ts +237 -0
  537. package/dist/internal/rewards/Projection.d.ts.map +1 -0
  538. package/dist/internal/rewards/Projection.js +616 -0
  539. package/dist/internal/rewards/Projection.js.map +1 -0
  540. package/dist/internal/rewards/Rates.d.ts +44 -0
  541. package/dist/internal/rewards/Rates.d.ts.map +1 -0
  542. package/dist/internal/rewards/Rates.js +60 -0
  543. package/dist/internal/rewards/Rates.js.map +1 -0
  544. package/dist/internal/rewards/Read.d.ts +158 -0
  545. package/dist/internal/rewards/Read.d.ts.map +1 -0
  546. package/dist/internal/rewards/Read.js +292 -0
  547. package/dist/internal/rewards/Read.js.map +1 -0
  548. package/dist/internal/rewards/Runner.d.ts +164 -0
  549. package/dist/internal/rewards/Runner.d.ts.map +1 -0
  550. package/dist/internal/rewards/Runner.js +1778 -0
  551. package/dist/internal/rewards/Runner.js.map +1 -0
  552. package/dist/internal/rewards/Signer.d.ts +224 -0
  553. package/dist/internal/rewards/Signer.d.ts.map +1 -0
  554. package/dist/internal/rewards/Signer.js +135 -0
  555. package/dist/internal/rewards/Signer.js.map +1 -0
  556. package/dist/internal/rewards/index.d.ts +15 -0
  557. package/dist/internal/rewards/index.d.ts.map +1 -0
  558. package/dist/internal/rewards/index.js +15 -0
  559. package/dist/internal/rewards/index.js.map +1 -0
  560. package/dist/internal/{funding → routes}/Action.d.ts +12 -1
  561. package/dist/internal/routes/Action.d.ts.map +1 -0
  562. package/dist/internal/{funding → routes}/Action.js +17 -9
  563. package/dist/internal/routes/Action.js.map +1 -0
  564. package/dist/internal/{funding → routes}/Catalog.d.ts +20 -20
  565. package/dist/internal/routes/Catalog.d.ts.map +1 -0
  566. package/dist/internal/{funding → routes}/Catalog.js +29 -29
  567. package/dist/internal/routes/Catalog.js.map +1 -0
  568. package/dist/internal/{funding → routes}/Chain.d.ts +10 -10
  569. package/dist/internal/routes/Chain.d.ts.map +1 -0
  570. package/dist/internal/{funding → routes}/Chain.js +3 -3
  571. package/dist/internal/routes/Chain.js.map +1 -0
  572. package/dist/internal/{funding → routes}/Deposit.d.ts +45 -23
  573. package/dist/internal/routes/Deposit.d.ts.map +1 -0
  574. package/dist/internal/{funding → routes}/Deposit.js +60 -27
  575. package/dist/internal/routes/Deposit.js.map +1 -0
  576. package/dist/internal/{funding → routes}/DepositAddress.d.ts +56 -27
  577. package/dist/internal/routes/DepositAddress.d.ts.map +1 -0
  578. package/dist/internal/{funding → routes}/DepositAddress.js +95 -33
  579. package/dist/internal/routes/DepositAddress.js.map +1 -0
  580. package/dist/internal/{funding → routes}/DepositWebhook.d.ts +4 -4
  581. package/dist/internal/routes/DepositWebhook.d.ts.map +1 -0
  582. package/dist/internal/{funding → routes}/DepositWebhook.js +4 -4
  583. package/dist/internal/routes/DepositWebhook.js.map +1 -0
  584. package/dist/internal/routes/Economics.d.ts +25 -0
  585. package/dist/internal/routes/Economics.d.ts.map +1 -0
  586. package/dist/internal/routes/Economics.js +28 -0
  587. package/dist/internal/routes/Economics.js.map +1 -0
  588. package/dist/internal/{funding → routes}/Evidence.d.ts +3 -3
  589. package/dist/internal/routes/Evidence.d.ts.map +1 -0
  590. package/dist/internal/{funding → routes}/Evidence.js +7 -7
  591. package/dist/internal/routes/Evidence.js.map +1 -0
  592. package/dist/internal/routes/Observability.d.ts +154 -0
  593. package/dist/internal/routes/Observability.d.ts.map +1 -0
  594. package/dist/internal/routes/Observability.js +389 -0
  595. package/dist/internal/routes/Observability.js.map +1 -0
  596. package/dist/internal/{funding → routes}/Provider.d.ts +311 -105
  597. package/dist/internal/routes/Provider.d.ts.map +1 -0
  598. package/dist/internal/{funding → routes}/Provider.js +229 -98
  599. package/dist/internal/routes/Provider.js.map +1 -0
  600. package/dist/internal/{funding → routes}/Reconciliation.d.ts +11 -6
  601. package/dist/internal/routes/Reconciliation.d.ts.map +1 -0
  602. package/dist/internal/{funding → routes}/Reconciliation.js +408 -158
  603. package/dist/internal/routes/Reconciliation.js.map +1 -0
  604. package/dist/internal/routes/Route.d.ts +21 -0
  605. package/dist/internal/routes/Route.d.ts.map +1 -0
  606. package/dist/internal/{funding → routes}/Route.js +1 -1
  607. package/dist/internal/routes/Route.js.map +1 -0
  608. package/dist/internal/{funding → routes}/SourceObservation.d.ts +6 -6
  609. package/dist/internal/routes/SourceObservation.d.ts.map +1 -0
  610. package/dist/internal/{funding → routes}/SourceObservation.js +8 -8
  611. package/dist/internal/routes/SourceObservation.js.map +1 -0
  612. package/dist/internal/{funding → routes}/Subsidy.d.ts +48 -3
  613. package/dist/internal/routes/Subsidy.d.ts.map +1 -0
  614. package/dist/internal/{funding → routes}/Subsidy.js +43 -3
  615. package/dist/internal/routes/Subsidy.js.map +1 -0
  616. package/dist/internal/{funding → routes}/Token.d.ts +4 -4
  617. package/dist/internal/routes/Token.d.ts.map +1 -0
  618. package/dist/internal/{funding → routes}/Token.js +3 -3
  619. package/dist/internal/routes/Token.js.map +1 -0
  620. package/dist/internal/{funding → routes}/Transfer.d.ts +241 -46
  621. package/dist/internal/routes/Transfer.d.ts.map +1 -0
  622. package/dist/internal/routes/Transfer.js +728 -0
  623. package/dist/internal/routes/Transfer.js.map +1 -0
  624. package/dist/internal/{funding → routes}/TransferReconciliation.d.ts +13 -10
  625. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -0
  626. package/dist/internal/routes/TransferReconciliation.js +422 -0
  627. package/dist/internal/routes/TransferReconciliation.js.map +1 -0
  628. package/dist/internal/routes/TransferSubsidy.d.ts +201 -0
  629. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -0
  630. package/dist/internal/routes/TransferSubsidy.js +256 -0
  631. package/dist/internal/routes/TransferSubsidy.js.map +1 -0
  632. package/dist/internal/{funding → routes}/TransferWebhook.d.ts +5 -5
  633. package/dist/internal/routes/TransferWebhook.d.ts.map +1 -0
  634. package/dist/internal/{funding → routes}/TransferWebhook.js +3 -3
  635. package/dist/internal/routes/TransferWebhook.js.map +1 -0
  636. package/dist/internal/{funding → routes}/index.d.ts +2 -0
  637. package/dist/internal/routes/index.d.ts.map +1 -0
  638. package/dist/internal/{funding → routes}/index.js +2 -0
  639. package/dist/internal/routes/index.js.map +1 -0
  640. package/dist/internal/{funding → routes}/providers/across.d.ts +4 -4
  641. package/dist/internal/routes/providers/across.d.ts.map +1 -0
  642. package/dist/internal/{funding → routes}/providers/across.js +13 -13
  643. package/dist/internal/routes/providers/across.js.map +1 -0
  644. package/dist/internal/{funding → routes}/providers/relay.d.ts +21 -12
  645. package/dist/internal/routes/providers/relay.d.ts.map +1 -0
  646. package/dist/internal/{funding → routes}/providers/relay.js +194 -110
  647. package/dist/internal/routes/providers/relay.js.map +1 -0
  648. package/dist/internal/{funding → routes}/providers/rhino.d.ts +4 -4
  649. package/dist/internal/routes/providers/rhino.d.ts.map +1 -0
  650. package/dist/internal/{funding → routes}/providers/rhino.js +10 -10
  651. package/dist/internal/routes/providers/rhino.js.map +1 -0
  652. package/dist/internal/{funding → routes}/providers/squid.d.ts +4 -4
  653. package/dist/internal/routes/providers/squid.d.ts.map +1 -0
  654. package/dist/internal/{funding → routes}/providers/squid.js +14 -14
  655. package/dist/internal/routes/providers/squid.js.map +1 -0
  656. package/dist/internal/{funding → routes}/providers/stargate.d.ts +46 -18
  657. package/dist/internal/routes/providers/stargate.d.ts.map +1 -0
  658. package/dist/internal/routes/providers/stargate.js +898 -0
  659. package/dist/internal/routes/providers/stargate.js.map +1 -0
  660. package/dist/internal/{funding → routes}/providers/symbiosis.d.ts +4 -4
  661. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -0
  662. package/dist/internal/{funding → routes}/providers/symbiosis.js +30 -20
  663. package/dist/internal/routes/providers/symbiosis.js.map +1 -0
  664. package/dist/internal/webhookDestinations/slack.js +12 -12
  665. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  666. package/dist/providers/index.d.ts +12 -12
  667. package/dist/providers/index.d.ts.map +1 -1
  668. package/dist/providers/index.js +12 -12
  669. package/dist/providers/index.js.map +1 -1
  670. package/dist/server.d.ts +19 -0
  671. package/dist/server.d.ts.map +1 -0
  672. package/dist/server.js +19 -0
  673. package/dist/server.js.map +1 -0
  674. package/package.json +15 -4
  675. package/src/ApiKey.ts +1 -1
  676. package/src/ApiKeys.test.ts +1033 -3
  677. package/src/ApiKeys.ts +489 -48
  678. package/src/App.test-d.ts +1 -1
  679. package/src/App.test.ts +216 -25
  680. package/src/App.ts +334 -31
  681. package/src/Assets.test.ts +2 -2
  682. package/src/Assets.ts +3 -1
  683. package/src/Auth.test-d.ts +1 -1
  684. package/src/Client.test-d.ts +539 -110
  685. package/src/Handler.ts +0 -1
  686. package/src/OpenApi.contract.test.ts +195 -0
  687. package/src/Scope.ts +17 -5
  688. package/src/Webhooks.ts +1 -1
  689. package/src/admin/App.test.ts +30 -2
  690. package/src/admin/App.ts +42 -6
  691. package/src/admin/apps/api-keys.test.ts +267 -5
  692. package/src/admin/apps/api-keys.ts +100 -50
  693. package/src/admin/apps/earn-vaults.test.ts +158 -0
  694. package/src/admin/apps/earn-vaults.ts +679 -6
  695. package/src/admin/apps/organizations.test.ts +306 -17
  696. package/src/admin/apps/organizations.ts +299 -24
  697. package/src/admin/apps/routes-support.test.ts +200 -0
  698. package/src/admin/apps/routes-support.ts +201 -0
  699. package/src/admin/apps/routes.test.ts +450 -0
  700. package/src/admin/apps/routes.ts +896 -0
  701. package/src/admin/apps/scopes.test.ts +15 -5
  702. package/src/admin/apps/subsidies.test.ts +306 -0
  703. package/src/admin/apps/subsidies.ts +457 -0
  704. package/src/admin/apps/verified-tokens.test.ts +8 -3
  705. package/src/admin/apps/verified-tokens.ts +3 -3
  706. package/src/admin/ui/plugin.ts +1 -2
  707. package/src/admin/ui/src/components/RewardCampaignForm.tsx +1009 -0
  708. package/src/admin/ui/src/lib/config.ts +11 -2
  709. package/src/admin/ui/src/lib/earn-vaults.ts +2 -2
  710. package/src/admin/ui/src/lib/organizations.test.ts +83 -50
  711. package/src/admin/ui/src/lib/organizations.ts +106 -25
  712. package/src/admin/ui/src/lib/query-client.ts +1 -1
  713. package/src/admin/ui/src/lib/reward-campaigns.ts +136 -0
  714. package/src/admin/ui/src/lib/routes.test.ts +88 -0
  715. package/src/admin/ui/src/lib/routes.ts +304 -0
  716. package/src/admin/ui/src/lib/subsidies.ts +75 -0
  717. package/src/admin/ui/src/routeTree.gen.ts +63 -0
  718. package/src/admin/ui/src/routes/__root.tsx +12 -1
  719. package/src/admin/ui/src/routes/api-keys.tsx +196 -84
  720. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +105 -70
  721. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +239 -23
  722. package/src/admin/ui/src/routes/routes.tsx +1615 -0
  723. package/src/admin/ui/src/routes/routes_.support.tsx +248 -0
  724. package/src/admin/ui/src/routes/subsidies.tsx +799 -0
  725. package/src/admin/ui.generated.ts +144 -69
  726. package/src/analytics/Analytics.test.ts +108 -18
  727. package/src/analytics/Analytics.ts +38 -6
  728. package/src/analytics/tables/requestEvents.test.ts +100 -0
  729. package/src/analytics/tables/requestEvents.ts +10 -1
  730. package/src/analytics/tables/routesLifecycleIntervals.ts +140 -0
  731. package/src/apps/Zones.test.ts +15 -0
  732. package/src/apps/Zones.ts +52 -5
  733. package/src/apps/composition.test.ts +68 -60
  734. package/src/apps/data/App.test.ts +154 -2
  735. package/src/apps/data/App.ts +88 -28
  736. package/src/apps/data/routes/activities.test.ts +419 -7
  737. package/src/apps/data/routes/activities.ts +683 -216
  738. package/src/apps/data/routes/balances.test.ts +2 -2
  739. package/src/apps/data/routes/blocks.test.ts +46 -1
  740. package/src/apps/data/routes/coingecko.test.ts +419 -1
  741. package/src/apps/data/routes/coingecko.ts +309 -253
  742. package/src/apps/data/routes/earn.discovery.test.ts +274 -0
  743. package/src/apps/data/routes/earn.test.ts +1294 -17
  744. package/src/apps/data/routes/earn.ts +1838 -321
  745. package/src/apps/data/routes/exchanges.test.ts +12 -15
  746. package/src/apps/data/routes/fee-amm.test.ts +224 -0
  747. package/src/apps/data/routes/fee-amm.ts +191 -160
  748. package/src/apps/data/routes/indexer.test.ts +389 -0
  749. package/src/apps/data/routes/indexer.ts +165 -69
  750. package/src/apps/data/routes/receipts.test.ts +1 -1
  751. package/src/apps/data/routes/rpc.test.ts +352 -8
  752. package/src/apps/data/routes/rpc.ts +407 -219
  753. package/src/apps/data/routes/rpc.zone.test.ts +340 -0
  754. package/src/apps/data/routes/tokenlist.test.ts +285 -0
  755. package/src/apps/data/routes/tokenlist.ts +173 -88
  756. package/src/apps/data/routes/tokens.test.ts +93 -3
  757. package/src/apps/data/routes/tokens.ts +39 -23
  758. package/src/apps/data/routes/transactions.test.ts +1 -1
  759. package/src/apps/data/routes/transfers.test.ts +56 -24
  760. package/src/apps/data/routes/transfers.ts +19 -8
  761. package/src/apps/data/routes/valuation.test.ts +1 -1
  762. package/src/apps/data/routes/verified-tokens.test.ts +345 -0
  763. package/src/apps/data/routes/verified-tokens.ts +99 -29
  764. package/src/apps/data/routes/webhooks.test.ts +645 -83
  765. package/src/apps/data/routes/webhooks.ts +1089 -857
  766. package/src/apps/data/routes/zones.test.ts +148 -71
  767. package/src/apps/data/routes/zones.ts +71 -55
  768. package/src/apps/docs/reference.ts +2 -2
  769. package/src/apps/index.ts +1 -1
  770. package/src/apps/management/App.ts +9 -51
  771. package/src/apps/management/Billing.test.ts +375 -14
  772. package/src/apps/management/Billing.ts +265 -29
  773. package/src/apps/management/routes/api-keys.test.ts +269 -7
  774. package/src/apps/management/routes/api-keys.ts +61 -20
  775. package/src/apps/management/routes/billing.test.ts +477 -15
  776. package/src/apps/management/routes/billing.ts +377 -50
  777. package/src/apps/management/routes/faucet.test.ts +1 -1
  778. package/src/apps/management/routes/faucet.ts +1 -1
  779. package/src/apps/management/routes/invitations.test.ts +270 -3
  780. package/src/apps/management/routes/invitations.ts +185 -15
  781. package/src/apps/management/routes/invoicePreview.test.ts +549 -0
  782. package/src/apps/management/routes/me.test.ts +246 -5
  783. package/src/apps/management/routes/me.ts +7 -2
  784. package/src/apps/management/routes/members.test.ts +108 -0
  785. package/src/apps/management/routes/orgs.test.ts +191 -3
  786. package/src/apps/management/routes/orgs.ts +58 -11
  787. package/src/apps/management/routes/projects.test.ts +33 -3
  788. package/src/apps/management/routes/projects.ts +6 -1
  789. package/src/apps/management/routes/scopes.test.ts +30 -2
  790. package/src/apps/management/routes/scopes.ts +4 -1
  791. package/src/apps/management/routes/usage.test.ts +32 -0
  792. package/src/apps/management/routes/usage.ts +22 -4
  793. package/src/apps/management/routes/webhooks.test.ts +49 -26
  794. package/src/apps/management/routes/webhooks.ts +78 -22
  795. package/src/apps/mcp.test.ts +6 -6
  796. package/src/apps/mcp.ts +7 -7
  797. package/src/apps/mpp/App.ts +37 -7
  798. package/src/apps/mpp/Mpp.test.ts +49 -8
  799. package/src/apps/mpp/Mpp.zone.test.ts +219 -0
  800. package/src/apps/mpp/internal/Adapter.ts +34 -0
  801. package/src/apps/mpp/internal/Policy.test.ts +86 -31
  802. package/src/apps/mpp/internal/Policy.ts +49 -7
  803. package/src/apps/mpp/internal/Sponsorship.test.ts +207 -0
  804. package/src/apps/mpp/internal/Sponsorship.ts +9 -3
  805. package/src/apps/relay/App.test.ts +839 -64
  806. package/src/apps/relay/App.ts +148 -81
  807. package/src/apps/relay/App.zone-billing.test.ts +257 -0
  808. package/src/apps/relay/Sponsorships.test.ts +67 -4
  809. package/src/apps/relay/Sponsorships.ts +233 -32
  810. package/src/apps/relay/Sponsorships.zone.test.ts +102 -0
  811. package/src/apps/{funding → routes}/Access.ts +6 -6
  812. package/src/apps/routes/App.test.ts +165 -0
  813. package/src/apps/routes/App.ts +96 -0
  814. package/src/apps/{funding → routes}/Inventory.ts +2 -2
  815. package/src/apps/routes/index.ts +1 -0
  816. package/src/apps/{funding → routes}/routes/chains.test.ts +66 -66
  817. package/src/apps/{funding → routes}/routes/chains.ts +23 -23
  818. package/src/apps/{funding → routes}/routes/deposit-addresses.test.ts +1358 -458
  819. package/src/apps/{funding → routes}/routes/deposit-addresses.ts +566 -246
  820. package/src/apps/{funding → routes}/routes/providers.test.ts +27 -33
  821. package/src/apps/{funding → routes}/routes/providers.ts +23 -23
  822. package/src/apps/{funding → routes}/routes/quotes.test.ts +298 -41
  823. package/src/apps/{funding → routes}/routes/quotes.ts +57 -40
  824. package/src/apps/{funding → routes}/routes/transfers.test.ts +1100 -353
  825. package/src/apps/routes/routes/transfers.ts +1332 -0
  826. package/src/cli/Cli.test.ts +1 -1
  827. package/src/cli/commands/admin.test.ts +748 -1
  828. package/src/cli/commands/admin.ts +278 -0
  829. package/src/cloudflare.ts +52 -47
  830. package/src/db/Db.test.ts +245 -2
  831. package/src/db/Db.ts +1476 -34
  832. package/src/db/Schema.ts +729 -228
  833. package/src/db/tables/apiKeyAdmissionBootstraps.ts +4 -0
  834. package/src/db/tables/apiKeyAdmissions.ts +218 -0
  835. package/src/db/tables/apiKeyOwnerAdmissions.ts +4 -0
  836. package/src/db/tables/apiKeyOwnerTombstones.ts +81 -0
  837. package/src/db/tables/apiKeyRevocations.test.ts +74 -0
  838. package/src/db/tables/apiKeyRevocations.ts +121 -0
  839. package/src/db/tables/authAccounts.ts +105 -0
  840. package/src/db/tables/authSessions.ts +13 -0
  841. package/src/db/tables/authVerifications.ts +13 -0
  842. package/src/db/tables/invitations.ts +142 -45
  843. package/src/db/tables/memberships.ts +79 -3
  844. package/src/db/tables/organizations.test.ts +690 -13
  845. package/src/db/tables/organizations.ts +139 -55
  846. package/src/db/tables/projects.test.ts +16 -0
  847. package/src/db/tables/projects.ts +13 -3
  848. package/src/db/tables/requestUsage.ts +4 -1
  849. package/src/db/tables/rewardAccounts.ts +178 -0
  850. package/src/db/tables/rewardCampaignDistributors.ts +68 -0
  851. package/src/db/tables/rewardCampaigns.test.ts +1388 -0
  852. package/src/db/tables/rewardCampaigns.ts +647 -0
  853. package/src/db/tables/rewardCredits.ts +110 -0
  854. package/src/db/tables/rewardEligibilityAssociations.test.ts +271 -0
  855. package/src/db/tables/rewardEligibilityAssociations.ts +184 -0
  856. package/src/db/tables/rewardRuns.ts +514 -0
  857. package/src/db/tables/rewardTransactionAttempts.ts +272 -0
  858. package/src/db/tables/routesCatalog.test.ts +185 -0
  859. package/src/db/tables/routesCatalog.ts +163 -0
  860. package/src/db/tables/routesDepositAddresses.test.ts +1048 -0
  861. package/src/db/tables/routesDepositAddresses.ts +1008 -0
  862. package/src/db/tables/{fundingDepositRequestObservations.test.ts → routesDepositRequestObservations.test.ts} +13 -14
  863. package/src/db/tables/{fundingDepositRequestObservations.ts → routesDepositRequestObservations.ts} +10 -10
  864. package/src/db/tables/{fundingDeposits.test.ts → routesDeposits.test.ts} +316 -46
  865. package/src/db/tables/routesDeposits.ts +1062 -0
  866. package/src/db/tables/routesIdempotency.test.ts +796 -0
  867. package/src/db/tables/routesIdempotency.ts +496 -0
  868. package/src/db/tables/routesSubsidies.test.ts +120 -0
  869. package/src/db/tables/routesSubsidies.ts +71 -0
  870. package/src/db/tables/{fundingTransferEvents.ts → routesTransferEvents.ts} +4 -4
  871. package/src/db/tables/routesTransferSubsidies.ts +38 -0
  872. package/src/db/tables/routesTransferSubsidyNonces.ts +124 -0
  873. package/src/db/tables/routesTransferTransactions.test.ts +195 -0
  874. package/src/db/tables/{fundingTransferTransactions.ts → routesTransferTransactions.ts} +63 -18
  875. package/src/db/tables/routesTransfers.test.ts +338 -0
  876. package/src/db/tables/routesTransfers.ts +662 -0
  877. package/src/db/tables/sponsoredTransactions.test.ts +269 -45
  878. package/src/db/tables/sponsoredTransactions.ts +225 -65
  879. package/src/db/tables/sponsorshipAttributions.test.ts +160 -0
  880. package/src/db/tables/sponsorshipAttributions.ts +168 -0
  881. package/src/db/tables/sponsorshipReconciliationCursors.test.ts +115 -0
  882. package/src/db/tables/sponsorshipReconciliationCursors.ts +67 -0
  883. package/src/db/tables/stripeCustomers.test.ts +85 -0
  884. package/src/db/tables/stripeCustomers.ts +24 -0
  885. package/src/db/tables/users.test.ts +129 -0
  886. package/src/db/tables/users.ts +49 -3
  887. package/src/db/tables/webhookQueueEvents.ts +8 -1
  888. package/src/db/tables/webhookSubscriptions.ts +95 -20
  889. package/src/handlers/internal/executionError.ts +3 -4
  890. package/src/handlers/internal/multisig.ts +13 -816
  891. package/src/handlers/internal/sponsorship.ts +26 -10
  892. package/src/handlers/relay.test-d.ts +9 -1
  893. package/src/handlers/relay.test.ts +823 -3
  894. package/src/handlers/relay.ts +127 -107
  895. package/src/index.test-d.ts +7 -0
  896. package/src/index.ts +0 -17
  897. package/src/internal/AssetResponse.ts +26 -0
  898. package/src/internal/Auth.test.ts +1564 -9
  899. package/src/internal/Auth.ts +833 -239
  900. package/src/internal/BetterAuth.test.ts +242 -0
  901. package/src/internal/BetterAuth.ts +349 -0
  902. package/src/internal/Cache.ts +2 -0
  903. package/src/internal/EarnRates.test.ts +17 -0
  904. package/src/internal/EarnRates.ts +124 -31
  905. package/src/internal/EarnSharePrices.test.ts +182 -0
  906. package/src/internal/EarnSharePrices.ts +313 -0
  907. package/src/internal/EarnVaults.test.ts +21 -0
  908. package/src/internal/EarnVaults.ts +33 -11
  909. package/src/internal/Email.ts +54 -0
  910. package/src/internal/Idempotency.test.ts +2 -2
  911. package/src/internal/Log.test-d.ts +8 -7
  912. package/src/internal/Log.test.ts +114 -16
  913. package/src/internal/Log.ts +53 -40
  914. package/src/internal/MetricSink.test.ts +313 -26
  915. package/src/internal/MetricSink.ts +73 -8
  916. package/src/internal/Mpp.test.ts +31 -0
  917. package/src/internal/Mpp.ts +21 -24
  918. package/src/internal/OpenApi.ts +45 -12
  919. package/src/internal/Provider.test.ts +1 -1
  920. package/src/internal/Provider.ts +1 -1
  921. package/src/internal/RateLimit.test.ts +21 -3
  922. package/src/internal/RateLimit.ts +12 -1
  923. package/src/internal/Store.test-d.ts +1 -1
  924. package/src/internal/Store.test.ts +151 -8
  925. package/src/internal/Store.ts +76 -9
  926. package/src/internal/Tidx.test.ts +59 -8
  927. package/src/internal/Tidx.ts +86 -14
  928. package/src/internal/Timing.test.ts +77 -0
  929. package/src/internal/Timing.ts +83 -6
  930. package/src/internal/VercelOidc.test.ts +188 -0
  931. package/src/internal/VercelOidc.ts +193 -0
  932. package/src/internal/VerifiedTokens.test.ts +60 -6
  933. package/src/internal/VerifiedTokens.ts +21 -24
  934. package/src/internal/Viem.batch.test.ts +80 -0
  935. package/src/internal/Viem.test.ts +201 -2
  936. package/src/internal/Viem.ts +221 -25
  937. package/src/internal/Webhooks.test.ts +85 -6
  938. package/src/internal/Webhooks.ts +22 -4
  939. package/src/internal/ZoneRpc.ts +50 -0
  940. package/src/internal/exchange/Provider.test.ts +2 -2
  941. package/src/internal/index.test.ts +3 -1
  942. package/src/internal/index.ts +3 -1
  943. package/src/internal/rewards/Audit.ts +231 -0
  944. package/src/internal/rewards/Campaigns.test.ts +1234 -0
  945. package/src/internal/rewards/Campaigns.ts +1205 -0
  946. package/src/internal/rewards/Credits.ts +165 -0
  947. package/src/internal/rewards/Events.local.test.ts +113 -0
  948. package/src/internal/rewards/Events.test.ts +152 -0
  949. package/src/internal/rewards/Events.ts +468 -0
  950. package/src/internal/rewards/Projection.test.ts +681 -0
  951. package/src/internal/rewards/Projection.ts +987 -0
  952. package/src/internal/rewards/Rates.test.ts +171 -0
  953. package/src/internal/rewards/Rates.ts +110 -0
  954. package/src/internal/rewards/Read.test.ts +501 -0
  955. package/src/internal/rewards/Read.ts +476 -0
  956. package/src/internal/rewards/Runner.checkpoint.test.ts +80 -0
  957. package/src/internal/rewards/Runner.states.test.ts +188 -0
  958. package/src/internal/rewards/Runner.test.ts +90 -0
  959. package/src/internal/rewards/Runner.ts +2229 -0
  960. package/src/internal/rewards/Signer.test.ts +79 -0
  961. package/src/internal/rewards/Signer.ts +180 -0
  962. package/src/internal/rewards/index.ts +14 -0
  963. package/src/internal/{funding → routes}/Action.test.ts +63 -14
  964. package/src/internal/{funding → routes}/Action.ts +35 -8
  965. package/src/internal/{funding → routes}/Catalog.test.ts +3 -3
  966. package/src/internal/{funding → routes}/Catalog.ts +39 -39
  967. package/src/internal/{funding → routes}/Chain.test.ts +1 -1
  968. package/src/internal/{funding → routes}/Chain.ts +11 -11
  969. package/src/internal/{funding → routes}/Deposit.test.ts +1 -1
  970. package/src/internal/{funding → routes}/Deposit.ts +93 -45
  971. package/src/internal/{funding → routes}/DepositAddress.test.ts +11 -3
  972. package/src/internal/{funding → routes}/DepositAddress.ts +132 -53
  973. package/src/internal/{funding → routes}/DepositWebhook.test.ts +61 -18
  974. package/src/internal/{funding → routes}/DepositWebhook.ts +9 -9
  975. package/src/internal/routes/Economics.test.ts +42 -0
  976. package/src/internal/routes/Economics.ts +47 -0
  977. package/src/internal/{funding → routes}/Evidence.test.ts +6 -6
  978. package/src/internal/{funding → routes}/Evidence.ts +9 -9
  979. package/src/internal/routes/Observability.test.ts +636 -0
  980. package/src/internal/routes/Observability.ts +668 -0
  981. package/src/internal/{funding → routes}/Provider.test.ts +489 -153
  982. package/src/internal/{funding → routes}/Provider.ts +489 -186
  983. package/src/internal/{funding → routes}/Reconciliation.local.test.ts +84 -12
  984. package/src/internal/{funding → routes}/Reconciliation.test.ts +1213 -279
  985. package/src/internal/{funding → routes}/Reconciliation.ts +501 -203
  986. package/src/internal/routes/Reconciliation.unattributed.test.ts +250 -0
  987. package/src/internal/{funding → routes}/Route.ts +7 -7
  988. package/src/internal/{funding → routes}/SourceObservation.test.ts +13 -14
  989. package/src/internal/{funding → routes}/SourceObservation.ts +13 -13
  990. package/src/internal/{funding → routes}/Subsidy.local.test.ts +7 -7
  991. package/src/internal/routes/Subsidy.test.ts +169 -0
  992. package/src/internal/{funding → routes}/Subsidy.ts +86 -6
  993. package/src/internal/{funding → routes}/Token.test.ts +1 -1
  994. package/src/internal/{funding → routes}/Token.ts +5 -5
  995. package/src/internal/routes/Transfer.test.ts +1199 -0
  996. package/src/internal/routes/Transfer.ts +1206 -0
  997. package/src/internal/routes/TransferReconciliation.test.ts +731 -0
  998. package/src/internal/routes/TransferReconciliation.ts +527 -0
  999. package/src/internal/routes/TransferSubsidy.test.ts +172 -0
  1000. package/src/internal/routes/TransferSubsidy.ts +447 -0
  1001. package/src/internal/{funding → routes}/TransferWebhook.test.ts +13 -13
  1002. package/src/internal/{funding → routes}/TransferWebhook.ts +7 -7
  1003. package/src/internal/{funding → routes}/index.test.ts +5 -3
  1004. package/src/internal/{funding → routes}/index.ts +2 -0
  1005. package/src/internal/{funding → routes}/providers/across.ts +16 -16
  1006. package/src/internal/{funding → routes}/providers/index.test.ts +157 -44
  1007. package/src/internal/{funding → routes}/providers/relay.test.ts +165 -32
  1008. package/src/internal/{funding → routes}/providers/relay.ts +228 -121
  1009. package/src/internal/{funding → routes}/providers/rhino.ts +16 -16
  1010. package/src/internal/{funding → routes}/providers/squid.ts +17 -17
  1011. package/src/internal/routes/providers/stargate.test.ts +728 -0
  1012. package/src/internal/routes/providers/stargate.ts +1276 -0
  1013. package/src/internal/{funding → routes}/providers/symbiosis.ts +64 -24
  1014. package/src/internal/webhookDestinations/slack.ts +10 -10
  1015. package/src/providers/index.ts +13 -13
  1016. package/src/server.ts +18 -0
  1017. package/dist/apps/funding/Access.d.ts.map +0 -1
  1018. package/dist/apps/funding/Access.js.map +0 -1
  1019. package/dist/apps/funding/App.js.map +0 -1
  1020. package/dist/apps/funding/Inventory.d.ts.map +0 -1
  1021. package/dist/apps/funding/Inventory.js.map +0 -1
  1022. package/dist/apps/funding/ProviderAttempts.d.ts +0 -5
  1023. package/dist/apps/funding/ProviderAttempts.d.ts.map +0 -1
  1024. package/dist/apps/funding/ProviderAttempts.js +0 -24
  1025. package/dist/apps/funding/ProviderAttempts.js.map +0 -1
  1026. package/dist/apps/funding/index.d.ts +0 -2
  1027. package/dist/apps/funding/index.d.ts.map +0 -1
  1028. package/dist/apps/funding/index.js +0 -2
  1029. package/dist/apps/funding/index.js.map +0 -1
  1030. package/dist/apps/funding/routes/chains.d.ts.map +0 -1
  1031. package/dist/apps/funding/routes/chains.js.map +0 -1
  1032. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +0 -1
  1033. package/dist/apps/funding/routes/deposit-addresses.js.map +0 -1
  1034. package/dist/apps/funding/routes/providers.d.ts.map +0 -1
  1035. package/dist/apps/funding/routes/providers.js +0 -57
  1036. package/dist/apps/funding/routes/providers.js.map +0 -1
  1037. package/dist/apps/funding/routes/quotes.d.ts.map +0 -1
  1038. package/dist/apps/funding/routes/quotes.js.map +0 -1
  1039. package/dist/apps/funding/routes/transfers.d.ts.map +0 -1
  1040. package/dist/apps/funding/routes/transfers.js +0 -828
  1041. package/dist/apps/funding/routes/transfers.js.map +0 -1
  1042. package/dist/db/tables/fundingCatalog.d.ts +0 -58
  1043. package/dist/db/tables/fundingCatalog.d.ts.map +0 -1
  1044. package/dist/db/tables/fundingCatalog.js.map +0 -1
  1045. package/dist/db/tables/fundingDepositAddresses.d.ts +0 -192
  1046. package/dist/db/tables/fundingDepositAddresses.d.ts.map +0 -1
  1047. package/dist/db/tables/fundingDepositAddresses.js +0 -235
  1048. package/dist/db/tables/fundingDepositAddresses.js.map +0 -1
  1049. package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +0 -1
  1050. package/dist/db/tables/fundingDepositRequestObservations.js.map +0 -1
  1051. package/dist/db/tables/fundingDeposits.d.ts.map +0 -1
  1052. package/dist/db/tables/fundingDeposits.js +0 -295
  1053. package/dist/db/tables/fundingDeposits.js.map +0 -1
  1054. package/dist/db/tables/fundingIdempotency.d.ts +0 -91
  1055. package/dist/db/tables/fundingIdempotency.d.ts.map +0 -1
  1056. package/dist/db/tables/fundingIdempotency.js +0 -103
  1057. package/dist/db/tables/fundingIdempotency.js.map +0 -1
  1058. package/dist/db/tables/fundingTransferEvents.d.ts.map +0 -1
  1059. package/dist/db/tables/fundingTransferEvents.js.map +0 -1
  1060. package/dist/db/tables/fundingTransferTransactions.d.ts +0 -53
  1061. package/dist/db/tables/fundingTransferTransactions.d.ts.map +0 -1
  1062. package/dist/db/tables/fundingTransferTransactions.js.map +0 -1
  1063. package/dist/db/tables/fundingTransfers.d.ts +0 -99
  1064. package/dist/db/tables/fundingTransfers.d.ts.map +0 -1
  1065. package/dist/db/tables/fundingTransfers.js +0 -110
  1066. package/dist/db/tables/fundingTransfers.js.map +0 -1
  1067. package/dist/internal/funding/Action.d.ts.map +0 -1
  1068. package/dist/internal/funding/Action.js.map +0 -1
  1069. package/dist/internal/funding/Catalog.d.ts.map +0 -1
  1070. package/dist/internal/funding/Catalog.js.map +0 -1
  1071. package/dist/internal/funding/Chain.d.ts.map +0 -1
  1072. package/dist/internal/funding/Chain.js.map +0 -1
  1073. package/dist/internal/funding/Deposit.d.ts.map +0 -1
  1074. package/dist/internal/funding/Deposit.js.map +0 -1
  1075. package/dist/internal/funding/DepositAddress.d.ts.map +0 -1
  1076. package/dist/internal/funding/DepositAddress.js.map +0 -1
  1077. package/dist/internal/funding/DepositWebhook.d.ts.map +0 -1
  1078. package/dist/internal/funding/DepositWebhook.js.map +0 -1
  1079. package/dist/internal/funding/Evidence.d.ts.map +0 -1
  1080. package/dist/internal/funding/Evidence.js.map +0 -1
  1081. package/dist/internal/funding/Provider.d.ts.map +0 -1
  1082. package/dist/internal/funding/Provider.js.map +0 -1
  1083. package/dist/internal/funding/Reconciliation.d.ts.map +0 -1
  1084. package/dist/internal/funding/Reconciliation.js.map +0 -1
  1085. package/dist/internal/funding/Route.d.ts +0 -21
  1086. package/dist/internal/funding/Route.d.ts.map +0 -1
  1087. package/dist/internal/funding/Route.js.map +0 -1
  1088. package/dist/internal/funding/SourceObservation.d.ts.map +0 -1
  1089. package/dist/internal/funding/SourceObservation.js.map +0 -1
  1090. package/dist/internal/funding/Subsidy.d.ts.map +0 -1
  1091. package/dist/internal/funding/Subsidy.js.map +0 -1
  1092. package/dist/internal/funding/Token.d.ts.map +0 -1
  1093. package/dist/internal/funding/Token.js.map +0 -1
  1094. package/dist/internal/funding/Transfer.d.ts.map +0 -1
  1095. package/dist/internal/funding/Transfer.js +0 -462
  1096. package/dist/internal/funding/Transfer.js.map +0 -1
  1097. package/dist/internal/funding/TransferReconciliation.d.ts.map +0 -1
  1098. package/dist/internal/funding/TransferReconciliation.js +0 -192
  1099. package/dist/internal/funding/TransferReconciliation.js.map +0 -1
  1100. package/dist/internal/funding/TransferWebhook.d.ts.map +0 -1
  1101. package/dist/internal/funding/TransferWebhook.js.map +0 -1
  1102. package/dist/internal/funding/index.d.ts.map +0 -1
  1103. package/dist/internal/funding/index.js.map +0 -1
  1104. package/dist/internal/funding/providers/across.d.ts.map +0 -1
  1105. package/dist/internal/funding/providers/across.js.map +0 -1
  1106. package/dist/internal/funding/providers/relay.d.ts.map +0 -1
  1107. package/dist/internal/funding/providers/relay.js.map +0 -1
  1108. package/dist/internal/funding/providers/rhino.d.ts.map +0 -1
  1109. package/dist/internal/funding/providers/rhino.js.map +0 -1
  1110. package/dist/internal/funding/providers/squid.d.ts.map +0 -1
  1111. package/dist/internal/funding/providers/squid.js.map +0 -1
  1112. package/dist/internal/funding/providers/stargate.d.ts.map +0 -1
  1113. package/dist/internal/funding/providers/stargate.js +0 -579
  1114. package/dist/internal/funding/providers/stargate.js.map +0 -1
  1115. package/dist/internal/funding/providers/symbiosis.d.ts.map +0 -1
  1116. package/dist/internal/funding/providers/symbiosis.js.map +0 -1
  1117. package/src/apps/funding/App.test.ts +0 -78
  1118. package/src/apps/funding/App.ts +0 -88
  1119. package/src/apps/funding/ProviderAttempts.ts +0 -26
  1120. package/src/apps/funding/index.ts +0 -1
  1121. package/src/apps/funding/routes/transfers.ts +0 -987
  1122. package/src/db/tables/fundingCatalog.test.ts +0 -122
  1123. package/src/db/tables/fundingCatalog.ts +0 -163
  1124. package/src/db/tables/fundingDepositAddresses.test.ts +0 -608
  1125. package/src/db/tables/fundingDepositAddresses.ts +0 -443
  1126. package/src/db/tables/fundingDeposits.ts +0 -572
  1127. package/src/db/tables/fundingIdempotency.test.ts +0 -182
  1128. package/src/db/tables/fundingIdempotency.ts +0 -180
  1129. package/src/db/tables/fundingTransferTransactions.test.ts +0 -112
  1130. package/src/db/tables/fundingTransfers.test.ts +0 -115
  1131. package/src/db/tables/fundingTransfers.ts +0 -189
  1132. package/src/handlers/internal/multisig.test.ts +0 -818
  1133. package/src/internal/funding/Subsidy.test.ts +0 -75
  1134. package/src/internal/funding/Transfer.test.ts +0 -524
  1135. package/src/internal/funding/Transfer.ts +0 -762
  1136. package/src/internal/funding/TransferReconciliation.test.ts +0 -147
  1137. package/src/internal/funding/TransferReconciliation.ts +0 -264
  1138. package/src/internal/funding/providers/stargate.test.ts +0 -328
  1139. package/src/internal/funding/providers/stargate.ts +0 -856
  1140. /package/dist/apps/{funding → routes}/Inventory.d.ts +0 -0
  1141. /package/src/internal/{funding → routes}/Route.test.ts +0 -0
package/src/db/Db.ts CHANGED
@@ -12,24 +12,44 @@ import {
12
12
  import * as pg from 'pg'
13
13
 
14
14
  import type * as AdminAuditLogs from './tables/adminAuditLogs.js'
15
+ import type * as ApiKeyAdmissionBootstraps from './tables/apiKeyAdmissionBootstraps.js'
16
+ import type * as ApiKeyAdmissions from './tables/apiKeyAdmissions.js'
17
+ import type * as ApiKeyOwnerAdmissions from './tables/apiKeyOwnerAdmissions.js'
18
+ import type * as ApiKeyOwnerTombstones from './tables/apiKeyOwnerTombstones.js'
19
+ import type * as ApiKeyRevocations from './tables/apiKeyRevocations.js'
20
+ import type * as AuthAccounts from './tables/authAccounts.js'
21
+ import type * as AuthSessions from './tables/authSessions.js'
22
+ import type * as AuthVerifications from './tables/authVerifications.js'
15
23
  import type * as BillingSettings from './tables/billingSettings.js'
16
24
  import type * as EarlyAccess from './tables/earlyAccess.js'
17
25
  import type * as EarnVaults from './tables/earnVaults.js'
18
26
  import type * as EnabledBillingSources from './tables/enabledBillingSources.js'
19
- import type * as FundingCatalog from './tables/fundingCatalog.js'
20
- import type * as FundingDepositAddresses from './tables/fundingDepositAddresses.js'
21
- import type * as FundingDepositRequestObservations from './tables/fundingDepositRequestObservations.js'
22
- import type * as FundingDeposits from './tables/fundingDeposits.js'
23
- import type * as FundingIdempotency from './tables/fundingIdempotency.js'
24
- import type * as FundingTransferEvents from './tables/fundingTransferEvents.js'
25
- import type * as FundingTransfers from './tables/fundingTransfers.js'
26
- import type * as FundingTransferTransactions from './tables/fundingTransferTransactions.js'
27
27
  import type * as Invitations from './tables/invitations.js'
28
28
  import type * as InviteLinks from './tables/inviteLinks.js'
29
29
  import type * as Memberships from './tables/memberships.js'
30
30
  import type * as Organizations from './tables/organizations.js'
31
31
  import type * as Projects from './tables/projects.js'
32
32
  import type * as RequestUsage from './tables/requestUsage.js'
33
+ import type * as RewardAccounts from './tables/rewardAccounts.js'
34
+ import type * as RewardCampaignDistributors from './tables/rewardCampaignDistributors.js'
35
+ import type * as RewardCampaigns from './tables/rewardCampaigns.js'
36
+ import type * as RewardCredits from './tables/rewardCredits.js'
37
+ import type * as RewardEligibilityAssociations from './tables/rewardEligibilityAssociations.js'
38
+ import type * as RewardRuns from './tables/rewardRuns.js'
39
+ import type * as RewardTransactionAttempts from './tables/rewardTransactionAttempts.js'
40
+ import type * as RoutesCatalog from './tables/routesCatalog.js'
41
+ import type * as RoutesDepositAddresses from './tables/routesDepositAddresses.js'
42
+ import type * as RoutesDepositRequestObservations from './tables/routesDepositRequestObservations.js'
43
+ import type * as RoutesDeposits from './tables/routesDeposits.js'
44
+ import type * as RoutesIdempotency from './tables/routesIdempotency.js'
45
+ import type * as RoutesSubsidies from './tables/routesSubsidies.js'
46
+ import type * as RoutesTransferEvents from './tables/routesTransferEvents.js'
47
+ import type * as RoutesTransfers from './tables/routesTransfers.js'
48
+ import type * as RoutesTransferSubsidies from './tables/routesTransferSubsidies.js'
49
+ import type * as RoutesTransferSubsidyNonces from './tables/routesTransferSubsidyNonces.js'
50
+ import type * as RoutesTransferTransactions from './tables/routesTransferTransactions.js'
51
+ import type * as SponsorshipReconciliationCursors from './tables/sponsorshipReconciliationCursors.js'
52
+ import type * as SponsorshipAttributions from './tables/sponsorshipAttributions.js'
33
53
  import type * as SponsoredTransactions from './tables/sponsoredTransactions.js'
34
54
  import type * as StripeCustomers from './tables/stripeCustomers.js'
35
55
  import type * as Users from './tables/users.js'
@@ -46,22 +66,18 @@ import type * as WebhookSubscriptions from './tables/webhookSubscriptions.js'
46
66
  */
47
67
  export type Database = {
48
68
  admin_audit_logs: AdminAuditLogs.Table
69
+ api_key_admission_bootstraps: ApiKeyAdmissionBootstraps.Table
70
+ api_key_admissions: ApiKeyAdmissions.Table
71
+ api_key_owner_admissions: ApiKeyOwnerAdmissions.Table
72
+ api_key_owner_tombstones: ApiKeyOwnerTombstones.Table
73
+ api_key_revocations: ApiKeyRevocations.Table
74
+ auth_accounts: AuthAccounts.Table
75
+ auth_sessions: AuthSessions.Table
76
+ auth_verifications: AuthVerifications.Table
49
77
  billing_settings: BillingSettings.Table
50
78
  early_access: EarlyAccess.Table
51
79
  earn_vaults: EarnVaults.Table
52
80
  enabled_billing_sources: EnabledBillingSources.Table
53
- funding_catalogs: FundingCatalog.CatalogTable
54
- funding_chain_tokens: FundingCatalog.ChainTokenTable
55
- funding_chains: FundingCatalog.ChainTable
56
- funding_deposit_addresses: FundingDepositAddresses.Table
57
- funding_deposit_request_observations: FundingDepositRequestObservations.Table
58
- funding_deposits: FundingDeposits.Table
59
- funding_idempotency_requests: FundingIdempotency.Table
60
- funding_routes: FundingCatalog.RouteTable
61
- funding_tokens: FundingCatalog.TokenTable
62
- funding_transfer_events: FundingTransferEvents.Table
63
- funding_transfer_transactions: FundingTransferTransactions.Table
64
- funding_transfers: FundingTransfers.Table
65
81
  invitations: Invitations.Table
66
82
  invite_link_redemptions: InviteLinks.RedemptionTable
67
83
  invite_links: InviteLinks.Table
@@ -77,6 +93,30 @@ export type Database = {
77
93
  projects: Projects.Table
78
94
  request_usage_buckets: RequestUsage.BucketTable
79
95
  request_usage_meter_events: RequestUsage.MeterEventTable
96
+ reward_accounts: RewardAccounts.Table
97
+ reward_campaign_distributors: RewardCampaignDistributors.Table
98
+ reward_campaigns: RewardCampaigns.Table
99
+ reward_credits: RewardCredits.Table
100
+ reward_eligibility_associations: RewardEligibilityAssociations.Table
101
+ reward_runs: RewardRuns.Table
102
+ reward_transaction_attempts: RewardTransactionAttempts.Table
103
+ routes_catalogs: RoutesCatalog.CatalogTable
104
+ routes_chain_tokens: RoutesCatalog.ChainTokenTable
105
+ routes_chains: RoutesCatalog.ChainTable
106
+ routes_deposit_addresses: RoutesDepositAddresses.Table
107
+ routes_deposit_request_observations: RoutesDepositRequestObservations.Table
108
+ routes_deposits: RoutesDeposits.Table
109
+ routes_idempotency_requests: RoutesIdempotency.Table
110
+ routes_routes: RoutesCatalog.RouteTable
111
+ routes_subsidies: RoutesSubsidies.Table
112
+ routes_tokens: RoutesCatalog.TokenTable
113
+ routes_transfer_events: RoutesTransferEvents.Table
114
+ routes_transfer_subsidies: RoutesTransferSubsidies.Table
115
+ routes_transfer_subsidy_nonces: RoutesTransferSubsidyNonces.Table
116
+ routes_transfer_transactions: RoutesTransferTransactions.Table
117
+ routes_transfers: RoutesTransfers.Table
118
+ sponsorship_reconciliation_cursors: SponsorshipReconciliationCursors.Table
119
+ sponsorship_attributions: SponsorshipAttributions.Table
80
120
  sponsored_transactions: SponsoredTransactions.Table
81
121
  stripe_customers: StripeCustomers.Table
82
122
  users: Users.Table
@@ -1523,6 +1563,1414 @@ export const migrations: readonly Migration[] = [
1523
1563
  sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_promotion_spend_idx ON sponsored_transactions (org_id, project_id, status, created_at) WHERE NOT billable`,
1524
1564
  ),
1525
1565
  },
1566
+ {
1567
+ name: '0142_funding_transfers_status_updated_at',
1568
+ up: (db) =>
1569
+ raw(db, sql`ALTER TABLE funding_transfers ADD COLUMN IF NOT EXISTS status_updated_at text`),
1570
+ },
1571
+ {
1572
+ name: '0143_funding_deposits_status_updated_at',
1573
+ up: (db) =>
1574
+ raw(db, sql`ALTER TABLE funding_deposits ADD COLUMN IF NOT EXISTS status_updated_at text`),
1575
+ },
1576
+ {
1577
+ name: '0144_funding_deposit_addresses_status_updated_at',
1578
+ up: (db) =>
1579
+ raw(
1580
+ db,
1581
+ sql`ALTER TABLE funding_deposit_addresses ADD COLUMN IF NOT EXISTS status_updated_at text`,
1582
+ ),
1583
+ },
1584
+ {
1585
+ name: '0145_funding_transfers_state_metrics_index',
1586
+ up: (db) =>
1587
+ raw(
1588
+ db,
1589
+ sql`CREATE INDEX IF NOT EXISTS funding_transfers_state_metrics_idx ON funding_transfers (status, environment, provider_id, method, (status_reason->>'code'), status_updated_at, updated_at)`,
1590
+ ),
1591
+ },
1592
+ {
1593
+ name: '0146_funding_deposits_state_metrics_index',
1594
+ up: (db) =>
1595
+ raw(
1596
+ db,
1597
+ sql`CREATE INDEX IF NOT EXISTS funding_deposits_state_metrics_idx ON funding_deposits (status, environment, deposit_address_id, (status_reason->>'code'), status_updated_at, updated_at)`,
1598
+ ),
1599
+ },
1600
+ {
1601
+ name: '0147_funding_deposits_provider_delivered_at',
1602
+ up: (db) =>
1603
+ raw(
1604
+ db,
1605
+ sql`ALTER TABLE funding_deposits ADD COLUMN IF NOT EXISTS provider_delivered_at text`,
1606
+ ),
1607
+ },
1608
+ {
1609
+ name: '0148_funding_transfers_updated_at_index',
1610
+ up: (db) =>
1611
+ raw(
1612
+ db,
1613
+ sql`CREATE INDEX IF NOT EXISTS funding_transfers_updated_at_idx ON funding_transfers (updated_at DESC, id DESC)`,
1614
+ ),
1615
+ },
1616
+ {
1617
+ name: '0149_funding_deposits_updated_at_index',
1618
+ up: (db) =>
1619
+ raw(
1620
+ db,
1621
+ sql`CREATE INDEX IF NOT EXISTS funding_deposits_updated_at_idx ON funding_deposits (updated_at DESC, id DESC)`,
1622
+ ),
1623
+ },
1624
+ {
1625
+ name: '0150_funding_deposit_addresses_updated_at_index',
1626
+ up: (db) =>
1627
+ raw(
1628
+ db,
1629
+ sql`CREATE INDEX IF NOT EXISTS funding_deposit_addresses_updated_at_idx ON funding_deposit_addresses (updated_at DESC, id DESC)`,
1630
+ ),
1631
+ },
1632
+ {
1633
+ name: '0151_sponsorship_attributions',
1634
+ up: (db) =>
1635
+ db.schema
1636
+ .createTable('sponsorshipAttributions')
1637
+ .ifNotExists()
1638
+ .addColumn('id', 'text', (c) => c.primaryKey())
1639
+ .addColumn('orgId', 'text', (c) => c.notNull())
1640
+ .addColumn('externalId', 'text')
1641
+ .addColumn('projectId', 'text')
1642
+ .addColumn('startsAt', 'text')
1643
+ .addColumn('endsAt', 'text')
1644
+ .addColumn('spendLimit', 'text')
1645
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1646
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
1647
+ .addCheckConstraint(
1648
+ 'sponsorship_attributions_source_check',
1649
+ sql`(external_id IS NULL) <> (project_id IS NULL)`,
1650
+ )
1651
+ .addCheckConstraint(
1652
+ 'sponsorship_attributions_window_check',
1653
+ sql`(starts_at IS NULL) = (ends_at IS NULL)`,
1654
+ ),
1655
+ },
1656
+ {
1657
+ name: '0152_sponsorship_attributions_external_unique',
1658
+ up: (db) =>
1659
+ raw(
1660
+ db,
1661
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS sponsorship_attributions_external_unique ON sponsorship_attributions (org_id, external_id) WHERE external_id IS NOT NULL`,
1662
+ ),
1663
+ },
1664
+ {
1665
+ name: '0153_sponsorship_attributions_project_unique',
1666
+ up: (db) =>
1667
+ raw(
1668
+ db,
1669
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS sponsorship_attributions_project_unique ON sponsorship_attributions (org_id, project_id) WHERE project_id IS NOT NULL`,
1670
+ ),
1671
+ },
1672
+ {
1673
+ name: '0154_sponsored_transactions_attribution_id',
1674
+ up: (db) =>
1675
+ raw(
1676
+ db,
1677
+ sql`ALTER TABLE sponsored_transactions ADD COLUMN IF NOT EXISTS sponsorship_attribution_id text`,
1678
+ ),
1679
+ },
1680
+ {
1681
+ name: '0155_sponsored_transactions_attribution_spend_index',
1682
+ up: (db) =>
1683
+ raw(
1684
+ db,
1685
+ sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_attribution_spend_idx ON sponsored_transactions (org_id, sponsorship_attribution_id, status, created_at) WHERE NOT billable`,
1686
+ ),
1687
+ },
1688
+ {
1689
+ name: '0156_project_sponsorship_attributions',
1690
+ up: (db) =>
1691
+ raw(
1692
+ db,
1693
+ sql`INSERT INTO sponsorship_attributions (id, org_id, external_id, project_id, starts_at, ends_at, spend_limit, created_at, updated_at)
1694
+ SELECT 'sat_' || md5(projects.org_id || ':' || projects.id), projects.org_id, NULL, projects.id, projects.sponsorship_subsidy_starts_at, projects.sponsorship_subsidy_ends_at, projects.sponsorship_spend_limit, projects.created_at, projects.updated_at
1695
+ FROM projects
1696
+ WHERE projects.sponsorship_subsidy_starts_at IS NOT NULL
1697
+ ON CONFLICT (org_id, project_id) WHERE project_id IS NOT NULL DO UPDATE
1698
+ SET starts_at = EXCLUDED.starts_at, ends_at = EXCLUDED.ends_at, spend_limit = EXCLUDED.spend_limit, updated_at = EXCLUDED.updated_at
1699
+ WHERE sponsorship_attributions.starts_at IS NULL`,
1700
+ ),
1701
+ },
1702
+ {
1703
+ name: '0157_project_sponsored_transaction_attributions',
1704
+ up: (db) =>
1705
+ raw(
1706
+ db,
1707
+ sql`UPDATE sponsored_transactions
1708
+ SET sponsorship_attribution_id = sponsorship_attributions.id
1709
+ FROM sponsorship_attributions
1710
+ WHERE sponsored_transactions.sponsorship_attribution_id IS NULL
1711
+ AND sponsored_transactions.org_id = sponsorship_attributions.org_id
1712
+ AND sponsored_transactions.project_id = sponsorship_attributions.project_id`,
1713
+ ),
1714
+ },
1715
+ {
1716
+ name: '0158_reward_eligibility_associations',
1717
+ up: (db) =>
1718
+ db.schema
1719
+ .createTable('rewardEligibilityAssociations')
1720
+ .ifNotExists()
1721
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
1722
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
1723
+ .addColumn('walletAddress', 'text', (c) => c.notNull())
1724
+ .addColumn('firstRegisteredAt', 'text', (c) => c.notNull())
1725
+ .addColumn('latestRegisteredAt', 'text', (c) => c.notNull())
1726
+ .addColumn('transactionHash', 'text')
1727
+ .addPrimaryKeyConstraint('reward_eligibility_associations_pkey', [
1728
+ 'chainId',
1729
+ 'vaultAddress',
1730
+ 'walletAddress',
1731
+ ]),
1732
+ },
1733
+ {
1734
+ name: '0159_reward_eligibility_registration_order',
1735
+ up: (db) =>
1736
+ raw(
1737
+ db,
1738
+ sql`ALTER TABLE reward_eligibility_associations ADD COLUMN IF NOT EXISTS registration_order bigint GENERATED ALWAYS AS IDENTITY UNIQUE`,
1739
+ ),
1740
+ },
1741
+ {
1742
+ name: '0160_reward_eligibility_page_index',
1743
+ up: (db) =>
1744
+ db.schema
1745
+ .createIndex('reward_eligibility_associations_page_idx')
1746
+ .ifNotExists()
1747
+ .on('rewardEligibilityAssociations')
1748
+ .columns(['chainId', 'vaultAddress', 'registrationOrder']),
1749
+ },
1750
+ {
1751
+ name: '0161_users_name',
1752
+ up: (db) => raw(db, sql`ALTER TABLE users ADD COLUMN IF NOT EXISTS name text`),
1753
+ },
1754
+ {
1755
+ name: '0162_users_image',
1756
+ up: (db) => raw(db, sql`ALTER TABLE users ADD COLUMN IF NOT EXISTS image text`),
1757
+ },
1758
+ {
1759
+ name: '0163_users_email_verified',
1760
+ up: (db) => raw(db, sql`ALTER TABLE users ADD COLUMN IF NOT EXISTS email_verified boolean`),
1761
+ },
1762
+ {
1763
+ name: '0164_users_auth_fields_backfill',
1764
+ up: (db) =>
1765
+ raw(
1766
+ db,
1767
+ sql`UPDATE users SET email_verified = email IS NOT NULL, name = COALESCE(NULLIF(btrim(email), ''), id) WHERE email_verified IS NULL OR name IS NULL`,
1768
+ ),
1769
+ },
1770
+ {
1771
+ name: '0165_users_auth_fields_required',
1772
+ // Defaults keep inserts from the previous Worker valid while the new
1773
+ // required Better Auth fields roll out.
1774
+ up: (db) =>
1775
+ raw(
1776
+ db,
1777
+ sql`ALTER TABLE users ALTER COLUMN email_verified SET DEFAULT false, ALTER COLUMN email_verified SET NOT NULL, ALTER COLUMN name SET DEFAULT '', ALTER COLUMN name SET NOT NULL`,
1778
+ ),
1779
+ },
1780
+ {
1781
+ name: '0166_users_email_auth_precondition',
1782
+ up: (db) =>
1783
+ raw(
1784
+ db,
1785
+ sql`DO $$ BEGIN
1786
+ IF EXISTS (SELECT 1 FROM users WHERE email IS NOT NULL AND btrim(email) = '') THEN
1787
+ RAISE EXCEPTION 'users.email contains blank values';
1788
+ END IF;
1789
+ END $$`,
1790
+ ),
1791
+ },
1792
+ {
1793
+ name: '0167_users_email_normalized',
1794
+ up: (db) => raw(db, sql`UPDATE users SET email = lower(btrim(email))`),
1795
+ },
1796
+ {
1797
+ name: '0168_users_email_index',
1798
+ // SIWE still creates address-keyed users. Enforce email uniqueness in a
1799
+ // later deployment after wallet identities are linked.
1800
+ up: (db) => raw(db, sql`CREATE INDEX IF NOT EXISTS users_email_idx ON users (email)`),
1801
+ },
1802
+ {
1803
+ name: '0169_users_email_normalized_index',
1804
+ up: (db) =>
1805
+ raw(
1806
+ db,
1807
+ sql`CREATE INDEX IF NOT EXISTS users_email_normalized_idx ON users (lower(btrim(email))) WHERE email IS NOT NULL`,
1808
+ ),
1809
+ },
1810
+ {
1811
+ name: '0170_auth_sessions',
1812
+ up: (db) =>
1813
+ db.schema
1814
+ .createTable('authSessions')
1815
+ .ifNotExists()
1816
+ .addColumn('id', 'text', (c) => c.primaryKey().notNull())
1817
+ .addColumn('expiresAt', 'text', (c) => c.notNull())
1818
+ .addColumn('token', 'text', (c) => c.notNull().unique())
1819
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1820
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
1821
+ .addColumn('ipAddress', 'text')
1822
+ .addColumn('userAgent', 'text')
1823
+ .addColumn('userId', 'text', (c) => c.notNull().references('users.id').onDelete('cascade')),
1824
+ },
1825
+ {
1826
+ name: '0171_auth_sessions_user_index',
1827
+ up: (db) =>
1828
+ db.schema
1829
+ .createIndex('auth_sessions_user_id_idx')
1830
+ .ifNotExists()
1831
+ .on('authSessions')
1832
+ .column('userId'),
1833
+ },
1834
+ {
1835
+ name: '0172_auth_accounts',
1836
+ up: (db) =>
1837
+ db.schema
1838
+ .createTable('authAccounts')
1839
+ .ifNotExists()
1840
+ .addColumn('id', 'text', (c) => c.primaryKey().notNull())
1841
+ .addColumn('issuer', 'text', (c) => c.notNull())
1842
+ .addColumn('accountId', 'text', (c) => c.notNull())
1843
+ .addColumn('providerId', 'text', (c) => c.notNull())
1844
+ .addColumn('userId', 'text', (c) => c.notNull().references('users.id').onDelete('cascade'))
1845
+ .addColumn('accessToken', 'text')
1846
+ .addColumn('refreshToken', 'text')
1847
+ .addColumn('idToken', 'text')
1848
+ .addColumn('accessTokenExpiresAt', 'text')
1849
+ .addColumn('refreshTokenExpiresAt', 'text')
1850
+ .addColumn('scope', 'text')
1851
+ .addColumn('password', 'text')
1852
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1853
+ .addColumn('updatedAt', 'text', (c) => c.notNull()),
1854
+ },
1855
+ {
1856
+ name: '0173_auth_accounts_user_index',
1857
+ up: (db) =>
1858
+ db.schema
1859
+ .createIndex('auth_accounts_user_id_idx')
1860
+ .ifNotExists()
1861
+ .on('authAccounts')
1862
+ .column('userId'),
1863
+ },
1864
+ {
1865
+ name: '0174_auth_accounts_identity_index',
1866
+ up: (db) =>
1867
+ db.schema
1868
+ .createIndex('auth_accounts_issuer_account_id_unique_idx')
1869
+ .ifNotExists()
1870
+ .unique()
1871
+ .on('authAccounts')
1872
+ .columns(['issuer', 'accountId']),
1873
+ },
1874
+ {
1875
+ name: '0175_auth_verifications',
1876
+ up: (db) =>
1877
+ db.schema
1878
+ .createTable('authVerifications')
1879
+ .ifNotExists()
1880
+ .addColumn('id', 'text', (c) => c.primaryKey().notNull())
1881
+ .addColumn('identifier', 'text', (c) => c.notNull())
1882
+ .addColumn('value', 'text', (c) => c.notNull())
1883
+ .addColumn('expiresAt', 'text', (c) => c.notNull())
1884
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1885
+ .addColumn('updatedAt', 'text', (c) => c.notNull()),
1886
+ },
1887
+ {
1888
+ name: '0176_auth_verifications_identifier_index',
1889
+ up: (db) =>
1890
+ db.schema
1891
+ .createIndex('auth_verifications_identifier_idx')
1892
+ .ifNotExists()
1893
+ .on('authVerifications')
1894
+ .column('identifier'),
1895
+ },
1896
+ {
1897
+ name: '0177_auth_sessions_provider',
1898
+ up: (db) => raw(db, sql`ALTER TABLE auth_sessions ADD COLUMN IF NOT EXISTS provider text`),
1899
+ },
1900
+ {
1901
+ name: '0178_reward_campaigns',
1902
+ up: (db) =>
1903
+ db.schema
1904
+ .createTable('rewardCampaigns')
1905
+ .ifNotExists()
1906
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
1907
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
1908
+ .addColumn('assetAddress', 'text', (c) => c.notNull())
1909
+ .addColumn('assetDecimals', 'integer', (c) => c.notNull())
1910
+ .addColumn('earnShareAddress', 'text', (c) => c.notNull())
1911
+ .addColumn('controllerAddress', 'text')
1912
+ .addColumn('distributorAddress', 'text')
1913
+ .addColumn('config', 'jsonb', (c) => c.notNull())
1914
+ .addColumn('pendingConfig', 'jsonb')
1915
+ .addColumn('pendingEffectiveAt', 'bigint')
1916
+ .addColumn('eventCursor', 'jsonb')
1917
+ .addColumn('deliveredThrough', 'bigint', (c) => c.notNull())
1918
+ .addColumn('paused', 'boolean', (c) => c.notNull().defaultTo(false))
1919
+ .addColumn('provisioningError', 'text')
1920
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1921
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
1922
+ .addPrimaryKeyConstraint('reward_campaigns_pkey', ['chainId', 'vaultAddress'])
1923
+ .addForeignKeyConstraint(
1924
+ 'reward_campaigns_vault_fkey',
1925
+ ['chainId', 'vaultAddress'],
1926
+ 'earnVaults',
1927
+ ['chainId', 'vaultAddress'],
1928
+ (c) => c.onDelete('restrict'),
1929
+ ),
1930
+ },
1931
+ {
1932
+ name: '0179_reward_accounts',
1933
+ up: (db) =>
1934
+ db.schema
1935
+ .createTable('rewardAccounts')
1936
+ .ifNotExists()
1937
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
1938
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
1939
+ .addColumn('recipient', 'text', (c) => c.notNull())
1940
+ .addColumn('registrationOrder', 'bigint', (c) => c.notNull())
1941
+ .addColumn('publicEarnShares', 'numeric', (c) => c.notNull())
1942
+ .addColumn('qualifiedEarnShares', 'numeric', (c) => c.notNull())
1943
+ .addColumn('allocatedPrincipalAssets', 'numeric', (c) => c.notNull())
1944
+ .addColumn('accrualRemainder', 'numeric', (c) => c.notNull())
1945
+ .addColumn('pendingRewardAssets', 'numeric', (c) => c.notNull())
1946
+ .addColumn('cumulativeEntitlement', 'numeric', (c) => c.notNull())
1947
+ .addColumn('cumulativePaid', 'numeric', (c) => c.notNull())
1948
+ .addColumn('deferral', 'text')
1949
+ .addColumn('lots', 'jsonb', (c) => c.notNull())
1950
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
1951
+ .addPrimaryKeyConstraint('reward_accounts_pkey', ['chainId', 'vaultAddress', 'recipient'])
1952
+ .addForeignKeyConstraint(
1953
+ 'reward_accounts_campaign_fkey',
1954
+ ['chainId', 'vaultAddress'],
1955
+ 'rewardCampaigns',
1956
+ ['chainId', 'vaultAddress'],
1957
+ (c) => c.onDelete('cascade'),
1958
+ ),
1959
+ },
1960
+ {
1961
+ name: '0180_reward_runs',
1962
+ up: (db) =>
1963
+ db.schema
1964
+ .createTable('rewardRuns')
1965
+ .ifNotExists()
1966
+ .addColumn('id', 'text', (c) => c.primaryKey().notNull())
1967
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
1968
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
1969
+ .addColumn('startsAfter', 'bigint', (c) => c.notNull())
1970
+ .addColumn('endsAt', 'bigint', (c) => c.notNull())
1971
+ .addColumn('config', 'jsonb', (c) => c.notNull())
1972
+ .addColumn('phase', 'text', (c) => c.notNull())
1973
+ .addColumn('leaseExpiresAt', 'text')
1974
+ .addColumn('fence', 'bigint', (c) => c.notNull().defaultTo(0))
1975
+ .addColumn('evidence', 'jsonb')
1976
+ .addColumn('fundedAssets', 'numeric')
1977
+ .addColumn('mintedEarnShares', 'numeric')
1978
+ .addColumn('statement', 'jsonb')
1979
+ .addColumn('statementHash', 'text')
1980
+ .addColumn('root', 'text')
1981
+ .addColumn('rootVersion', 'bigint')
1982
+ .addColumn('liability', 'numeric')
1983
+ .addColumn('error', 'text')
1984
+ .addColumn('createdAt', 'text', (c) => c.notNull())
1985
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
1986
+ .addUniqueConstraint('reward_runs_boundary_key', ['chainId', 'vaultAddress', 'startsAfter'])
1987
+ .addForeignKeyConstraint(
1988
+ 'reward_runs_campaign_fkey',
1989
+ ['chainId', 'vaultAddress'],
1990
+ 'rewardCampaigns',
1991
+ ['chainId', 'vaultAddress'],
1992
+ (c) => c.onDelete('cascade'),
1993
+ ),
1994
+ },
1995
+ {
1996
+ name: '0181_reward_transaction_attempts',
1997
+ up: (db) =>
1998
+ db.schema
1999
+ .createTable('rewardTransactionAttempts')
2000
+ .ifNotExists()
2001
+ .addColumn('id', 'text', (c) => c.primaryKey().notNull())
2002
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
2003
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
2004
+ .addColumn('runId', 'text')
2005
+ .addColumn('intent', 'jsonb', (c) => c.notNull())
2006
+ .addColumn('intentId', 'text', (c) => c.notNull())
2007
+ .addColumn('signer', 'text', (c) => c.notNull())
2008
+ .addColumn('nonce', 'numeric')
2009
+ .addColumn('expiresAt', 'text')
2010
+ .addColumn('signedBytes', 'text')
2011
+ .addColumn('transactionHash', 'text')
2012
+ .addColumn('state', 'text', (c) => c.notNull())
2013
+ .addColumn('receipt', 'jsonb')
2014
+ .addColumn('confirmedBlockHash', 'text')
2015
+ .addColumn('replacementOf', 'text')
2016
+ .addColumn('createdAt', 'text', (c) => c.notNull())
2017
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
2018
+ .addForeignKeyConstraint(
2019
+ 'reward_transaction_attempts_campaign_fkey',
2020
+ ['chainId', 'vaultAddress'],
2021
+ 'rewardCampaigns',
2022
+ ['chainId', 'vaultAddress'],
2023
+ (c) => c.onDelete('cascade'),
2024
+ )
2025
+ .addForeignKeyConstraint(
2026
+ 'reward_transaction_attempts_run_fkey',
2027
+ ['runId'],
2028
+ 'rewardRuns',
2029
+ ['id'],
2030
+ (c) => c.onDelete('cascade'),
2031
+ )
2032
+ .addForeignKeyConstraint(
2033
+ 'reward_transaction_attempts_replacement_fkey',
2034
+ ['replacementOf'],
2035
+ 'rewardTransactionAttempts',
2036
+ ['id'],
2037
+ (c) => c.onDelete('restrict'),
2038
+ ),
2039
+ },
2040
+ {
2041
+ name: '0182_reward_transaction_attempt_nonce_key',
2042
+ up: (db) =>
2043
+ raw(
2044
+ db,
2045
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS reward_transaction_attempt_nonce_key ON reward_transaction_attempts (chain_id, signer, nonce) WHERE nonce IS NOT NULL`,
2046
+ ),
2047
+ },
2048
+ {
2049
+ name: '0183_reward_campaigns_due_index',
2050
+ up: (db) =>
2051
+ db.schema
2052
+ .createIndex('reward_campaigns_due_idx')
2053
+ .ifNotExists()
2054
+ .on('rewardCampaigns')
2055
+ .columns(['paused', 'deliveredThrough']),
2056
+ },
2057
+ {
2058
+ name: '0184_reward_transaction_attempt_live_intent_key',
2059
+ up: (db) =>
2060
+ raw(
2061
+ db,
2062
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS reward_transaction_attempt_live_intent_key ON reward_transaction_attempts (intent_id) WHERE state IN ('created', 'signed', 'broadcast')`,
2063
+ ),
2064
+ },
2065
+ {
2066
+ name: '0185_reward_campaign_signer',
2067
+ up: (db) =>
2068
+ raw(db, sql`ALTER TABLE reward_campaigns ADD COLUMN IF NOT EXISTS signer_address text`),
2069
+ },
2070
+ {
2071
+ name: '0186_reward_transaction_attempt_run_index',
2072
+ up: (db) =>
2073
+ raw(
2074
+ db,
2075
+ sql`CREATE INDEX IF NOT EXISTS reward_transaction_attempt_run_idx ON reward_transaction_attempts (run_id, created_at)`,
2076
+ ),
2077
+ },
2078
+ {
2079
+ name: '0187_reward_transaction_attempt_intent_run_index',
2080
+ up: (db) =>
2081
+ raw(
2082
+ db,
2083
+ sql`CREATE INDEX IF NOT EXISTS reward_transaction_attempt_intent_run_idx ON reward_transaction_attempts (intent_id, run_id, created_at)`,
2084
+ ),
2085
+ },
2086
+ {
2087
+ name: '0188_reward_campaign_earn_share_decimals',
2088
+ up: (db) =>
2089
+ raw(
2090
+ db,
2091
+ sql`ALTER TABLE reward_campaigns ADD COLUMN IF NOT EXISTS earn_share_decimals integer NOT NULL DEFAULT 18`,
2092
+ ),
2093
+ },
2094
+ {
2095
+ name: '0189_reward_campaign_earn_share_decimals_default',
2096
+ up: (db) =>
2097
+ raw(db, sql`ALTER TABLE reward_campaigns ALTER COLUMN earn_share_decimals DROP DEFAULT`),
2098
+ },
2099
+ {
2100
+ name: '0190_routes_tables',
2101
+ up: (db) =>
2102
+ raw(
2103
+ db,
2104
+ sql`DO $$
2105
+ DECLARE
2106
+ entry record;
2107
+ target_name text;
2108
+ BEGIN
2109
+ -- Tests replay every DDL statement on new connections, recreating empty legacy tables.
2110
+ IF to_regclass('routes_catalogs') IS NOT NULL THEN
2111
+ DROP TABLE IF EXISTS
2112
+ funding_deposit_request_observations,
2113
+ funding_deposits,
2114
+ funding_deposit_addresses,
2115
+ funding_transfer_transactions,
2116
+ funding_transfer_events,
2117
+ funding_idempotency_requests,
2118
+ funding_transfers,
2119
+ funding_routes,
2120
+ funding_chain_tokens,
2121
+ funding_tokens,
2122
+ funding_chains,
2123
+ funding_catalogs
2124
+ CASCADE;
2125
+ END IF;
2126
+
2127
+ IF to_regclass('funding_catalogs') IS NOT NULL AND to_regclass('routes_catalogs') IS NULL THEN
2128
+ ALTER TABLE funding_catalogs RENAME TO routes_catalogs;
2129
+ END IF;
2130
+ IF to_regclass('funding_chain_tokens') IS NOT NULL AND to_regclass('routes_chain_tokens') IS NULL THEN
2131
+ ALTER TABLE funding_chain_tokens RENAME TO routes_chain_tokens;
2132
+ END IF;
2133
+ IF to_regclass('funding_chains') IS NOT NULL AND to_regclass('routes_chains') IS NULL THEN
2134
+ ALTER TABLE funding_chains RENAME TO routes_chains;
2135
+ END IF;
2136
+ IF to_regclass('funding_deposit_addresses') IS NOT NULL AND to_regclass('routes_deposit_addresses') IS NULL THEN
2137
+ ALTER TABLE funding_deposit_addresses RENAME TO routes_deposit_addresses;
2138
+ END IF;
2139
+ IF to_regclass('funding_deposit_request_observations') IS NOT NULL AND to_regclass('routes_deposit_request_observations') IS NULL THEN
2140
+ ALTER TABLE funding_deposit_request_observations RENAME TO routes_deposit_request_observations;
2141
+ END IF;
2142
+ IF to_regclass('funding_deposits') IS NOT NULL AND to_regclass('routes_deposits') IS NULL THEN
2143
+ ALTER TABLE funding_deposits RENAME TO routes_deposits;
2144
+ END IF;
2145
+ IF to_regclass('funding_idempotency_requests') IS NOT NULL AND to_regclass('routes_idempotency_requests') IS NULL THEN
2146
+ ALTER TABLE funding_idempotency_requests RENAME TO routes_idempotency_requests;
2147
+ END IF;
2148
+ IF to_regclass('funding_routes') IS NOT NULL AND to_regclass('routes_routes') IS NULL THEN
2149
+ ALTER TABLE funding_routes RENAME TO routes_routes;
2150
+ END IF;
2151
+ IF to_regclass('funding_tokens') IS NOT NULL AND to_regclass('routes_tokens') IS NULL THEN
2152
+ ALTER TABLE funding_tokens RENAME TO routes_tokens;
2153
+ END IF;
2154
+ IF to_regclass('funding_transfer_events') IS NOT NULL AND to_regclass('routes_transfer_events') IS NULL THEN
2155
+ ALTER TABLE funding_transfer_events RENAME TO routes_transfer_events;
2156
+ END IF;
2157
+ IF to_regclass('funding_transfer_transactions') IS NOT NULL AND to_regclass('routes_transfer_transactions') IS NULL THEN
2158
+ ALTER TABLE funding_transfer_transactions RENAME TO routes_transfer_transactions;
2159
+ END IF;
2160
+ IF to_regclass('funding_transfers') IS NOT NULL AND to_regclass('routes_transfers') IS NULL THEN
2161
+ ALTER TABLE funding_transfers RENAME TO routes_transfers;
2162
+ END IF;
2163
+
2164
+ UPDATE routes_deposit_addresses
2165
+ SET snapshot = jsonb_set(snapshot, '{subsidize}', to_jsonb(subsidize), true)
2166
+ WHERE snapshot->'subsidize' IS DISTINCT FROM to_jsonb(subsidize);
2167
+
2168
+ FOR entry IN
2169
+ SELECT c.conname AS name, t.relname AS table_name
2170
+ FROM pg_constraint AS c
2171
+ JOIN pg_class AS t ON t.oid = c.conrelid
2172
+ JOIN pg_namespace AS n ON n.oid = t.relnamespace
2173
+ WHERE n.nspname = current_schema() AND c.conname LIKE 'funding\_%' ESCAPE '\\'
2174
+ LOOP
2175
+ target_name := regexp_replace(entry.name, '^funding_', 'routes_');
2176
+ EXECUTE format(
2177
+ 'ALTER TABLE %I.%I RENAME CONSTRAINT %I TO %I',
2178
+ current_schema(),
2179
+ entry.table_name,
2180
+ entry.name,
2181
+ target_name
2182
+ );
2183
+ END LOOP;
2184
+
2185
+ FOR entry IN
2186
+ SELECT indexname AS name
2187
+ FROM pg_indexes
2188
+ WHERE schemaname = current_schema() AND indexname LIKE 'funding\_%' ESCAPE '\\'
2189
+ LOOP
2190
+ target_name := regexp_replace(entry.name, '^funding_', 'routes_');
2191
+ IF to_regclass(target_name) IS NULL THEN
2192
+ EXECUTE format('ALTER INDEX %I.%I RENAME TO %I', current_schema(), entry.name, target_name);
2193
+ ELSE
2194
+ EXECUTE format('DROP INDEX %I.%I', current_schema(), entry.name);
2195
+ END IF;
2196
+ END LOOP;
2197
+ END $$`,
2198
+ ),
2199
+ },
2200
+ {
2201
+ // Correct the deelUSD router boundary so registry reads can verify its bytecode.
2202
+ name: '0191_deelusd_earn_router_deployment_block',
2203
+ up: (db) =>
2204
+ raw(
2205
+ db,
2206
+ sql`UPDATE earn_vaults
2207
+ SET zones = jsonb_set(zones, '{0,deploymentBlock}', '35822949'::jsonb)
2208
+ WHERE chain_id = 4217
2209
+ AND vault_address = '0x4f94590b636f5878bce585e82379de81e1ec174f'
2210
+ AND zones->0->>'chainId' = '421700001'
2211
+ AND lower(zones->0->>'earnRouter') = '0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'
2212
+ AND zones->0->>'deploymentBlock' = '35816964'`,
2213
+ ),
2214
+ },
2215
+ {
2216
+ name: '0192_reward_account_eligibility_registration',
2217
+ up: (db) =>
2218
+ raw(
2219
+ db,
2220
+ sql`ALTER TABLE reward_accounts ADD COLUMN IF NOT EXISTS eligibility_registered_at text`,
2221
+ ),
2222
+ },
2223
+ {
2224
+ name: '0193_routes_subsidies',
2225
+ up: (db) =>
2226
+ db.schema
2227
+ .createTable('routesSubsidies')
2228
+ .ifNotExists()
2229
+ .addColumn('apiKeyId', 'text')
2230
+ .addColumn('createdAt', 'text', (c) => c.notNull())
2231
+ .addColumn('enabled', 'boolean', (c) => c.notNull())
2232
+ .addColumn('frequency', 'text', (c) => c.notNull())
2233
+ .addColumn('maxAmount', 'text')
2234
+ .addColumn('orgId', 'text', (c) =>
2235
+ c.notNull().references('organizations.id').onDelete('cascade'),
2236
+ )
2237
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
2238
+ .addCheckConstraint('routes_subsidies_frequency_check', sql`frequency = 'tx'`)
2239
+ .addCheckConstraint(
2240
+ 'routes_subsidies_enabled_check',
2241
+ sql`CASE WHEN enabled THEN CASE WHEN max_amount ~ '^(0|[1-9][0-9]*)([.][0-9]{1,6})?$' THEN max_amount::numeric > 0 ELSE false END ELSE max_amount IS NULL END`,
2242
+ ),
2243
+ },
2244
+ {
2245
+ name: '0194_routes_subsidies_org_unique',
2246
+ up: (db) =>
2247
+ raw(
2248
+ db,
2249
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS routes_subsidies_org_unique ON routes_subsidies (org_id) WHERE api_key_id IS NULL`,
2250
+ ),
2251
+ },
2252
+ {
2253
+ name: '0195_routes_subsidies_api_key_unique',
2254
+ up: (db) =>
2255
+ raw(
2256
+ db,
2257
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS routes_subsidies_api_key_unique ON routes_subsidies (api_key_id) WHERE api_key_id IS NOT NULL`,
2258
+ ),
2259
+ },
2260
+ {
2261
+ name: '0196_routes_subsidies_backfill',
2262
+ up: (db) =>
2263
+ raw(
2264
+ db,
2265
+ sql`INSERT INTO routes_subsidies (api_key_id, created_at, enabled, frequency, max_amount, org_id, updated_at) SELECT NULL, created_at, true, 'tx', '5', id, updated_at FROM organizations ON CONFLICT DO NOTHING`,
2266
+ ),
2267
+ },
2268
+ {
2269
+ name: '0197_routes_deposits_subsidy_meter_reported_at',
2270
+ up: (db) =>
2271
+ raw(
2272
+ db,
2273
+ sql`ALTER TABLE routes_deposits ADD COLUMN IF NOT EXISTS subsidy_meter_reported_at text`,
2274
+ ),
2275
+ },
2276
+ {
2277
+ name: '0198_routes_deposits_unreported_subsidy_index',
2278
+ up: (db) =>
2279
+ raw(
2280
+ db,
2281
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_unreported_subsidy_idx ON routes_deposits (status_updated_at, id) WHERE environment = 'production' AND status = 'completed' AND settlement_transaction_hash IS NOT NULL AND subsidy_amount IS NOT NULL AND subsidy_meter_reported_at IS NULL`,
2282
+ ),
2283
+ },
2284
+ {
2285
+ name: '0199_routes_deposits_subsidy_usage_index',
2286
+ up: (db) =>
2287
+ raw(
2288
+ db,
2289
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_subsidy_usage_idx ON routes_deposits (org_id, environment, status_updated_at) WHERE status = 'completed' AND settlement_transaction_hash IS NOT NULL AND subsidy_amount IS NOT NULL`,
2290
+ ),
2291
+ },
2292
+ {
2293
+ name: '0200_routes_deposits_legacy_subsidies_reported',
2294
+ up: (db) =>
2295
+ raw(
2296
+ db,
2297
+ sql`UPDATE routes_deposits SET subsidy_meter_reported_at = coalesce(status_updated_at, updated_at) WHERE environment = 'production' AND settlement_transaction_hash IS NOT NULL AND subsidy_amount IS NOT NULL AND subsidy_meter_reported_at IS NULL`,
2298
+ ),
2299
+ },
2300
+ {
2301
+ name: '0201_routes_deposits_billable_subsidy_index',
2302
+ up: (db) =>
2303
+ raw(
2304
+ db,
2305
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_billable_subsidy_idx ON routes_deposits (status_updated_at, id) WHERE environment = 'production' AND settlement_transaction_hash IS NOT NULL AND subsidy_amount IS NOT NULL AND (subsidy_amount->>'baseUnits')::numeric > 0 AND subsidy_meter_reported_at IS NULL AND (status = 'completed' OR (status IN ('action-required', 'settling') AND tempo_gas_paid IS NOT NULL))`,
2306
+ ),
2307
+ },
2308
+ {
2309
+ name: '0202_routes_deposits_provider_subsidy',
2310
+ up: (db) =>
2311
+ raw(db, sql`ALTER TABLE routes_deposits ADD COLUMN IF NOT EXISTS provider_subsidy jsonb`),
2312
+ },
2313
+ {
2314
+ name: '0203_routes_deposits_billable_subsidy_index_v2',
2315
+ up: (db) =>
2316
+ raw(
2317
+ db,
2318
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_billable_subsidy_v2_idx ON routes_deposits (status_updated_at, id) WHERE environment = 'production' AND subsidy_meter_reported_at IS NULL AND (status = 'completed' OR (status IN ('action-required', 'settling') AND tempo_gas_paid IS NOT NULL)) AND (((provider_subsidy->'amount'->>'baseUnits')::numeric > 0) OR (settlement_transaction_hash IS NOT NULL AND (subsidy_amount->>'baseUnits')::numeric > 0))`,
2319
+ ),
2320
+ },
2321
+ {
2322
+ name: '0204_routes_deposits_subsidy_usage_index_v2',
2323
+ up: (db) =>
2324
+ raw(
2325
+ db,
2326
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_subsidy_usage_v2_idx ON routes_deposits (org_id, environment, subsidy_meter_reported_at) WHERE (provider_subsidy->'amount'->>'baseUnits')::numeric > 0 OR (subsidy_amount->>'baseUnits')::numeric > 0`,
2327
+ ),
2328
+ },
2329
+ {
2330
+ name: '0205_sponsored_transactions_admin_index',
2331
+ up: (db) =>
2332
+ raw(
2333
+ db,
2334
+ sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_admin_idx ON sponsored_transactions (created_at DESC, id DESC)`,
2335
+ ),
2336
+ },
2337
+ {
2338
+ name: '0206_routes_deposits_admin_subsidy_index',
2339
+ up: (db) =>
2340
+ raw(
2341
+ db,
2342
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_admin_subsidy_idx ON routes_deposits (updated_at DESC, id DESC) WHERE (provider_subsidy->'amount'->>'baseUnits')::numeric > 0 OR (subsidy_amount->>'baseUnits')::numeric > 0`,
2343
+ ),
2344
+ },
2345
+ {
2346
+ name: '0207_routes_deposit_addresses_drop_api_key',
2347
+ up: (db) => raw(db, sql`ALTER TABLE routes_deposit_addresses DROP COLUMN IF EXISTS api_key_id`),
2348
+ },
2349
+ {
2350
+ name: '0208_routes_subsidies_drop_api_key_policies',
2351
+ up: (db) =>
2352
+ raw(
2353
+ db,
2354
+ sql`DO $$
2355
+ BEGIN
2356
+ IF EXISTS (
2357
+ SELECT 1
2358
+ FROM information_schema.columns
2359
+ WHERE table_schema = current_schema()
2360
+ AND table_name = 'routes_subsidies'
2361
+ AND column_name = 'api_key_id'
2362
+ ) THEN
2363
+ DELETE FROM routes_subsidies WHERE api_key_id IS NOT NULL;
2364
+ END IF;
2365
+ END $$`,
2366
+ ),
2367
+ },
2368
+ {
2369
+ name: '0209_routes_subsidies_drop_api_key_indexes',
2370
+ up: (db) =>
2371
+ raw(
2372
+ db,
2373
+ sql`DROP INDEX IF EXISTS routes_subsidies_org_unique, routes_subsidies_api_key_unique`,
2374
+ ),
2375
+ },
2376
+ {
2377
+ name: '0210_routes_subsidies_drop_api_key',
2378
+ up: (db) => raw(db, sql`ALTER TABLE routes_subsidies DROP COLUMN IF EXISTS api_key_id`),
2379
+ },
2380
+ {
2381
+ name: '0211_routes_subsidies_org_unique',
2382
+ up: (db) =>
2383
+ raw(
2384
+ db,
2385
+ sql`CREATE UNIQUE INDEX IF NOT EXISTS routes_subsidies_org_unique ON routes_subsidies (org_id)`,
2386
+ ),
2387
+ },
2388
+ {
2389
+ name: '0212_routes_transfer_subsidy_nonces',
2390
+ up: (db) =>
2391
+ db.schema
2392
+ .createTable('routesTransferSubsidyNonces')
2393
+ .ifNotExists()
2394
+ .addColumn('account', 'text', (c) => c.notNull())
2395
+ .addColumn('chainId', 'text', (c) => c.notNull())
2396
+ .addColumn('nextNonce', 'text', (c) => c.notNull())
2397
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
2398
+ .addPrimaryKeyConstraint('routes_transfer_subsidy_nonces_pkey', ['chainId', 'account']),
2399
+ },
2400
+ {
2401
+ name: '0213_routes_transfers_subsidy_amount',
2402
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_amount jsonb`), // prettier-ignore
2403
+ },
2404
+ {
2405
+ name: '0214_routes_transfers_subsidy_meter_reported_at',
2406
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_meter_reported_at text`), // prettier-ignore
2407
+ },
2408
+ {
2409
+ name: '0215_routes_transfers_subsidy_transaction_hash',
2410
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_transaction_hash text`), // prettier-ignore
2411
+ },
2412
+ {
2413
+ name: '0216_routes_transfers_billable_subsidy_index',
2414
+ up: (db) =>
2415
+ raw(
2416
+ db,
2417
+ sql`CREATE INDEX IF NOT EXISTS routes_transfers_billable_subsidy_idx ON routes_transfers (status_updated_at, id) WHERE environment = 'production' AND status = 'completed' AND subsidy_transaction_hash IS NOT NULL AND subsidy_amount IS NOT NULL AND (subsidy_amount->>'baseUnits')::numeric > 0 AND subsidy_meter_reported_at IS NULL`,
2418
+ ),
2419
+ },
2420
+ {
2421
+ name: '0217_routes_transfers_subsidy_account',
2422
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_account text`), // prettier-ignore
2423
+ },
2424
+ {
2425
+ name: '0218_routes_transfers_subsidy_chain_id',
2426
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_chain_id text`), // prettier-ignore
2427
+ },
2428
+ {
2429
+ name: '0219_routes_transfers_subsidy_native_amount',
2430
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_native_amount text`), // prettier-ignore
2431
+ },
2432
+ {
2433
+ name: '0220_routes_transfers_subsidy_token_address',
2434
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_token_address text`), // prettier-ignore
2435
+ },
2436
+ {
2437
+ name: '0221_routes_transfers_subsidy_reservation_index',
2438
+ up: (db) =>
2439
+ raw(
2440
+ db,
2441
+ sql`CREATE INDEX IF NOT EXISTS routes_transfers_subsidy_reservation_idx ON routes_transfers (subsidy_chain_id, subsidy_account, subsidy_token_address) WHERE status IN ('processing', 'action-required') AND subsidy_amount IS NOT NULL AND (subsidy_amount->>'baseUnits')::numeric > 0`,
2442
+ ),
2443
+ },
2444
+ {
2445
+ name: '0222_routes_transfers_subsidy_commitment_amount',
2446
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS subsidy_commitment_amount jsonb`), // prettier-ignore
2447
+ },
2448
+ {
2449
+ name: '0223_routes_transfers_provider_delivered_at',
2450
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfers ADD COLUMN IF NOT EXISTS provider_delivered_at text`), // prettier-ignore
2451
+ },
2452
+ {
2453
+ name: '0224_routes_transfer_subsidy_nonces_blocked_at',
2454
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfer_subsidy_nonces ADD COLUMN IF NOT EXISTS blocked_at text`), // prettier-ignore
2455
+ },
2456
+ {
2457
+ name: '0225_routes_transfer_subsidy_nonces_blocked_transfer_id',
2458
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfer_subsidy_nonces ADD COLUMN IF NOT EXISTS blocked_transfer_id text`), // prettier-ignore
2459
+ },
2460
+ {
2461
+ name: '0226_routes_transfer_subsidy_nonces_blocked_reason',
2462
+ up: (db) => raw(db, sql`ALTER TABLE routes_transfer_subsidy_nonces ADD COLUMN IF NOT EXISTS blocked_reason text`), // prettier-ignore
2463
+ },
2464
+ {
2465
+ name: '0227_routes_transfers_subsidy_commitment_index',
2466
+ up: (db) =>
2467
+ raw(
2468
+ db,
2469
+ sql`CREATE INDEX IF NOT EXISTS routes_transfers_subsidy_commitment_idx ON routes_transfers (subsidy_chain_id, subsidy_account, subsidy_token_address) WHERE status IN ('awaiting-source', 'processing', 'action-required', 'refunding') AND subsidy_commitment_amount IS NOT NULL AND (subsidy_commitment_amount->>'baseUnits')::numeric > 0`,
2470
+ ),
2471
+ },
2472
+ {
2473
+ name: '0228_routes_transfer_subsidy_nonces_block_check',
2474
+ up: (db) =>
2475
+ raw(
2476
+ db,
2477
+ sql`DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'routes_transfer_subsidy_nonces_block_check' AND conrelid = 'routes_transfer_subsidy_nonces'::regclass) THEN ALTER TABLE routes_transfer_subsidy_nonces ADD CONSTRAINT routes_transfer_subsidy_nonces_block_check CHECK ((blocked_at IS NULL AND blocked_transfer_id IS NULL AND blocked_reason IS NULL) OR (blocked_at IS NOT NULL AND blocked_transfer_id IS NOT NULL AND blocked_reason = 'broadcast_rejected')); END IF; END $$`,
2478
+ ),
2479
+ },
2480
+ {
2481
+ // The test harness replays idempotent DDL on new connections, so legacy
2482
+ // index migrations still need this unused physical column to exist.
2483
+ name: '0229_routes_subsidies_legacy_api_key_compatibility',
2484
+ up: (db) => raw(db, sql`ALTER TABLE routes_subsidies ADD COLUMN IF NOT EXISTS api_key_id text`), // prettier-ignore
2485
+ },
2486
+ {
2487
+ name: '0230_routes_transfers_admin_subsidy_index',
2488
+ up: (db) =>
2489
+ raw(
2490
+ db,
2491
+ sql`CREATE INDEX IF NOT EXISTS routes_transfers_admin_subsidy_idx ON routes_transfers (updated_at DESC, id DESC) WHERE subsidy_amount IS NOT NULL AND (subsidy_amount->>'baseUnits')::numeric > 0`,
2492
+ ),
2493
+ },
2494
+ {
2495
+ name: '0231_routes_transfers_expired_subsidy_commitments_index',
2496
+ up: (db) =>
2497
+ raw(
2498
+ db,
2499
+ sql`CREATE INDEX IF NOT EXISTS routes_transfers_expired_subsidy_commitments_idx ON routes_transfers (quote_expires_at, id) WHERE status = 'awaiting-source' AND subsidy_commitment_amount IS NOT NULL AND (subsidy_commitment_amount->>'baseUnits')::numeric > 0`,
2500
+ ),
2501
+ },
2502
+ {
2503
+ name: '0232_sponsorship_reconciliation_cursors',
2504
+ up: (db) =>
2505
+ db.schema
2506
+ .createTable('sponsorshipReconciliationCursors')
2507
+ .ifNotExists()
2508
+ .addColumn('blockNumber', 'text', (c) => c.notNull())
2509
+ .addColumn('chainId', 'integer', (c) => c.notNull())
2510
+ .addColumn('feePayer', 'text', (c) => c.notNull())
2511
+ .addColumn('transactionIndex', 'integer', (c) => c.notNull())
2512
+ .addColumn('updatedAt', 'text', (c) => c.notNull())
2513
+ .addPrimaryKeyConstraint('sponsorship_reconciliation_cursors_pkey', [
2514
+ 'chainId',
2515
+ 'feePayer',
2516
+ ]),
2517
+ },
2518
+ {
2519
+ name: '0233_sponsored_transactions_recovery_index',
2520
+ up: (db) =>
2521
+ raw(
2522
+ db,
2523
+ sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_recovery_idx ON sponsored_transactions (finalized_at, chain_id, created_at) WHERE status = 'failed' AND transaction_hash IS NULL`,
2524
+ ),
2525
+ },
2526
+ {
2527
+ name: '0234_sponsorship_reconciliation_progress',
2528
+ up: (db) =>
2529
+ raw(
2530
+ db,
2531
+ sql`ALTER TABLE sponsorship_reconciliation_cursors ADD COLUMN IF NOT EXISTS complete boolean NOT NULL DEFAULT false, ADD COLUMN IF NOT EXISTS retry_count integer NOT NULL DEFAULT 0, ADD COLUMN IF NOT EXISTS retry_key text, ADD COLUMN IF NOT EXISTS revision text NOT NULL DEFAULT ''`,
2532
+ ),
2533
+ },
2534
+ {
2535
+ name: '0235_routes_deposits_unattributed_index',
2536
+ up: (db) =>
2537
+ raw(
2538
+ db,
2539
+ sql`CREATE INDEX IF NOT EXISTS routes_deposits_unattributed_idx ON routes_deposits (deposit_address_id, created_at, id) WHERE provider_request_id IS NULL`,
2540
+ ),
2541
+ },
2542
+ {
2543
+ name: '0236_routes_transfer_subsidies',
2544
+ up: (db) =>
2545
+ db.schema
2546
+ .createTable('routesTransferSubsidies')
2547
+ .ifNotExists()
2548
+ .addColumn('sourceChainId', 'text', (c) => c.notNull())
2549
+ .addColumn('transactionRef', 'text', (c) => c.notNull())
2550
+ .addColumn('destinationChainId', 'text', (c) => c.notNull())
2551
+ .addColumn('recipient', 'text', (c) => c.notNull())
2552
+ .addColumn('tokenAddress', 'text', (c) => c.notNull())
2553
+ .addColumn('transaction', 'jsonb', (c) => c.notNull())
2554
+ .addColumn('transferId', 'text', (c) => c.notNull())
2555
+ .addColumn('createdAt', 'text', (c) => c.notNull())
2556
+ .addPrimaryKeyConstraint('routes_transfer_subsidies_pkey', [
2557
+ 'sourceChainId',
2558
+ 'transactionRef',
2559
+ ]),
2560
+ },
2561
+ {
2562
+ name: '0237_routes_transfer_subsidies_capture',
2563
+ // Capture legacy Worker writes during rollout and retain settlement evidence after transfer deletion.
2564
+ up: (db) =>
2565
+ raw(
2566
+ db,
2567
+ sql`DO $$
2568
+ BEGIN
2569
+ LOCK TABLE routes_transfers IN SHARE ROW EXCLUSIVE MODE;
2570
+ INSERT INTO routes_transfer_subsidies (
2571
+ source_chain_id, transaction_ref, destination_chain_id, recipient,
2572
+ token_address, transaction, transfer_id, created_at
2573
+ )
2574
+ SELECT snapshot->'sourceChain'->>'id', snapshot->'sourceTransactionHashes'->>0,
2575
+ subsidy_chain_id, lower(snapshot->>'recipient'), subsidy_token_address,
2576
+ provider_state->'transferSubsidy', id, updated_at
2577
+ FROM routes_transfers
2578
+ WHERE subsidy_transaction_hash IS NOT NULL
2579
+ AND provider_state->'transferSubsidy' IS NOT NULL
2580
+ AND snapshot->'sourceTransactionHashes'->>0 IS NOT NULL
2581
+ ON CONFLICT DO NOTHING;
2582
+
2583
+ CREATE OR REPLACE FUNCTION capture_routes_transfer_subsidy() RETURNS trigger
2584
+ LANGUAGE plpgsql SET search_path FROM CURRENT AS $capture$
2585
+ DECLARE
2586
+ settlement routes_transfer_subsidies%ROWTYPE;
2587
+ source_chain text;
2588
+ source_ref text;
2589
+ BEGIN
2590
+ IF NEW.subsidy_transaction_hash IS NULL OR NEW.provider_state->'transferSubsidy' IS NULL THEN
2591
+ RETURN NEW;
2592
+ END IF;
2593
+ source_chain := NEW.snapshot->'sourceChain'->>'id';
2594
+ source_ref := NEW.snapshot->'sourceTransactionHashes'->>0;
2595
+ IF source_ref IS NULL THEN
2596
+ RAISE EXCEPTION 'Subsidy source evidence is missing';
2597
+ END IF;
2598
+ INSERT INTO routes_transfer_subsidies (
2599
+ source_chain_id, transaction_ref, destination_chain_id, recipient,
2600
+ token_address, transaction, transfer_id, created_at
2601
+ ) VALUES (
2602
+ source_chain, source_ref, NEW.subsidy_chain_id, lower(NEW.snapshot->>'recipient'),
2603
+ NEW.subsidy_token_address, NEW.provider_state->'transferSubsidy', NEW.id, NEW.updated_at
2604
+ ) ON CONFLICT DO NOTHING;
2605
+ SELECT * INTO STRICT settlement FROM routes_transfer_subsidies
2606
+ WHERE source_chain_id = source_chain AND transaction_ref = source_ref;
2607
+ IF settlement.transaction IS DISTINCT FROM NEW.provider_state->'transferSubsidy'
2608
+ OR settlement.destination_chain_id IS DISTINCT FROM NEW.subsidy_chain_id
2609
+ OR settlement.recipient IS DISTINCT FROM lower(NEW.snapshot->>'recipient')
2610
+ OR settlement.token_address IS DISTINCT FROM NEW.subsidy_token_address THEN
2611
+ RAISE EXCEPTION 'Source payment already has a different subsidy settlement';
2612
+ END IF;
2613
+ IF settlement.transfer_id <> NEW.id THEN
2614
+ NEW.subsidy_amount := NULL;
2615
+ NEW.subsidy_commitment_amount := NULL;
2616
+ NEW.subsidy_native_amount := NULL;
2617
+ END IF;
2618
+ RETURN NEW;
2619
+ END $capture$;
2620
+ DROP TRIGGER IF EXISTS routes_transfer_subsidy_capture ON routes_transfers;
2621
+ CREATE TRIGGER routes_transfer_subsidy_capture
2622
+ BEFORE INSERT OR UPDATE OF provider_state, subsidy_transaction_hash, subsidy_amount
2623
+ ON routes_transfers FOR EACH ROW EXECUTE FUNCTION capture_routes_transfer_subsidy();
2624
+ END $$`,
2625
+ ),
2626
+ },
2627
+ {
2628
+ name: '0238_routes_transfer_source_claim_scope',
2629
+ // Derive tenancy for old and new writers before replacing global source uniqueness.
2630
+ up: (db) =>
2631
+ raw(
2632
+ db,
2633
+ sql`DO $$
2634
+ BEGIN
2635
+ ALTER TABLE routes_transfer_transactions
2636
+ ADD COLUMN IF NOT EXISTS org_id text,
2637
+ ADD COLUMN IF NOT EXISTS environment text,
2638
+ ADD COLUMN IF NOT EXISTS project_id text;
2639
+ UPDATE routes_transfer_transactions AS evidence
2640
+ SET org_id = owner.org_id, environment = owner.environment, project_id = owner.project_id
2641
+ FROM routes_transfers AS owner WHERE owner.id = evidence.transfer_id;
2642
+ ALTER TABLE routes_transfer_transactions
2643
+ ALTER COLUMN org_id SET NOT NULL, ALTER COLUMN environment SET NOT NULL;
2644
+ CREATE OR REPLACE FUNCTION scope_routes_transfer_transaction() RETURNS trigger
2645
+ LANGUAGE plpgsql SET search_path FROM CURRENT AS $scope$
2646
+ BEGIN
2647
+ SELECT org_id, environment, project_id INTO STRICT NEW.org_id, NEW.environment, NEW.project_id
2648
+ FROM routes_transfers WHERE id = NEW.transfer_id;
2649
+ RETURN NEW;
2650
+ END $scope$;
2651
+ DROP TRIGGER IF EXISTS routes_transfer_transaction_scope ON routes_transfer_transactions;
2652
+ CREATE TRIGGER routes_transfer_transaction_scope
2653
+ BEFORE INSERT OR UPDATE ON routes_transfer_transactions
2654
+ FOR EACH ROW EXECUTE FUNCTION scope_routes_transfer_transaction();
2655
+ CREATE UNIQUE INDEX IF NOT EXISTS routes_transfer_transactions_source_owner_unique
2656
+ ON routes_transfer_transactions (org_id, environment, project_id, chain_id, transaction_ref)
2657
+ NULLS NOT DISTINCT WHERE role = 'source';
2658
+ DROP INDEX IF EXISTS routes_transfer_transactions_source_unique;
2659
+ END $$`,
2660
+ ),
2661
+ },
2662
+ {
2663
+ name: '0239_routes_transfer_source_lookup_index',
2664
+ up: (db) =>
2665
+ raw(
2666
+ db,
2667
+ sql`CREATE INDEX IF NOT EXISTS routes_transfer_transactions_source_lookup_idx ON routes_transfer_transactions (chain_id, transaction_ref) WHERE role = 'source'`,
2668
+ ),
2669
+ },
2670
+ {
2671
+ name: '0240_sponsored_transactions_finalization_attempted_at',
2672
+ up: (db) =>
2673
+ raw(
2674
+ db,
2675
+ sql`ALTER TABLE sponsored_transactions ADD COLUMN IF NOT EXISTS finalization_attempted_at text`,
2676
+ ),
2677
+ },
2678
+ {
2679
+ name: '0241_sponsored_transactions_finalization_queue_index',
2680
+ up: (db) =>
2681
+ raw(
2682
+ db,
2683
+ sql`CREATE INDEX IF NOT EXISTS sponsored_transactions_finalization_queue_idx ON sponsored_transactions (finalization_attempted_at NULLS FIRST, created_at, id) WHERE status = 'pending'`,
2684
+ ),
2685
+ },
2686
+ {
2687
+ name: '0242_api_key_owner_tombstones',
2688
+ up: (db) =>
2689
+ db.schema
2690
+ .createTable('api_key_owner_tombstones')
2691
+ .ifNotExists()
2692
+ .addColumn('id', 'text', (column) => column.primaryKey())
2693
+ .addColumn('createdAt', 'text', (column) => column.notNull()),
2694
+ },
2695
+ {
2696
+ name: '0243_api_key_owner_admissions',
2697
+ up: (db) =>
2698
+ db.schema
2699
+ .createTable('api_key_owner_admissions')
2700
+ .ifNotExists()
2701
+ .addColumn('orgId', 'text', (column) => column.primaryKey())
2702
+ .addColumn('liveKeys', 'integer', (column) => column.notNull())
2703
+ .addColumn('updatedAt', 'text', (column) => column.notNull()),
2704
+ },
2705
+ {
2706
+ name: '0244_api_key_admissions',
2707
+ up: (db) =>
2708
+ db.schema
2709
+ .createTable('api_key_admissions')
2710
+ .ifNotExists()
2711
+ .addColumn('expiresAt', 'text')
2712
+ .addColumn('id', 'text', (column) => column.notNull().unique())
2713
+ .addColumn('orgId', 'text', (column) => column.notNull())
2714
+ .addColumn('projectId', 'text')
2715
+ .addPrimaryKeyConstraint('api_key_admissions_pkey', ['orgId', 'id']),
2716
+ },
2717
+ {
2718
+ name: '0245_api_key_admission_bootstraps',
2719
+ up: (db) =>
2720
+ db.schema
2721
+ .createTable('api_key_admission_bootstraps')
2722
+ .ifNotExists()
2723
+ .addColumn('orgId', 'text', (column) => column.primaryKey())
2724
+ .addColumn('bootstrappedAt', 'text', (column) => column.notNull()),
2725
+ },
2726
+ {
2727
+ name: '0246_api_key_revocations',
2728
+ up: (db) =>
2729
+ db.schema
2730
+ .createTable('api_key_revocations')
2731
+ .ifNotExists()
2732
+ .addColumn('id', 'text', (column) => column.primaryKey())
2733
+ .addColumn('revokedAt', 'text', (column) => column.notNull()),
2734
+ },
2735
+ {
2736
+ name: '0247_api_key_revocation_lifecycle',
2737
+ up: (db) =>
2738
+ raw(
2739
+ db,
2740
+ sql`ALTER TABLE api_key_revocations ADD COLUMN IF NOT EXISTS org_id text REFERENCES organizations(id) ON DELETE CASCADE, ADD COLUMN IF NOT EXISTS expires_at text`,
2741
+ ),
2742
+ },
2743
+ {
2744
+ name: '0248_api_key_revocation_expiry_backfill',
2745
+ up: (db) =>
2746
+ raw(
2747
+ db,
2748
+ sql`UPDATE api_key_revocations SET expires_at = to_char(revoked_at::timestamptz + interval '7 days', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') WHERE expires_at IS NULL`,
2749
+ ),
2750
+ },
2751
+ {
2752
+ name: '0249_api_key_revocation_expiry_required',
2753
+ up: (db) => raw(db, sql`ALTER TABLE api_key_revocations ALTER COLUMN expires_at SET NOT NULL`),
2754
+ },
2755
+ {
2756
+ name: '0250_api_key_revocation_expiry_index',
2757
+ up: (db) =>
2758
+ raw(
2759
+ db,
2760
+ sql`CREATE INDEX IF NOT EXISTS api_key_revocations_expiry_idx ON api_key_revocations (expires_at, id)`,
2761
+ ),
2762
+ },
2763
+ {
2764
+ name: '0251_api_key_revocation_org_index',
2765
+ up: (db) =>
2766
+ raw(
2767
+ db,
2768
+ sql`CREATE INDEX IF NOT EXISTS api_key_revocations_org_idx ON api_key_revocations (org_id) WHERE org_id IS NOT NULL`,
2769
+ ),
2770
+ },
2771
+ {
2772
+ // Triggers make migrate-before-deploy safe: older Workers still fence raw owner deletes and acquire the same locks as new key writes.
2773
+ name: '0252_api_key_owner_delete_trigger_function',
2774
+ up: (db) =>
2775
+ raw(
2776
+ db,
2777
+ sql`CREATE OR REPLACE FUNCTION api_key_fence_deleted_owner() RETURNS trigger LANGUAGE plpgsql AS $api_key_fence$
2778
+ DECLARE owner_key text;
2779
+ BEGIN
2780
+ IF TG_TABLE_NAME = 'organizations' THEN
2781
+ owner_key := 'organization:' || OLD.id;
2782
+ ELSE
2783
+ PERFORM pg_advisory_xact_lock(hashtextextended('organization:' || OLD.org_id, 0));
2784
+ owner_key := 'project:' || OLD.org_id || ':' || OLD.id;
2785
+ END IF;
2786
+ PERFORM pg_advisory_xact_lock(hashtextextended(owner_key, 0));
2787
+ EXECUTE format('INSERT INTO %I.api_key_owner_tombstones (id, created_at) VALUES ($1, $2) ON CONFLICT (id) DO NOTHING', TG_TABLE_SCHEMA)
2788
+ USING owner_key, to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"');
2789
+ RETURN OLD;
2790
+ END
2791
+ $api_key_fence$`,
2792
+ ),
2793
+ },
2794
+ {
2795
+ name: '0253_api_key_organization_delete_trigger',
2796
+ up: (db) =>
2797
+ raw(
2798
+ db,
2799
+ sql`DO $api_key_trigger$
2800
+ BEGIN
2801
+ IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'api_key_fence_deleted_organization' AND tgrelid = 'organizations'::regclass) THEN
2802
+ CREATE TRIGGER api_key_fence_deleted_organization BEFORE DELETE ON organizations FOR EACH ROW EXECUTE FUNCTION api_key_fence_deleted_owner();
2803
+ END IF;
2804
+ END
2805
+ $api_key_trigger$`,
2806
+ ),
2807
+ },
2808
+ {
2809
+ name: '0254_api_key_project_delete_trigger',
2810
+ up: (db) =>
2811
+ raw(
2812
+ db,
2813
+ sql`DO $api_key_trigger$
2814
+ BEGIN
2815
+ IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgname = 'api_key_fence_deleted_project' AND tgrelid = 'projects'::regclass) THEN
2816
+ CREATE TRIGGER api_key_fence_deleted_project BEFORE DELETE ON projects FOR EACH ROW EXECUTE FUNCTION api_key_fence_deleted_owner();
2817
+ END IF;
2818
+ END
2819
+ $api_key_trigger$`,
2820
+ ),
2821
+ },
2822
+ {
2823
+ // The table lock partitions legacy writers; a 24-hour organization-deletion embargo lets pre-fence Worker requests finish before owners can disappear.
2824
+ name: '0255_routes_organization_delete_fence',
2825
+ up: (db) =>
2826
+ raw(
2827
+ db,
2828
+ sql`DO $migration$ BEGIN LOCK TABLE routes_idempotency_requests IN SHARE ROW EXCLUSIVE MODE; EXECUTE $definition$ CREATE OR REPLACE FUNCTION api_key_fence_deleted_owner() RETURNS trigger LANGUAGE plpgsql AS $body$ DECLARE owner_key text; BEGIN IF TG_TABLE_NAME = 'organizations' THEN PERFORM pg_advisory_xact_lock(hashtextextended('routes-subsidy:' || OLD.id, 0)); PERFORM pg_advisory_xact_lock(hashtextextended('routes-ownerless-legacy', 0)); owner_key := 'organization:' || OLD.id; ELSE PERFORM pg_advisory_xact_lock(hashtextextended('organization:' || OLD.org_id, 0)); owner_key := 'project:' || OLD.org_id || ':' || OLD.id; END IF; PERFORM pg_advisory_xact_lock(hashtextextended(owner_key, 0)); EXECUTE format('INSERT INTO %I.api_key_owner_tombstones (id, created_at) VALUES ($1, $2) ON CONFLICT (id) DO NOTHING', TG_TABLE_SCHEMA) USING owner_key, to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'); IF TG_TABLE_NAME = 'organizations' THEN EXECUTE format('INSERT INTO %I.api_key_owner_tombstones (id, created_at) VALUES ($1, $2) ON CONFLICT (id) DO NOTHING', TG_TABLE_SCHEMA) USING 'routes-ownerless-legacy-cutoff', to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'); END IF; RETURN OLD; END $body$ $definition$; EXECUTE $definition$ CREATE OR REPLACE FUNCTION fence_routes_organization_delete() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ BEGIN PERFORM pg_advisory_xact_lock(hashtextextended('routes-ownerless-legacy', 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'routes-legacy-attempt-drain' AND created_at::timestamptz + interval '24 hours' > CURRENT_TIMESTAMP) THEN RAISE EXCEPTION 'route lifecycle rollout drain is active' USING ERRCODE = '23503'; END IF; IF EXISTS (SELECT 1 FROM routes_deposit_addresses WHERE org_id = OLD.id AND (status != 'deactivated' OR (provider_id = 'relay' AND subsidize))) OR EXISTS (SELECT 1 FROM routes_idempotency_requests AS request WHERE request.status IN ('pending', 'provisioned') AND (request.expires_at::timestamptz > CURRENT_TIMESTAMP OR COALESCE((to_jsonb(request)->>'irrevocable')::boolean, false)) AND (((to_jsonb(request)->>'org_id') = OLD.id AND (to_jsonb(request)->>'operation') = 'deposit_address') OR to_jsonb(request)->>'org_id' IS NULL OR to_jsonb(request)->>'operation' IS NULL)) THEN RAISE EXCEPTION 'organization has active route deposit address work' USING ERRCODE = '23503'; END IF; RETURN OLD; END $body$ $definition$; EXECUTE $definition$ CREATE OR REPLACE FUNCTION fence_routes_deposit_address_owner() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ BEGIN PERFORM pg_advisory_xact_lock(hashtextextended('routes-subsidy:' || NEW.org_id, 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'organization:' || NEW.org_id) THEN RAISE EXCEPTION 'route deposit address owner was deleted' USING ERRCODE = '23503'; END IF; RETURN NEW; END $body$ $definition$; EXECUTE $definition$ CREATE OR REPLACE FUNCTION fence_routes_idempotency_owner() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ DECLARE owner_id text; BEGIN owner_id := to_jsonb(NEW)->>'org_id'; IF owner_id IS NULL THEN SELECT org_id INTO owner_id FROM api_key_admissions WHERE id = NEW.api_key_id; END IF; IF owner_id IS NULL THEN PERFORM pg_advisory_xact_lock(hashtextextended('routes-ownerless-legacy', 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'routes-ownerless-legacy-cutoff') THEN RAISE EXCEPTION 'ownerless route idempotency creation is disabled' USING ERRCODE = '23503'; END IF; RETURN NEW; END IF; PERFORM pg_advisory_xact_lock(hashtextextended('routes-subsidy:' || owner_id, 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'organization:' || owner_id) THEN RAISE EXCEPTION 'route idempotency owner was deleted' USING ERRCODE = '23503'; END IF; RETURN NEW; END $body$ $definition$; EXECUTE 'CREATE OR REPLACE TRIGGER routes_deposit_address_owner_fence BEFORE INSERT OR UPDATE OF org_id ON routes_deposit_addresses FOR EACH ROW EXECUTE FUNCTION fence_routes_deposit_address_owner()'; EXECUTE 'CREATE OR REPLACE TRIGGER routes_idempotency_owner_fence BEFORE INSERT OR UPDATE ON routes_idempotency_requests FOR EACH ROW EXECUTE FUNCTION fence_routes_idempotency_owner()'; EXECUTE 'CREATE OR REPLACE TRIGGER routes_organization_delete_fence BEFORE DELETE ON organizations FOR EACH ROW EXECUTE FUNCTION fence_routes_organization_delete()'; INSERT INTO api_key_owner_tombstones (id, created_at) VALUES ('routes-legacy-attempt-drain', to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')) ON CONFLICT (id) DO NOTHING; END $migration$`,
2829
+ ),
2830
+ },
2831
+ {
2832
+ name: '0256_routes_idempotency_organization',
2833
+ up: (db) =>
2834
+ raw(db, sql`ALTER TABLE routes_idempotency_requests ADD COLUMN IF NOT EXISTS org_id text`),
2835
+ },
2836
+ {
2837
+ name: '0257_routes_idempotency_operation',
2838
+ up: (db) =>
2839
+ raw(db, sql`ALTER TABLE routes_idempotency_requests ADD COLUMN IF NOT EXISTS operation text`),
2840
+ },
2841
+ {
2842
+ name: '0258_routes_idempotency_irrevocable',
2843
+ up: (db) =>
2844
+ raw(
2845
+ db,
2846
+ sql`ALTER TABLE routes_idempotency_requests ADD COLUMN IF NOT EXISTS irrevocable boolean NOT NULL DEFAULT false`,
2847
+ ),
2848
+ },
2849
+ {
2850
+ name: '0259_routes_idempotency_organization_inflight_index',
2851
+ up: (db) =>
2852
+ raw(
2853
+ db,
2854
+ sql`CREATE INDEX IF NOT EXISTS routes_idempotency_requests_organization_inflight_idx ON routes_idempotency_requests (org_id) WHERE org_id IS NOT NULL AND operation = 'deposit_address' AND status IN ('pending', 'provisioned')`,
2855
+ ),
2856
+ },
2857
+ {
2858
+ name: '0260_routes_idempotency_match_hash',
2859
+ up: (db) =>
2860
+ raw(
2861
+ db,
2862
+ sql`ALTER TABLE routes_idempotency_requests ADD COLUMN IF NOT EXISTS match_hash text`,
2863
+ ),
2864
+ },
2865
+ {
2866
+ name: '0261_routes_idempotency_match_inflight_index',
2867
+ up: (db) =>
2868
+ raw(
2869
+ db,
2870
+ sql`CREATE INDEX IF NOT EXISTS routes_idempotency_requests_match_inflight_idx ON routes_idempotency_requests (org_id, match_hash) WHERE match_hash IS NOT NULL AND operation = 'deposit_address' AND status IN ('pending', 'provisioned')`,
2871
+ ),
2872
+ },
2873
+ {
2874
+ name: '0262_routes_organization_delete_fence_unattributed_checkpoint',
2875
+ up: (db) =>
2876
+ raw(
2877
+ db,
2878
+ sql`CREATE OR REPLACE FUNCTION fence_routes_organization_delete() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ BEGIN PERFORM pg_advisory_xact_lock(hashtextextended('routes-ownerless-legacy', 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'routes-legacy-attempt-drain' AND created_at::timestamptz + interval '24 hours' > CURRENT_TIMESTAMP) THEN RAISE EXCEPTION 'route lifecycle rollout drain is active' USING ERRCODE = '23503'; END IF; IF EXISTS (SELECT 1 FROM routes_deposit_addresses WHERE org_id = OLD.id AND (status != 'deactivated' OR (provider_id = 'relay' AND subsidize))) OR EXISTS (SELECT 1 FROM routes_idempotency_requests AS request WHERE request.status IN ('pending', 'provisioned') AND (request.expires_at::timestamptz > CURRENT_TIMESTAMP OR COALESCE((to_jsonb(request)->>'irrevocable')::boolean, false)) AND (((to_jsonb(request)->>'org_id') = OLD.id AND (to_jsonb(request)->>'operation') = 'deposit_address') OR to_jsonb(request)->>'org_id' IS NULL OR to_jsonb(request)->>'operation' IS NULL)) THEN RAISE EXCEPTION 'organization has active route deposit address work' USING ERRCODE = '23503'; END IF; RETURN OLD; END $body$`,
2879
+ ),
2880
+ },
2881
+ {
2882
+ // Rolling workers may insert after preflight; these triggers share the deletion lock and reject owners deleted while provisioning.
2883
+ name: '0263_routes_creation_owner_fences',
2884
+ up: (db) =>
2885
+ raw(
2886
+ db,
2887
+ sql`DO $migration$ BEGIN EXECUTE $definition$ CREATE OR REPLACE FUNCTION fence_routes_idempotency_owner() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ DECLARE owner_id text; BEGIN owner_id := NEW.org_id; IF owner_id IS NULL THEN SELECT org_id INTO owner_id FROM api_key_admissions WHERE id = NEW.api_key_id; END IF; IF owner_id IS NULL THEN PERFORM pg_advisory_xact_lock(hashtextextended('routes-ownerless-legacy', 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'routes-ownerless-legacy-cutoff') THEN RAISE EXCEPTION 'ownerless route idempotency creation is disabled' USING ERRCODE = '23503'; END IF; RETURN NEW; END IF; PERFORM pg_advisory_xact_lock(hashtextextended('routes-subsidy:' || owner_id, 0)); IF EXISTS (SELECT 1 FROM api_key_owner_tombstones WHERE id = 'organization:' || owner_id) THEN RAISE EXCEPTION 'route idempotency owner was deleted' USING ERRCODE = '23503'; END IF; RETURN NEW; END $body$ $definition$; EXECUTE 'CREATE OR REPLACE TRIGGER routes_idempotency_owner_fence BEFORE INSERT OR UPDATE OF org_id, status ON routes_idempotency_requests FOR EACH ROW EXECUTE FUNCTION fence_routes_idempotency_owner()'; END $migration$`,
2888
+ ),
2889
+ },
2890
+ {
2891
+ // Existing unattributed checkpoints get one bounded drain window because their subsidy intent cannot be reconstructed.
2892
+ name: '0264_routes_legacy_checkpoint_drain',
2893
+ up: (db) =>
2894
+ raw(
2895
+ db,
2896
+ sql`WITH marker AS (INSERT INTO api_key_owner_tombstones (id, created_at) VALUES ('routes-legacy-checkpoint-drain', to_char(clock_timestamp() AT TIME ZONE 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')) ON CONFLICT (id) DO UPDATE SET created_at = api_key_owner_tombstones.created_at RETURNING created_at) UPDATE routes_idempotency_requests AS request SET expires_at = to_char(marker.created_at::timestamptz + interval '24 hours', 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"') FROM marker WHERE request.status = 'provisioned' AND (request.org_id IS NULL OR request.operation IS NULL) AND request.expires_at::timestamptz < marker.created_at::timestamptz + interval '24 hours'`,
2897
+ ),
2898
+ },
2899
+ {
2900
+ name: '0265_routes_deposit_address_creator',
2901
+ up: (db) =>
2902
+ raw(
2903
+ db,
2904
+ sql`DO $migration$ BEGIN ALTER TABLE routes_deposit_addresses ADD COLUMN IF NOT EXISTS creator_user_id text; UPDATE routes_deposit_addresses AS address SET creator_user_id = organization.user_id FROM organizations AS organization WHERE address.org_id = organization.id AND address.creator_user_id IS NULL; CREATE INDEX IF NOT EXISTS routes_deposit_addresses_creator_user_idx ON routes_deposit_addresses (creator_user_id) WHERE creator_user_id IS NOT NULL; EXECUTE $definition$ CREATE OR REPLACE FUNCTION set_routes_deposit_address_creator() RETURNS trigger LANGUAGE plpgsql SET search_path FROM CURRENT AS $body$ BEGIN NEW.creator_user_id := (SELECT user_id FROM organizations WHERE id = NEW.org_id); RETURN NEW; END $body$ $definition$; EXECUTE 'CREATE OR REPLACE TRIGGER routes_deposit_address_creator BEFORE INSERT OR UPDATE OF org_id ON routes_deposit_addresses FOR EACH ROW EXECUTE FUNCTION set_routes_deposit_address_creator()'; END $migration$`,
2905
+ ),
2906
+ },
2907
+ {
2908
+ name: '0266_reward_credits',
2909
+ up: (db) =>
2910
+ db.schema
2911
+ .createTable('rewardCredits')
2912
+ .ifNotExists()
2913
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
2914
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
2915
+ .addColumn('recipient', 'text', (c) => c.notNull())
2916
+ .addColumn('reference', 'text', (c) => c.notNull())
2917
+ .addColumn('assets', 'numeric', (c) => c.notNull())
2918
+ .addColumn('createdAt', 'text', (c) => c.notNull())
2919
+ .addPrimaryKeyConstraint('reward_credits_pkey', [
2920
+ 'chainId',
2921
+ 'vaultAddress',
2922
+ 'recipient',
2923
+ 'reference',
2924
+ ])
2925
+ // Runs rewrite reward_accounts wholesale, so the ledger must not cascade from it.
2926
+ .addForeignKeyConstraint(
2927
+ 'reward_credits_campaign_fkey',
2928
+ ['chainId', 'vaultAddress'],
2929
+ 'rewardCampaigns',
2930
+ ['chainId', 'vaultAddress'],
2931
+ (c) => c.onDelete('cascade'),
2932
+ ),
2933
+ },
2934
+ {
2935
+ name: '0267_reward_campaign_distributors',
2936
+ up: (db) =>
2937
+ db.schema
2938
+ .createTable('rewardCampaignDistributors')
2939
+ .ifNotExists()
2940
+ .addColumn('chainId', 'bigint', (c) => c.notNull())
2941
+ .addColumn('vaultAddress', 'text', (c) => c.notNull())
2942
+ .addColumn('distributorAddress', 'text', (c) => c.notNull())
2943
+ .addColumn('createdAt', 'text', (c) => c.notNull())
2944
+ .addPrimaryKeyConstraint('reward_campaign_distributors_pkey', [
2945
+ 'chainId',
2946
+ 'vaultAddress',
2947
+ 'distributorAddress',
2948
+ ])
2949
+ .addForeignKeyConstraint(
2950
+ 'reward_campaign_distributors_campaign_fkey',
2951
+ ['chainId', 'vaultAddress'],
2952
+ 'rewardCampaigns',
2953
+ ['chainId', 'vaultAddress'],
2954
+ (c) => c.onDelete('cascade'),
2955
+ ),
2956
+ },
2957
+ {
2958
+ name: '0268_reward_campaign_distributors_backfill',
2959
+ up: (db) =>
2960
+ raw(
2961
+ db,
2962
+ sql`INSERT INTO reward_campaign_distributors (chain_id, vault_address, distributor_address, created_at) SELECT chain_id, vault_address, distributor_address, updated_at FROM reward_campaigns WHERE distributor_address IS NOT NULL ON CONFLICT DO NOTHING`,
2963
+ ),
2964
+ },
2965
+ {
2966
+ // This verified distributor paid rewards before distributor history was retained.
2967
+ name: '0269_reward_campaign_previous_distributor',
2968
+ up: (db) =>
2969
+ raw(
2970
+ db,
2971
+ sql`INSERT INTO reward_campaign_distributors (chain_id, vault_address, distributor_address, created_at) SELECT chain_id, vault_address, '0x6c857bf1fe7de1bc1d5c639c721b2633f8fe34f3', created_at FROM reward_campaigns WHERE chain_id = 4217 AND vault_address = '0xd730394f3bb85a4828e35fc5e361dcc9f894fa4f' ON CONFLICT DO NOTHING`,
2972
+ ),
2973
+ },
1526
2974
  ]
1527
2975
 
1528
2976
  /**
@@ -1554,10 +3002,7 @@ function fromDialect(dialect: Dialect, options: fromDialect.Options = {}): Db {
1554
3002
  // transaction poolers reset session state between statements.
1555
3003
  const kysely = options.schema ? root.withPlugin(new WithSchemaPlugin(options.schema)) : root
1556
3004
  // Builds Db over a top-level Kysely handle or transaction-scoped Kysely handle.
1557
- function build(kysely: Kysely<Database>): Db {
1558
- // Prevents same-handle nested transactions from deadlocking capped pools.
1559
- // Nested work must use the callback's scoped `tx`.
1560
- let active = false
3005
+ function build(kysely: Kysely<Database>, transactional = false): Db {
1561
3006
  return {
1562
3007
  async close() {
1563
3008
  await kysely.destroy()
@@ -1630,13 +3075,8 @@ function fromDialect(dialect: Dialect, options: fromDialect.Options = {}): Db {
1630
3075
  })
1631
3076
  },
1632
3077
  async transaction(fn) {
1633
- if (active) throw new Error('Db.transaction does not support nesting.')
1634
- active = true
1635
- try {
1636
- return await kysely.transaction().execute((trx) => fn(build(trx)))
1637
- } finally {
1638
- active = false
1639
- }
3078
+ if (transactional) throw new Error('Db.transaction does not support nesting.')
3079
+ return kysely.transaction().execute((trx) => fn(build(trx, true)))
1640
3080
  },
1641
3081
  }
1642
3082
  }
@@ -1653,20 +3093,20 @@ declare namespace fromDialect {
1653
3093
 
1654
3094
  /**
1655
3095
  * Creates a Postgres-backed {@link Db} via Kysely's `PostgresDialect`. Optional
1656
- * `schema` qualifies repository queries, scopes migrations, and caps the pool.
3096
+ * `schema` qualifies repository queries and scopes migrations.
1657
3097
  *
1658
3098
  * @param options - Postgres options.
1659
3099
  * @returns The database.
1660
3100
  */
1661
3101
  export function postgres(options: postgres.Options): Db {
1662
- const { connectionString, schema } = options
3102
+ const { connectionString, maxConnections, schema } = options
1663
3103
  // Bounded connect and pool-checkout wait: the pg default (0) waits forever,
1664
3104
  // so an unresponsive origin parks callers and their invocation memory
1665
3105
  // invisibly instead of failing into the retry paths.
1666
3106
  const pool = new pg.Pool({
1667
3107
  connectionString,
1668
3108
  connectionTimeoutMillis: 30_000,
1669
- ...(schema ? { max: 1 } : {}),
3109
+ ...(maxConnections === undefined && !schema ? {} : { max: maxConnections ?? 1 }),
1670
3110
  })
1671
3111
  return fromDialect(new PostgresDialect({ pool }), { schema })
1672
3112
  }
@@ -1676,6 +3116,8 @@ export declare namespace postgres {
1676
3116
  type Options = {
1677
3117
  /** Postgres connection string (`postgresql://…`). */
1678
3118
  connectionString: string
3119
+ /** Maximum connections held by this local pool; defaults to `1` with schema scoping. */
3120
+ maxConnections?: number | undefined
1679
3121
  /** Schema to qualify and create during migration (isolates concurrent tests). */
1680
3122
  schema?: string | undefined
1681
3123
  }