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
@@ -19,10 +19,13 @@ import * as Fees from '../../internal/Fees.js'
19
19
  import type * as Log from '../../internal/Log.js'
20
20
  import * as Organizations from '../../db/tables/organizations.js'
21
21
  import * as Projects from '../../db/tables/projects.js'
22
+ import * as SponsorshipAttributions from '../../db/tables/sponsorshipAttributions.js'
23
+ import * as SponsorshipReconciliationCursors from '../../db/tables/sponsorshipReconciliationCursors.js'
22
24
  import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
23
25
  import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
24
26
  import * as core_Billing from '../management/Billing.js'
25
27
  import * as RequestListener from '../../handlers/internal/requestListener.js'
28
+ import * as Tidx from '../../internal/Tidx.js'
26
29
  import * as Viem from '../../internal/Viem.js'
27
30
  import * as Sponsorships from './Sponsorships.js'
28
31
 
@@ -34,7 +37,7 @@ const zone = runtime.zone.chainId
34
37
  const zoneScope = `zone:${zone}:read` as const
35
38
  const zoneOptions = TestApp.zone({
36
39
  chainId: zone,
37
- rpcUrl: runtime.zone.publicZoneUrl,
40
+ rpcUrl: runtime.zone.internalRpcUrl,
38
41
  })
39
42
 
40
43
  /** Super admin secret configured on the end-to-end billing app. */
@@ -42,6 +45,14 @@ const superAdminSecret = 'tempo:sk:a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a
42
45
 
43
46
  /** Keys covering the sponsorship policy matrix. */
44
47
  const keys = [
48
+ {
49
+ environment: 'sandbox',
50
+ id: 'key_relay_sponsor',
51
+ orgId: 'org_1',
52
+ projectId: 'prj_1',
53
+ scopes: ['rpc-relay:read', 'rpc-relay:sponsor'],
54
+ token: 'secret_relay_sponsor',
55
+ },
45
56
  {
46
57
  id: 'key_sponsor',
47
58
  orgId: 'org_1',
@@ -226,6 +237,139 @@ describe('behavior: Zone chain routing', () => {
226
237
  expect(body).toMatchObject({ result: `0x${zone.toString(16)}` })
227
238
  })
228
239
 
240
+ test.each(['relay', 'sponsor'] as const)(
241
+ 'rejects a Zone token without a public RPC on %s',
242
+ async (mount) => {
243
+ const calls: string[] = []
244
+ const server = await Relay.createServer(
245
+ RequestListener.fromFetchHandler(async (request) => {
246
+ calls.push(await request.text())
247
+ return Response.json({ id: 1, jsonrpc: '2.0', result: Hex.fromNumber(zone) })
248
+ }),
249
+ )
250
+ try {
251
+ const api = TestApp.create({
252
+ auth: { keys },
253
+ rpc: { auth: 'internal:secret', url: server.url },
254
+ zones: [TestApp.zone({ chainId: zone, rpcUrl: server.url })],
255
+ })
256
+ const body = await request(api, {
257
+ body: { id: 1, jsonrpc: '2.0', method: 'eth_chainId' },
258
+ mount,
259
+ pathChainId: zone,
260
+ zoneToken: 'unvalidated-token',
261
+ })
262
+
263
+ expect(body).toMatchObject({ error: { code: -32_603 } })
264
+ expect(calls).toMatchInlineSnapshot(`[]`)
265
+ } finally {
266
+ await server.closeAsync()
267
+ }
268
+ },
269
+ )
270
+
271
+ test.each(['relay', 'sponsor'] as const)(
272
+ 'blocks privileged Zone methods before %s dispatch',
273
+ async (mount) => {
274
+ const calls: string[] = []
275
+ const server = await Relay.createServer(
276
+ RequestListener.fromFetchHandler(async (request) => {
277
+ calls.push(await request.text())
278
+ return Response.json({ id: 1, jsonrpc: '2.0', result: null })
279
+ }),
280
+ )
281
+ try {
282
+ for (const selector of ['path', 'body', 'default'] as const) {
283
+ const api = TestApp.create({
284
+ auth: { keys },
285
+ ...(selector === 'default' ? { defaultChainId: zone } : {}),
286
+ rpc: { publicZoneUrl: server.url, url: 'http://internal.zone.test' },
287
+ zones: [TestApp.zone({ chainId: zone, rpcUrl: 'http://internal.zone.test' })],
288
+ })
289
+ for (const method of [
290
+ 'admin_nodeInfo',
291
+ 'debug_traceTransaction',
292
+ 'eth_accounts',
293
+ 'eth_sendTransaction',
294
+ 'eth_sign',
295
+ 'eth_signTransaction',
296
+ 'tempo_fundAddress',
297
+ ]) {
298
+ const body = await request(api, {
299
+ body: {
300
+ id: 1,
301
+ jsonrpc: '2.0',
302
+ method,
303
+ params: selector === 'body' ? [{ chainId: zone }] : [],
304
+ },
305
+ mount,
306
+ ...(selector === 'path' ? { pathChainId: zone } : {}),
307
+ zoneToken: 'caller-token',
308
+ })
309
+ expect(body).toMatchObject({
310
+ error: { code: -32004, data: { code: 'api_key_forbidden' } },
311
+ })
312
+ }
313
+ }
314
+ expect(calls).toMatchInlineSnapshot(`[]`)
315
+ } finally {
316
+ await server.closeAsync()
317
+ }
318
+ },
319
+ )
320
+
321
+ test.each(['relay', 'sponsor'] as const)(
322
+ 'filters mixed Zone batches on %s while preserving reads and signed broadcasts',
323
+ async (mount) => {
324
+ const methods: string[] = []
325
+ const server = await Relay.createServer(
326
+ RequestListener.fromFetchHandler(async (request) => {
327
+ type Body = { id: number; method: string }
328
+ const body = (await request.json()) as Body
329
+ methods.push(body.method)
330
+ return Response.json({ id: body.id, jsonrpc: '2.0', result: null })
331
+ }),
332
+ )
333
+ try {
334
+ const api = TestApp.create({
335
+ auth: { keys },
336
+ rpc: { publicZoneUrl: server.url, url: 'http://internal.zone.test' },
337
+ zones: [TestApp.zone({ chainId: zone, rpcUrl: 'http://internal.zone.test' })],
338
+ })
339
+ const body = await request(api, {
340
+ body: [
341
+ { id: 1, jsonrpc: '2.0', method: 'eth_chainId' },
342
+ { id: 2, jsonrpc: '2.0', method: 'admin_nodeInfo' },
343
+ { id: 3, jsonrpc: '2.0', method: 'zone_getAuthorizationTokenInfo' },
344
+ { id: 4, jsonrpc: '2.0', method: 'eth_sendRawTransaction', params: ['0x00'] },
345
+ { id: 5, jsonrpc: '2.0', method: 'eth_getBlockAccessList', params: ['latest'] },
346
+ { id: 6, jsonrpc: '2.0', method: 'eth_getStorageValues', params: [{}, 'latest'] },
347
+ ],
348
+ mount,
349
+ pathChainId: zone,
350
+ zoneToken: 'caller-token',
351
+ })
352
+ expect(body).toMatchObject([
353
+ { id: 1, result: null },
354
+ { id: 2, error: { code: -32004, data: { code: 'api_key_forbidden' } } },
355
+ { id: 3, result: null },
356
+ { id: 4, result: null },
357
+ { id: 5, result: null },
358
+ { id: 6, result: null },
359
+ ])
360
+ expect(methods.sort()).toEqual([
361
+ 'eth_chainId',
362
+ 'eth_getBlockAccessList',
363
+ 'eth_getStorageValues',
364
+ 'eth_sendRawTransaction',
365
+ 'zone_getAuthorizationTokenInfo',
366
+ ])
367
+ } finally {
368
+ await server.closeAsync()
369
+ }
370
+ },
371
+ )
372
+
229
373
  test('allows a Zone token in a batch', async () => {
230
374
  const body = (await request(app(), {
231
375
  body: [
@@ -242,6 +386,54 @@ describe('behavior: Zone chain routing', () => {
242
386
  ])
243
387
  })
244
388
 
389
+ test.each([
390
+ ['relay', 307],
391
+ ['relay', 308],
392
+ ['sponsor', 307],
393
+ ['sponsor', 308],
394
+ ] as const)('rejects public Zone redirects on %s with status %s', async (mount, status) => {
395
+ const calls: string[] = []
396
+ const internal = await Relay.createServer(
397
+ RequestListener.fromFetchHandler(async (request) => {
398
+ calls.push(await request.text())
399
+ return Response.json({ id: 1, jsonrpc: '2.0', result: Hex.fromNumber(zone) })
400
+ }),
401
+ )
402
+ const publicRpc = await Relay.createServer(
403
+ RequestListener.fromFetchHandler(async (request) => {
404
+ await request.text()
405
+ return new Response(null, { headers: { location: internal.url }, status })
406
+ }),
407
+ )
408
+ try {
409
+ const api = TestApp.create({
410
+ auth: { keys },
411
+ rpc: {
412
+ auth: 'internal:secret',
413
+ publicZoneUrl: publicRpc.url,
414
+ url: internal.url,
415
+ zoneHeaders: {
416
+ 'CF-Access-Client-Id': 'service-id',
417
+ 'CF-Access-Client-Secret': 'service-secret',
418
+ },
419
+ },
420
+ zones: [TestApp.zone({ chainId: zone, rpcUrl: internal.url })],
421
+ })
422
+ const body = await request(api, {
423
+ body: { id: 1, jsonrpc: '2.0', method: 'eth_chainId' },
424
+ mount,
425
+ pathChainId: zone,
426
+ zoneToken: 'caller-token',
427
+ })
428
+
429
+ expect(body).toMatchObject({ error: { code: -32_603 } })
430
+ expect(calls).toMatchInlineSnapshot(`[]`)
431
+ } finally {
432
+ await publicRpc.closeAsync()
433
+ await internal.closeAsync()
434
+ }
435
+ })
436
+
245
437
  test.each([
246
438
  ['relay', 'secret_zone_relay'],
247
439
  ['sponsor', 'secret_zone_sponsor'],
@@ -377,6 +569,62 @@ describe('behavior: Zone chain routing', () => {
377
569
  expect(body).toMatchObject({ error: { data: { code: 'api_key_forbidden' } } })
378
570
  })
379
571
 
572
+ test.each(['relay', 'sponsor'] as const)(
573
+ 'blocks Zone raw-sign requests without explicit sponsorship on %s',
574
+ async (mount) => {
575
+ const calls: string[] = []
576
+ const server = await Relay.createServer(
577
+ RequestListener.fromFetchHandler(async (request) => {
578
+ calls.push(await request.text())
579
+ return Response.json({ id: 1, jsonrpc: '2.0', result: '0x00' })
580
+ }),
581
+ )
582
+ try {
583
+ const serialized = await senderAccount.signTransaction({
584
+ chainId: zone,
585
+ gas: 100_000n,
586
+ maxFeePerGas: 1_000_000n,
587
+ maxPriorityFeePerGas: 0n,
588
+ nonce: 0,
589
+ to: Tempo.accounts[8]!.address,
590
+ value: 0n,
591
+ })
592
+ const api = TestApp.create({
593
+ auth: { keys },
594
+ relay: { feePayer: { account: feePayerAccount } },
595
+ rpc: { publicZoneUrl: server.url, url: 'http://internal.zone.test' },
596
+ zones: [TestApp.zone({ chainId: zone, rpcUrl: 'http://internal.zone.test' })],
597
+ })
598
+ for (const transaction of [
599
+ serialized,
600
+ '0x02c0',
601
+ '0x76',
602
+ 'not-hex',
603
+ { from: senderAccount.address },
604
+ ]) {
605
+ const body = await request(api, {
606
+ apiKey: 'secret_relay_sponsor',
607
+ body: {
608
+ id: 1,
609
+ jsonrpc: '2.0',
610
+ method: 'eth_signRawTransaction',
611
+ params: [transaction],
612
+ },
613
+ mount,
614
+ pathChainId: zone,
615
+ zoneToken: 'caller-token',
616
+ })
617
+ expect(body).toMatchObject({
618
+ error: { code: -32004, data: { code: 'api_key_forbidden' } },
619
+ })
620
+ }
621
+ expect(calls).toMatchInlineSnapshot(`[]`)
622
+ } finally {
623
+ await server.closeAsync()
624
+ }
625
+ },
626
+ )
627
+
380
628
  test('requires Zone authorization for an embedded signed transaction', async () => {
381
629
  const entries: Log.Entry[] = []
382
630
  const api = TestApp.create({
@@ -410,6 +658,16 @@ describe('behavior: Zone chain routing', () => {
410
658
  expect(refused).toMatchObject({ error: { data: { code: 'api_key_forbidden' } } })
411
659
  expectSponsorshipCode({ code: 'api_key_forbidden', entry: entries[0] })
412
660
  expect(authorized).toMatchObject({ result: expect.stringMatching(/^0x/) })
661
+ for (const mount of ['relay', 'sponsor'] as const) {
662
+ const authorized = await request(api, {
663
+ ...rpc,
664
+ apiKey: 'secret_relay_sponsor',
665
+ mount,
666
+ pathChainId: zone,
667
+ zoneToken: token(),
668
+ })
669
+ expect(authorized).toMatchObject({ result: expect.stringMatching(/^0x/) })
670
+ }
413
671
  })
414
672
  })
415
673
 
@@ -428,6 +686,7 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
428
686
  token: 'secret_sponsor',
429
687
  })
430
688
  expect(body.error).toBeUndefined()
689
+ expect(body.sponsorship_details).toStrictEqual({ subsidized: true })
431
690
  // The relay returned the envelope counter-signed by the fee payer.
432
691
  const signed = Transaction.deserialize(body.result as `0x76${string}`)
433
692
  expect(signed.feePayerSignature).toBeDefined()
@@ -450,12 +709,14 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship', () => {
450
709
  "feeAmount": null,
451
710
  "feeMax": "1",
452
711
  "feeToken": "0x20c0000000000000000000000000000000000000",
712
+ "finalizationAttemptedAt": null,
453
713
  "finalizedAt": null,
454
714
  "id": "<id>",
455
715
  "meterReportedAt": null,
456
716
  "orgId": "org_1",
457
717
  "projectId": "prj_1",
458
718
  "signPayload": "<hash>",
719
+ "sponsorshipAttributionId": null,
459
720
  "status": "pending",
460
721
  "transaction": "<hex>",
461
722
  "transactionHash": "<hash>",
@@ -982,8 +1243,8 @@ describe('behavior: mainnet billing gate', () => {
982
1243
  async function configureSubsidy(db: ReturnType<typeof TestApp.database>) {
983
1244
  await Organizations.create(db, { id: 'org_1', name: 'Privy' })
984
1245
  await Organizations.setSponsorshipSubsidy(db, 'org_1', {
1246
+ attributionSpendLimit: '100.00',
985
1247
  durationDays: 90,
986
- projectSpendLimit: '100.00',
987
1248
  })
988
1249
  const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
989
1250
  await activate(db)
@@ -998,52 +1259,310 @@ describe('behavior: mainnet billing gate', () => {
998
1259
  /** A $2 signed cap, over the `'1.00'` platform default. */
999
1260
  const overCapFees = { gas: 1_000_000n, maxFeePerGas: 2_000_000_000_000n } as const
1000
1261
 
1001
- test('behavior: active project promotions waive charges with active billing', async () => {
1262
+ test('behavior: read-only relay requests do not create sponsorship attributions', async () => {
1002
1263
  const db = TestApp.database()
1003
- const project = await configureSubsidy(db)
1264
+ await configureSubsidy(db)
1265
+
1266
+ const body = await relayRequest(createMainnetApp({ db }), {
1267
+ externalId: 'privy-account-1',
1268
+ method: 'eth_chainId',
1269
+ mount: 'relay',
1270
+ params: [],
1271
+ token: 'secret_unscoped',
1272
+ })
1273
+
1274
+ expect(body.error).toBeUndefined()
1275
+ expect(
1276
+ await db.kysely.selectFrom('sponsorship_attributions').select('id').execute(),
1277
+ ).toHaveLength(0)
1278
+ })
1279
+
1280
+ test('behavior: opaque attribution promotions waive charges with active billing', async () => {
1281
+ const db = TestApp.database()
1282
+ await configureSubsidy(db)
1283
+ await SponsorshipAttributions.resolveExternal(db, {
1284
+ externalId: 'privy-account-1',
1285
+ orgId: 'org_1',
1286
+ })
1004
1287
  const body = await relayRequest(createMainnetApp({ db }), {
1288
+ externalId: 'privy-account-1',
1005
1289
  method: 'eth_signRawTransaction',
1006
1290
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1007
- projectId: project.id,
1008
1291
  token: 'secret_unattributed_prod',
1009
1292
  })
1010
1293
  expect(body.error).toBeUndefined()
1011
1294
 
1012
1295
  const [row] = await SponsoredTransactions.listPending(db)
1013
1296
  expect(row).toMatchObject({
1297
+ sponsorshipAttributionId: expect.stringMatching(/^sat_/),
1014
1298
  billable: false,
1015
1299
  orgId: 'org_1',
1016
- projectId: project.id,
1300
+ projectId: null,
1301
+ })
1302
+ const updated = await SponsorshipAttributions.resolveExternal(db, {
1303
+ externalId: 'privy-account-1',
1304
+ orgId: 'org_1',
1017
1305
  })
1018
- const updated = await Projects.get(db, project.id)
1019
- const startsAt = updated?.sponsorshipSubsidyStartsAt
1020
- const endsAt = updated?.sponsorshipSubsidyEndsAt
1306
+ const startsAt = updated?.startsAt
1307
+ const endsAt = updated?.endsAt
1021
1308
  expect({ endsAt, startsAt }).toMatchObject({ endsAt: expect.any(String), startsAt: expect.any(String) }) // prettier-ignore
1022
1309
  if (!endsAt || !startsAt) throw new Error('Expected an activated promotion window.')
1023
1310
  expect(Date.parse(endsAt) - Date.parse(startsAt)).toBe(90 * 86_400_000)
1024
1311
  })
1025
1312
 
1026
- test('behavior: exhausted project promotions return to customer billing', async () => {
1313
+ test.each(['externalId', 'legacyExternalId'] as const)(
1314
+ 'behavior: rotating %s cannot create fresh promotional budgets',
1315
+ async (header) => {
1316
+ const db = TestApp.databaseFactory()
1317
+ const seed = db()
1318
+ await configureSubsidy(seed)
1319
+ await Organizations.setSponsorshipSubsidy(seed, 'org_1', {
1320
+ attributionSpendLimit: '0.000001',
1321
+ durationDays: 90,
1322
+ })
1323
+ await BillingSettings.upsert(seed, { orgId: 'org_1', spendLimit: '0.000002' })
1324
+ const entries: Log.Entry[] = []
1325
+ const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
1326
+ const results = await Promise.all(
1327
+ [0, 1, 2, 3].map(async (nonce) =>
1328
+ relayRequest(app, {
1329
+ [header]: `rotating-account-${nonce}`,
1330
+ method: 'eth_signRawTransaction',
1331
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, nonce })],
1332
+ token: 'secret_unattributed_prod',
1333
+ }),
1334
+ ),
1335
+ )
1336
+
1337
+ expect(results.filter((result) => !result.error)).toHaveLength(2)
1338
+ expect(results.filter((result) => result.error?.data?.code === 'spend_limit_exceeded')).toHaveLength(2) // prettier-ignore
1339
+ expect(entries.filter((entry) => entry.sponsorship?.reason === 'spend_limit_exceeded')).toHaveLength(2) // prettier-ignore
1340
+ expect(await seed.kysely.selectFrom('sponsorship_attributions').selectAll().execute()).toStrictEqual([]) // prettier-ignore
1341
+ expect(
1342
+ await SponsoredTransactions.spend(seed, {
1343
+ billable: false,
1344
+ chainIds: [Viem.chainId.mainnet],
1345
+ orgId: 'org_1',
1346
+ since: '2000-01-01T00:00:00.000Z',
1347
+ }),
1348
+ ).toBe(0n)
1349
+ expect(
1350
+ await SponsoredTransactions.spend(seed, {
1351
+ chainIds: [Viem.chainId.mainnet],
1352
+ orgId: 'org_1',
1353
+ since: '2000-01-01T00:00:00.000Z',
1354
+ }),
1355
+ ).toBe(2n)
1356
+ },
1357
+ )
1358
+
1359
+ test('behavior: Privy legacy attribution header resolves the same canonical record', async () => {
1360
+ const db = TestApp.database()
1361
+ await configureSubsidy(db)
1362
+ await SponsorshipAttributions.resolveExternal(db, {
1363
+ externalId: 'privy-account-1',
1364
+ orgId: 'org_1',
1365
+ })
1366
+ const body = await relayRequest(createMainnetApp({ db }), {
1367
+ legacyExternalId: 'privy-account-1',
1368
+ method: 'eth_signRawTransaction',
1369
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1370
+ token: 'secret_unattributed_prod',
1371
+ })
1372
+
1373
+ expect(body.error).toBeUndefined()
1374
+ expect(
1375
+ await SponsorshipAttributions.resolveExternal(db, {
1376
+ externalId: 'privy-account-1',
1377
+ orgId: 'org_1',
1378
+ }),
1379
+ ).toMatchObject({ startsAt: expect.any(String) })
1380
+ })
1381
+
1382
+ test('behavior: external attribution ids are bounded to 128 characters', async () => {
1383
+ const db = TestApp.database()
1384
+ await configureSubsidy(db)
1385
+ await SponsorshipAttributions.resolveExternal(db, {
1386
+ externalId: 'a'.repeat(128),
1387
+ orgId: 'org_1',
1388
+ })
1389
+ const app = createMainnetApp({ db })
1390
+ const accepted = await relayRequest(app, {
1391
+ externalId: 'a'.repeat(128),
1392
+ method: 'eth_signRawTransaction',
1393
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1394
+ token: 'secret_unattributed_prod',
1395
+ })
1396
+ const rejected = await relayRequest(app, {
1397
+ externalId: 'a'.repeat(129),
1398
+ method: 'eth_signRawTransaction',
1399
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, nonce: 1 })],
1400
+ token: 'secret_unattributed_prod',
1401
+ })
1402
+
1403
+ expect(accepted.error).toBeUndefined()
1404
+ expect(rejected.error).toStrictEqual({
1405
+ code: -32602,
1406
+ data: { code: 'attribution_id_invalid' },
1407
+ message: 'Attribution rejected.',
1408
+ })
1409
+ expect(
1410
+ await db.kysely.selectFrom('sponsorship_attributions').select('externalId').execute(),
1411
+ ).toStrictEqual([{ externalId: 'a'.repeat(128) }])
1412
+ })
1413
+
1414
+ test('behavior: the canonical header takes precedence over the legacy header', async () => {
1415
+ const db = TestApp.database()
1416
+ await configureSubsidy(db)
1417
+ await SponsorshipAttributions.resolveExternal(db, {
1418
+ externalId: 'canonical-account',
1419
+ orgId: 'org_1',
1420
+ })
1421
+ const body = await relayRequest(createMainnetApp({ db }), {
1422
+ externalId: 'canonical-account',
1423
+ legacyExternalId: 'legacy-account',
1424
+ method: 'eth_signRawTransaction',
1425
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1426
+ token: 'secret_unattributed_prod',
1427
+ })
1428
+
1429
+ expect(body.error).toBeUndefined()
1430
+ expect(
1431
+ await db.kysely.selectFrom('sponsorship_attributions').select('externalId').execute(),
1432
+ ).toStrictEqual([{ externalId: 'canonical-account' }])
1433
+ })
1434
+
1435
+ test.each(['privy-account-2', 'unknown-account'])(
1436
+ 'behavior: retrying an envelope with attribution %s is rejected',
1437
+ async (externalId) => {
1438
+ const db = TestApp.database()
1439
+ await configureSubsidy(db)
1440
+ await SponsorshipAttributions.resolveExternal(db, {
1441
+ externalId: 'privy-account-1',
1442
+ orgId: 'org_1',
1443
+ })
1444
+ await SponsorshipAttributions.resolveExternal(db, {
1445
+ externalId: 'privy-account-2',
1446
+ orgId: 'org_1',
1447
+ })
1448
+ const app = createMainnetApp({ db })
1449
+ const transaction = await signSponsorable({ chainId: Viem.chainId.mainnet })
1450
+ const accepted = await relayRequest(app, {
1451
+ externalId: 'privy-account-1',
1452
+ method: 'eth_signRawTransaction',
1453
+ params: [transaction],
1454
+ token: 'secret_unattributed_prod',
1455
+ })
1456
+ const rejected = await relayRequest(app, {
1457
+ externalId,
1458
+ method: 'eth_signRawTransaction',
1459
+ params: [transaction],
1460
+ token: 'secret_unattributed_prod',
1461
+ })
1462
+
1463
+ expect(accepted.error).toBeUndefined()
1464
+ expect(rejected.error).toStrictEqual({
1465
+ code: -32602,
1466
+ data: { code: 'attribution_id_invalid' },
1467
+ message: 'Attribution rejected.',
1468
+ })
1469
+ },
1470
+ )
1471
+
1472
+ test('behavior: foreign external ids cannot select a legacy or project promotion', async () => {
1473
+ const db = TestApp.database()
1474
+ const project = await configureSubsidy(db)
1475
+ const foreign = await SponsorshipAttributions.resolveExternal(db, {
1476
+ externalId: 'foreign-account',
1477
+ orgId: 'org_2',
1478
+ })
1479
+ const legacy = await SponsorshipAttributions.resolveExternal(db, {
1480
+ externalId: 'legacy-account',
1481
+ orgId: 'org_1',
1482
+ })
1483
+ const body = await relayRequest(createMainnetApp({ db }), {
1484
+ externalId: 'foreign-account',
1485
+ legacyExternalId: 'legacy-account',
1486
+ method: 'eth_signRawTransaction',
1487
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1488
+ projectId: project.id,
1489
+ token: 'secret_unattributed_prod',
1490
+ })
1491
+
1492
+ expect(body.error).toBeUndefined()
1493
+ expect(await SponsoredTransactions.listPending(db)).toMatchObject([
1494
+ { billable: true, projectId: project.id, sponsorshipAttributionId: null },
1495
+ ])
1496
+ expect(
1497
+ await db.kysely.selectFrom('sponsorship_attributions').selectAll().orderBy('orgId').execute(),
1498
+ ).toStrictEqual([legacy, foreign])
1499
+ })
1500
+
1501
+ test('behavior: Tempo Project attribution uses the canonical promotion path', async () => {
1502
+ const db = TestApp.database()
1503
+ const project = await configureSubsidy(db)
1504
+ const body = await relayRequest(createMainnetApp({ db }), {
1505
+ method: 'eth_signRawTransaction',
1506
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1507
+ projectId: project.id,
1508
+ token: 'secret_unattributed_prod',
1509
+ })
1510
+
1511
+ expect(body.error).toBeUndefined()
1512
+ expect(await SponsoredTransactions.listPending(db)).toMatchObject([
1513
+ {
1514
+ billable: false,
1515
+ projectId: project.id,
1516
+ sponsorshipAttributionId: expect.stringMatching(/^sat_/),
1517
+ },
1518
+ ])
1519
+ })
1520
+
1521
+ test('behavior: sponsor fills return their sponsorship details', async () => {
1522
+ const db = TestApp.database()
1523
+ const project = await configureSubsidy(db)
1524
+ const body = await relayRequest(createMainnetApp({ db }), {
1525
+ method: 'eth_fillTransaction',
1526
+ params: [fill],
1527
+ projectId: project.id,
1528
+ token: 'secret_unattributed_prod',
1529
+ })
1530
+
1531
+ expect(body.error).toBeUndefined()
1532
+ expect(body.sponsorship_details).toStrictEqual({ subsidized: true })
1533
+ })
1534
+
1535
+ test('behavior: exhausted attribution promotions return to customer billing', async () => {
1027
1536
  const db = TestApp.database()
1028
1537
  await Organizations.create(db, { id: 'org_1', name: 'Privy' })
1029
1538
  await Organizations.setSponsorshipSubsidy(db, 'org_1', {
1539
+ attributionSpendLimit: '0.000001',
1030
1540
  durationDays: 90,
1031
- projectSpendLimit: '0.000001',
1032
1541
  })
1033
- const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
1034
1542
  await activate(db)
1543
+ await SponsorshipAttributions.resolveExternal(db, {
1544
+ externalId: 'privy-account-1',
1545
+ orgId: 'org_1',
1546
+ })
1035
1547
  const app = createMainnetApp({ db })
1548
+ const transaction = await signSponsorable({ chainId: Viem.chainId.mainnet })
1036
1549
 
1037
1550
  const subsidized = await relayRequest(app, {
1551
+ externalId: 'privy-account-1',
1038
1552
  method: 'eth_signRawTransaction',
1039
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1040
- projectId: project.id,
1553
+ params: [transaction],
1041
1554
  token: 'secret_unattributed_prod',
1042
1555
  })
1043
1556
  const billed = await relayRequest(app, {
1557
+ externalId: 'privy-account-1',
1044
1558
  method: 'eth_signRawTransaction',
1045
1559
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet, nonce: 1 })],
1046
- projectId: project.id,
1560
+ token: 'secret_unattributed_prod',
1561
+ })
1562
+ const retried = await relayRequest(app, {
1563
+ externalId: 'privy-account-1',
1564
+ method: 'eth_signRawTransaction',
1565
+ params: [transaction],
1047
1566
  token: 'secret_unattributed_prod',
1048
1567
  })
1049
1568
 
@@ -1051,49 +1570,123 @@ describe('behavior: mainnet billing gate', () => {
1051
1570
  billed: undefined,
1052
1571
  subsidized: undefined,
1053
1572
  })
1573
+ expect({
1574
+ billed: billed.sponsorship_details,
1575
+ subsidized: subsidized.sponsorship_details,
1576
+ }).toStrictEqual({ billed: { subsidized: false }, subsidized: { subsidized: true } })
1577
+ expect(retried.sponsorship_details).toStrictEqual({ subsidized: true })
1054
1578
  expect(await SponsoredTransactions.listPending(db)).toMatchObject([
1055
- { billable: false, projectId: project.id },
1056
- { billable: true, projectId: project.id },
1579
+ {
1580
+ sponsorshipAttributionId: expect.stringMatching(/^sat_/),
1581
+ billable: false,
1582
+ projectId: null,
1583
+ },
1584
+ { sponsorshipAttributionId: expect.stringMatching(/^sat_/), billable: true, projectId: null },
1057
1585
  ])
1058
1586
  })
1059
1587
 
1060
- test('behavior: uncapped project promotions waive charges with active billing', async () => {
1588
+ test('behavior: uncapped attribution promotions waive charges with active billing', async () => {
1061
1589
  const db = TestApp.database()
1062
1590
  await Organizations.create(db, { id: 'org_1', name: 'Privy' })
1063
1591
  await Organizations.setSponsorshipSubsidy(db, 'org_1', {
1592
+ attributionSpendLimit: null,
1064
1593
  durationDays: 90,
1065
- projectSpendLimit: null,
1066
1594
  })
1067
- const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
1068
1595
  await activate(db)
1596
+ await SponsorshipAttributions.resolveExternal(db, {
1597
+ externalId: 'privy-account-1',
1598
+ orgId: 'org_1',
1599
+ })
1069
1600
  const body = await relayRequest(createMainnetApp({ db }), {
1601
+ externalId: 'privy-account-1',
1070
1602
  method: 'eth_signRawTransaction',
1071
1603
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1072
- projectId: project.id,
1073
1604
  token: 'secret_unattributed_prod',
1074
1605
  })
1075
1606
  expect(body.error).toBeUndefined()
1076
1607
  expect(await SponsoredTransactions.listPending(db)).toMatchObject([
1077
- { billable: false, projectId: project.id },
1608
+ {
1609
+ sponsorshipAttributionId: expect.stringMatching(/^sat_/),
1610
+ billable: false,
1611
+ projectId: null,
1612
+ },
1078
1613
  ])
1079
1614
  })
1080
1615
 
1081
- test('behavior: project promotions still require active billing', async () => {
1616
+ test('behavior: registered attribution bursts share promotion and fallback billing limits', async () => {
1617
+ const db = TestApp.databaseFactory()
1618
+ const seed = db()
1619
+ await configureSubsidy(seed)
1620
+ await Organizations.setSponsorshipSubsidy(seed, 'org_1', {
1621
+ attributionSpendLimit: '0.000002',
1622
+ durationDays: 90,
1623
+ })
1624
+ await BillingSettings.upsert(seed, { orgId: 'org_1', spendLimit: '0.000001' })
1625
+ const attribution = await SponsorshipAttributions.resolveExternal(seed, {
1626
+ externalId: 'privy-account-1',
1627
+ orgId: 'org_1',
1628
+ })
1629
+ const entries: Log.Entry[] = []
1630
+ const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
1631
+ const results = await Promise.all(
1632
+ Array.from({ length: 6 }, async (_, nonce) =>
1633
+ relayRequest(app, {
1634
+ ...(nonce % 2 === 0
1635
+ ? { externalId: 'privy-account-1' }
1636
+ : { legacyExternalId: 'privy-account-1' }),
1637
+ method: 'eth_signRawTransaction',
1638
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, nonce })],
1639
+ token: 'secret_unattributed_prod',
1640
+ }),
1641
+ ),
1642
+ )
1643
+
1644
+ expect(results.filter((result) => !result.error)).toHaveLength(3)
1645
+ expect(
1646
+ results.filter((result) => result.error?.data?.code === 'spend_limit_exceeded'),
1647
+ ).toHaveLength(3)
1648
+ expect(
1649
+ entries.filter((entry) => entry.sponsorship?.reason === 'spend_limit_exceeded'),
1650
+ ).toHaveLength(3)
1651
+ const rows = await SponsoredTransactions.listPending(seed)
1652
+ expect(rows.filter((row) => !row.billable)).toHaveLength(2)
1653
+ expect(rows.filter((row) => row.billable)).toHaveLength(1)
1654
+ expect(rows.every((row) => row.sponsorshipAttributionId === attribution.id)).toBe(true)
1655
+ for (const row of rows)
1656
+ await SponsoredTransactions.finalize(seed, row.id, {
1657
+ feeAmount: '1',
1658
+ finalizedAt: new Date().toISOString(),
1659
+ })
1660
+ const scope = {
1661
+ chainIds: [Viem.chainId.mainnet],
1662
+ orgId: 'org_1',
1663
+ since: '2000-01-01T00:00:00.000Z',
1664
+ }
1665
+ expect(await SponsoredTransactions.spend(seed, { ...scope, billable: false })).toBe(2n)
1666
+ expect(await SponsoredTransactions.spend(seed, scope)).toBe(1n)
1667
+ expect(
1668
+ await SponsoredTransactions.listUnreported(seed, { chainIds: scope.chainIds }),
1669
+ ).toMatchObject([{ billable: true, feeAmount: '1', sponsorshipAttributionId: attribution.id }])
1670
+ })
1671
+
1672
+ test('behavior: attribution promotions still require active billing', async () => {
1082
1673
  const db = TestApp.database()
1083
1674
  await Organizations.create(db, { id: 'org_1', name: 'Privy' })
1084
1675
  await Organizations.setSponsorshipSubsidy(db, 'org_1', {
1676
+ attributionSpendLimit: null,
1085
1677
  durationDays: 90,
1086
- projectSpendLimit: null,
1087
1678
  })
1088
1679
  const project = await Projects.create(db, { name: 'Privy app', orgId: 'org_1' })
1089
1680
  await TestApp.verifiedSeed(db, Viem.chainId.mainnet)
1090
1681
  const body = await relayRequest(createMainnetApp({ db }), {
1682
+ externalId: 'privy-account-1',
1091
1683
  method: 'eth_signRawTransaction',
1092
1684
  params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1093
1685
  projectId: project.id,
1094
1686
  token: 'secret_unattributed_prod',
1095
1687
  })
1096
1688
  expect(body.error?.data).toStrictEqual({ code: 'billing_required' })
1689
+ expect(body.sponsorship_details).toBeUndefined()
1097
1690
  expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
1098
1691
  expect(await Projects.get(db, project.id)).toMatchObject({
1099
1692
  sponsorshipSubsidyEndsAt: null,
@@ -1118,12 +1711,16 @@ describe('behavior: mainnet billing gate', () => {
1118
1711
  test('behavior: expired project promotions return to customer billing', async () => {
1119
1712
  const db = TestApp.database()
1120
1713
  const project = await configureSubsidy(db)
1121
- await Projects.activateSponsorship(db, {
1122
- at: new Date(Date.now() - 91 * 86_400_000).toISOString(),
1714
+ const attribution = await SponsorshipAttributions.resolveProject(db, {
1715
+ orgId: 'org_1',
1716
+ projectId: project.id,
1717
+ })
1718
+ await SponsorshipAttributions.activate(db, {
1123
1719
  endsAt: new Date(Date.now() - 86_400_000).toISOString(),
1124
- id: project.id,
1720
+ id: attribution.id,
1125
1721
  orgId: 'org_1',
1126
1722
  spendLimit: '100000000',
1723
+ startsAt: new Date(Date.now() - 91 * 86_400_000).toISOString(),
1127
1724
  })
1128
1725
  const body = await relayRequest(createMainnetApp({ db }), {
1129
1726
  method: 'eth_signRawTransaction',
@@ -1147,7 +1744,7 @@ describe('behavior: mainnet billing gate', () => {
1147
1744
  expect(body.error).toStrictEqual({
1148
1745
  code: -32602,
1149
1746
  data: { code: 'project_id_invalid' },
1150
- message: 'Project attribution rejected.',
1747
+ message: 'Attribution rejected.',
1151
1748
  })
1152
1749
  })
1153
1750
 
@@ -1164,6 +1761,23 @@ describe('behavior: mainnet billing gate', () => {
1164
1761
  expect(body.error?.data).toStrictEqual({ code: 'project_id_invalid' })
1165
1762
  })
1166
1763
 
1764
+ test('behavior: rejects cached project attribution after project deletion', async () => {
1765
+ const db = TestApp.database()
1766
+ await configureSubsidy(db)
1767
+ const body = await relayRequest(createMainnetApp({ db }), {
1768
+ method: 'eth_signRawTransaction',
1769
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet })],
1770
+ token: 'secret_sponsor_prod',
1771
+ })
1772
+
1773
+ expect(body.error).toStrictEqual({
1774
+ code: -32602,
1775
+ data: { code: 'project_id_invalid' },
1776
+ message: 'Attribution rejected.',
1777
+ })
1778
+ expect(await SponsoredTransactions.listPending(db)).toHaveLength(0)
1779
+ })
1780
+
1167
1781
  test('behavior: refuses mainnet sponsorship without a billing source', async () => {
1168
1782
  const entries: Log.Entry[] = []
1169
1783
  const body = await relayRequest(
@@ -1515,44 +2129,57 @@ describe('behavior: mainnet billing gate', () => {
1515
2129
  expect(row?.currency).toBe('usd')
1516
2130
  })
1517
2131
 
1518
- test('behavior: refuses sponsorship over the period spend limit; raising restores', async () => {
1519
- const db = TestApp.database()
1520
- const entries: Log.Entry[] = []
1521
- await activate(db)
1522
- await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '1' })
1523
- // $0.90 already finalized this window; a $0.50 cap would overshoot $1.
1524
- const seeded = await SponsoredTransactions.upsert(db, {
1525
- apiKeyId: 'key_sponsor_prod',
1526
- billable: true,
1527
- chainId: Viem.chainId.mainnet,
1528
- environment: 'production',
1529
- orgId: 'org_1',
1530
- projectId: 'prj_1',
1531
- signPayload: `0x${'31'.repeat(32)}`,
1532
- transaction: `0x76${'cc'.repeat(16)}`,
1533
- transactionHash: `0x${'32'.repeat(32)}`,
1534
- })
1535
- await SponsoredTransactions.finalize(db, seeded.id, {
1536
- feeAmount: '900000',
1537
- finalizedAt: new Date().toISOString(),
1538
- })
1539
-
1540
- const app = createMainnetApp({ db, logger: (entry) => void entries.push(entry) })
1541
- const request = async () =>
1542
- await relayRequest(app, {
1543
- method: 'eth_signRawTransaction',
1544
- params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
1545
- token: 'secret_sponsor_prod',
2132
+ test.each([Viem.chainId.mainnet, 8001])(
2133
+ 'behavior: counts chain %i toward the period spend limit; raising restores',
2134
+ async (chainId) => {
2135
+ const db = TestApp.database()
2136
+ const entries: Log.Entry[] = []
2137
+ await activate(db)
2138
+ await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '1' })
2139
+ // $0.90 already finalized this window; a $0.50 cap would overshoot $1.
2140
+ const seeded = await SponsoredTransactions.upsert(db, {
2141
+ apiKeyId: 'key_sponsor_prod',
2142
+ billable: true,
2143
+ chainId,
2144
+ environment: 'production',
2145
+ orgId: 'org_1',
2146
+ projectId: 'prj_1',
2147
+ signPayload: `0x${'31'.repeat(32)}`,
2148
+ transaction: `0x76${'cc'.repeat(16)}`,
2149
+ transactionHash: `0x${'32'.repeat(32)}`,
2150
+ })
2151
+ await SponsoredTransactions.finalize(db, seeded.id, {
2152
+ feeAmount: '900000',
2153
+ finalizedAt: new Date().toISOString(),
1546
2154
  })
1547
- const refused = await request()
1548
- expect(refused.error?.message).toBe('Spend limit exceeded.')
1549
- expect(refused.error?.data).toStrictEqual({ code: 'spend_limit_exceeded' })
1550
- expectSponsorshipCode({ code: 'spend_limit_exceeded', entry: entries[0] })
1551
2155
 
1552
- await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '10' })
1553
- const restored = await request()
1554
- expect(restored.error).toBeUndefined()
1555
- })
2156
+ const app = createMainnetApp({
2157
+ db,
2158
+ logger: (entry) => void entries.push(entry),
2159
+ zones: [
2160
+ TestApp.zone({
2161
+ chainId: 8001,
2162
+ rpcUrl: 'https://zone.example',
2163
+ sourceChainId: Viem.chainId.mainnet,
2164
+ }),
2165
+ ],
2166
+ })
2167
+ const request = async () =>
2168
+ await relayRequest(app, {
2169
+ method: 'eth_signRawTransaction',
2170
+ params: [await signSponsorable({ chainId: Viem.chainId.mainnet, ...halfDollarFees })],
2171
+ token: 'secret_sponsor_prod',
2172
+ })
2173
+ const refused = await request()
2174
+ expect(refused.error?.message).toBe('Spend limit exceeded.')
2175
+ expect(refused.error?.data).toStrictEqual({ code: 'spend_limit_exceeded' })
2176
+ expectSponsorshipCode({ code: 'spend_limit_exceeded', entry: entries[0] })
2177
+
2178
+ await BillingSettings.upsert(db, { orgId: 'org_1', spendLimit: '10' })
2179
+ const restored = await request()
2180
+ expect(restored.error).toBeUndefined()
2181
+ },
2182
+ )
1556
2183
 
1557
2184
  test('behavior: pending signed caps consume spend-limit budget', async () => {
1558
2185
  const db = TestApp.database()
@@ -1698,6 +2325,142 @@ describe.skipIf(runtime.mode !== 'localnet')('behavior: sponsorship (viem)', ()
1698
2325
  )
1699
2326
  }, 60_000)
1700
2327
 
2328
+ test('behavior: old failed intents do not hide active transactions or pin recovery', async () => {
2329
+ const receipts: Transaction.TransactionReceipt[] = []
2330
+ const intents: SponsoredTransactions.Record[] = []
2331
+ for (const amount of [3n, 4n, 5n]) {
2332
+ const before = new Set((await SponsoredTransactions.listPending(db)).map((row) => row.id))
2333
+ const { receipt } = await Actions.token.transferSync(getClient(), {
2334
+ amount,
2335
+ feePayer: true,
2336
+ to: Tempo.accounts[8]!.address,
2337
+ token: alphaUsd,
2338
+ })
2339
+ receipts.push(receipt)
2340
+ const intent = (await SponsoredTransactions.listPending(db)).find(
2341
+ (row) => row.transactionHash === null && !before.has(row.id),
2342
+ )
2343
+ expect(intent).toBeDefined()
2344
+ intents.push(intent!)
2345
+ // Separate the active intent's search window from the older transactions.
2346
+ await new Promise((resolve) => setTimeout(resolve, 1_100))
2347
+ }
2348
+ await Organizations.create(db, { id: 'org_1', name: 'One' })
2349
+ for (const intent of intents.slice(0, 2))
2350
+ await SponsoredTransactions.fail(db, intent.id, new Date().toISOString())
2351
+
2352
+ const tidx = Tidx.getClient({
2353
+ chainId: runtime.chainId,
2354
+ tidx: { baseUrl: runtime.tidxUrl },
2355
+ })
2356
+ await expect
2357
+ .poll(
2358
+ async () => {
2359
+ const { rows } = await tidx.fetch({
2360
+ // Runtime hashes bound this query to the three submitted transactions.
2361
+ query:
2362
+ `SELECT hash FROM txs WHERE hash IN (${receipts.map((receipt) => `'${receipt.transactionHash}'`).join(', ')})` as string,
2363
+ })
2364
+ return rows.length
2365
+ },
2366
+ { timeout: 30_000 },
2367
+ )
2368
+ .toBe(3)
2369
+
2370
+ const options = {
2371
+ candidateCap: 1,
2372
+ feePayer: feePayer.address,
2373
+ getClient: () => relayClient,
2374
+ getTidx: () => tidx,
2375
+ skewMs: 0,
2376
+ }
2377
+ // The real API health route rejects RPC calls, exercising a misconfigured upstream.
2378
+ const unavailable = createClient({
2379
+ chain: Tempo.chain,
2380
+ transport: http(`${server.url}/health`, { retryCount: 0 }),
2381
+ })
2382
+ const failed = await Sponsorships.reconcile(db, {
2383
+ ...options,
2384
+ getClient: () => unavailable,
2385
+ })
2386
+ expect(failed.errors).toBeGreaterThan(0)
2387
+ expect(
2388
+ await SponsorshipReconciliationCursors.load(db, {
2389
+ chainId: runtime.chainId,
2390
+ feePayer: feePayer.address.toLowerCase() as Hex.Hex,
2391
+ }),
2392
+ ).toMatchObject({ complete: true, retryCount: 1 })
2393
+ expect((await SponsoredTransactions.get(db, intents[2]!.id))?.transactionHash).toBeNull()
2394
+ for (let attempt = 0; attempt < 2; attempt++)
2395
+ expect(
2396
+ (
2397
+ await Sponsorships.reconcile(db, {
2398
+ ...options,
2399
+ getClient: () => unavailable,
2400
+ })
2401
+ ).errors,
2402
+ ).toBeGreaterThan(0)
2403
+ expect(
2404
+ await SponsorshipReconciliationCursors.load(db, {
2405
+ chainId: runtime.chainId,
2406
+ feePayer: feePayer.address.toLowerCase() as Hex.Hex,
2407
+ }),
2408
+ ).toMatchObject({
2409
+ blockNumber: receipts[2]!.blockNumber.toString(),
2410
+ complete: false,
2411
+ retryCount: 0,
2412
+ transactionIndex: receipts[2]!.transactionIndex,
2413
+ })
2414
+
2415
+ expect((await Sponsorships.reconcile(db, options)).errors).toBe(0)
2416
+ expect((await SponsoredTransactions.get(db, intents[2]!.id))?.transactionHash).toBe(
2417
+ receipts[2]!.transactionHash,
2418
+ )
2419
+ // Each pass must advance beyond already processed on-chain candidates.
2420
+ await Sponsorships.reconcile(db, options)
2421
+ expect(
2422
+ await SponsorshipReconciliationCursors.load(db, {
2423
+ chainId: runtime.chainId,
2424
+ feePayer: feePayer.address.toLowerCase() as Hex.Hex,
2425
+ }),
2426
+ ).toMatchObject({ complete: true, retryCount: 0, retryKey: null })
2427
+ for (const [index, intent] of intents.entries())
2428
+ expect((await SponsoredTransactions.get(db, intent.id))?.transactionHash).toBe(
2429
+ receipts[index]!.transactionHash,
2430
+ )
2431
+ await Sponsorships.finalize(db, { getClient: () => relayClient })
2432
+ for (const intent of intents)
2433
+ expect((await SponsoredTransactions.get(db, intent.id))?.status).toBe('finalized')
2434
+
2435
+ const { receipt } = await Actions.token.transferSync(getClient(), {
2436
+ amount: 6n,
2437
+ feePayer: true,
2438
+ to: Tempo.accounts[8]!.address,
2439
+ token: alphaUsd,
2440
+ })
2441
+ const later = (await SponsoredTransactions.listPending(db)).find(
2442
+ (row) => row.transactionHash === null,
2443
+ )!
2444
+ await SponsoredTransactions.fail(db, later.id, new Date().toISOString())
2445
+ await expect
2446
+ .poll(
2447
+ async () => {
2448
+ const { rows } = await tidx.fetch({
2449
+ // Runtime hash restricts the query to the new recovery candidate.
2450
+ query: `SELECT hash FROM txs WHERE hash = '${receipt.transactionHash}'` as string,
2451
+ })
2452
+ return rows.length
2453
+ },
2454
+ { timeout: 30_000 },
2455
+ )
2456
+ .toBe(1)
2457
+ // A new failed intent must start at the head, even after a full final page.
2458
+ await Sponsorships.reconcile(db, options)
2459
+ expect((await SponsoredTransactions.get(db, later.id))?.transactionHash).toBe(
2460
+ receipt.transactionHash,
2461
+ )
2462
+ }, 90_000)
2463
+
1701
2464
  test('behavior: sign-only sends record and finalize from the real receipt', async () => {
1702
2465
  const request = await prepareTransactionRequest(relayClient, {
1703
2466
  account: sender,
@@ -1792,6 +2555,10 @@ async function relayRequest(app: ReturnType<typeof TestApp.create>, options: rel
1792
2555
  body: JSON.stringify({ id: 1, jsonrpc: '2.0', method: options.method, params: options.params }), // prettier-ignore
1793
2556
  headers: {
1794
2557
  'content-type': 'application/json',
2558
+ ...(options.externalId ? { 'tempo-attribution-id': options.externalId } : {}),
2559
+ ...(options.legacyExternalId
2560
+ ? { 'x-tempo-attribution-key': options.legacyExternalId }
2561
+ : {}),
1795
2562
  ...(options.projectId ? { 'tempo-project-id': options.projectId } : {}),
1796
2563
  ...(options.token ? { 'tempo-api-key': options.token } : {}),
1797
2564
  },
@@ -1801,12 +2568,17 @@ async function relayRequest(app: ReturnType<typeof TestApp.create>, options: rel
1801
2568
  return (await response.json()) as {
1802
2569
  error?: { code: number; data?: { code: string } | undefined; message: string } | undefined
1803
2570
  result?: `0x${string}` | undefined
2571
+ sponsorship_details?: { subsidized: boolean } | undefined
1804
2572
  }
1805
2573
  }
1806
2574
 
1807
2575
  declare namespace relayRequest {
1808
2576
  /** Options for one composed relay request. */
1809
2577
  type Options = {
2578
+ /** Opaque provider account attribution. */
2579
+ externalId?: string | undefined
2580
+ /** Legacy Privy external attribution id. */
2581
+ legacyExternalId?: string | undefined
1810
2582
  /** JSON-RPC method. */
1811
2583
  method: string
1812
2584
  /** Relay mount to call. */
@@ -1954,6 +2726,7 @@ function createMainnetApp(options: createMainnetApp.Options = {}) {
1954
2726
  ...(options.logger ? { logger: options.logger } : {}),
1955
2727
  relay: { feePayer: { account: feePayerAccount } },
1956
2728
  supportedChainIds: [Viem.chainId.mainnet],
2729
+ zones: options.zones,
1957
2730
  })
1958
2731
  }
1959
2732
 
@@ -1964,6 +2737,8 @@ declare namespace createMainnetApp {
1964
2737
  db?: Db.Source | undefined
1965
2738
  /** Structured request log sink. */
1966
2739
  logger?: Log.Emit | undefined
2740
+ /** Configured Zone chains. */
2741
+ zones?: TestApp.create.Options['zones'] | undefined
1967
2742
  }
1968
2743
  }
1969
2744