tapimo 0.13.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 (1143) 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 +21383 -18056
  9. package/dist/App.d.ts.map +1 -1
  10. package/dist/App.js +301 -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 +2 -2
  24. package/dist/Webhooks.js.map +1 -1
  25. package/dist/admin/App.d.ts +3936 -1337
  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 +1446 -0
  34. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  35. package/dist/admin/apps/earn-vaults.js +465 -8
  36. package/dist/admin/apps/earn-vaults.js.map +1 -1
  37. package/dist/admin/apps/organizations.d.ts +344 -3
  38. package/dist/admin/apps/organizations.d.ts.map +1 -1
  39. package/dist/admin/apps/organizations.js +288 -10
  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 +16 -16
  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 +40 -8
  76. package/dist/apps/Zones.js.map +1 -1
  77. package/dist/apps/data/App.d.ts +4310 -2548
  78. package/dist/apps/data/App.d.ts.map +1 -1
  79. package/dist/apps/data/App.js +86 -26
  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 +94 -22
  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 +1641 -352
  92. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  93. package/dist/apps/data/routes/earn.js +1561 -120
  94. package/dist/apps/data/routes/earn.js.map +1 -1
  95. package/dist/apps/data/routes/exchanges.d.ts +15 -0
  96. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  97. package/dist/apps/data/routes/exchanges.js +180 -114
  98. package/dist/apps/data/routes/exchanges.js.map +1 -1
  99. package/dist/apps/data/routes/fee-amm.d.ts +5 -0
  100. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  101. package/dist/apps/data/routes/fee-amm.js +49 -38
  102. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  103. package/dist/apps/data/routes/indexer.d.ts +125 -0
  104. package/dist/apps/data/routes/indexer.d.ts.map +1 -1
  105. package/dist/apps/data/routes/indexer.js +83 -27
  106. package/dist/apps/data/routes/indexer.js.map +1 -1
  107. package/dist/apps/data/routes/rpc.d.ts +507 -33
  108. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  109. package/dist/apps/data/routes/rpc.js +266 -156
  110. package/dist/apps/data/routes/rpc.js.map +1 -1
  111. package/dist/apps/data/routes/tokenlist.d.ts +47 -15
  112. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  113. package/dist/apps/data/routes/tokenlist.js +68 -11
  114. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  115. package/dist/apps/data/routes/tokens.d.ts +95 -93
  116. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  117. package/dist/apps/data/routes/tokens.js +26 -14
  118. package/dist/apps/data/routes/tokens.js.map +1 -1
  119. package/dist/apps/data/routes/transfers.d.ts +16 -0
  120. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  121. package/dist/apps/data/routes/transfers.js +9 -7
  122. package/dist/apps/data/routes/transfers.js.map +1 -1
  123. package/dist/apps/data/routes/verified-tokens.d.ts +4 -4
  124. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
  125. package/dist/apps/data/routes/verified-tokens.js +64 -20
  126. package/dist/apps/data/routes/verified-tokens.js.map +1 -1
  127. package/dist/apps/data/routes/webhooks.d.ts +1210 -70
  128. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  129. package/dist/apps/data/routes/webhooks.js +301 -163
  130. package/dist/apps/data/routes/webhooks.js.map +1 -1
  131. package/dist/apps/data/routes/zones.d.ts.map +1 -1
  132. package/dist/apps/data/routes/zones.js +20 -12
  133. package/dist/apps/data/routes/zones.js.map +1 -1
  134. package/dist/apps/docs/reference.js +2 -2
  135. package/dist/apps/docs/reference.js.map +1 -1
  136. package/dist/apps/index.d.ts +1 -1
  137. package/dist/apps/index.d.ts.map +1 -1
  138. package/dist/apps/index.js +1 -1
  139. package/dist/apps/index.js.map +1 -1
  140. package/dist/apps/management/App.d.ts +4119 -3297
  141. package/dist/apps/management/App.d.ts.map +1 -1
  142. package/dist/apps/management/App.js +5 -14
  143. package/dist/apps/management/App.js.map +1 -1
  144. package/dist/apps/management/Billing.d.ts +49 -8
  145. package/dist/apps/management/Billing.d.ts.map +1 -1
  146. package/dist/apps/management/Billing.js +221 -26
  147. package/dist/apps/management/Billing.js.map +1 -1
  148. package/dist/apps/management/routes/api-keys.d.ts +174 -72
  149. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  150. package/dist/apps/management/routes/api-keys.js +43 -15
  151. package/dist/apps/management/routes/api-keys.js.map +1 -1
  152. package/dist/apps/management/routes/billing.d.ts +364 -78
  153. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  154. package/dist/apps/management/routes/billing.js +274 -49
  155. package/dist/apps/management/routes/billing.js.map +1 -1
  156. package/dist/apps/management/routes/faucet.d.ts +6 -6
  157. package/dist/apps/management/routes/faucet.js +1 -1
  158. package/dist/apps/management/routes/faucet.js.map +1 -1
  159. package/dist/apps/management/routes/invitations.d.ts +99 -24
  160. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  161. package/dist/apps/management/routes/invitations.js +117 -13
  162. package/dist/apps/management/routes/invitations.js.map +1 -1
  163. package/dist/apps/management/routes/invite-links.d.ts +42 -42
  164. package/dist/apps/management/routes/me.d.ts.map +1 -1
  165. package/dist/apps/management/routes/me.js +6 -2
  166. package/dist/apps/management/routes/me.js.map +1 -1
  167. package/dist/apps/management/routes/members.d.ts +16 -16
  168. package/dist/apps/management/routes/orgs.d.ts +36 -20
  169. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  170. package/dist/apps/management/routes/orgs.js +52 -12
  171. package/dist/apps/management/routes/orgs.js.map +1 -1
  172. package/dist/apps/management/routes/projects.d.ts +40 -40
  173. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  174. package/dist/apps/management/routes/projects.js +6 -1
  175. package/dist/apps/management/routes/projects.js.map +1 -1
  176. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  177. package/dist/apps/management/routes/scopes.js +4 -1
  178. package/dist/apps/management/routes/scopes.js.map +1 -1
  179. package/dist/apps/management/routes/usage.d.ts +8 -8
  180. package/dist/apps/management/routes/usage.js +21 -4
  181. package/dist/apps/management/routes/usage.js.map +1 -1
  182. package/dist/apps/management/routes/verified-token-requests.d.ts +16 -16
  183. package/dist/apps/management/routes/webhooks.d.ts +931 -215
  184. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  185. package/dist/apps/management/routes/webhooks.js +71 -25
  186. package/dist/apps/management/routes/webhooks.js.map +1 -1
  187. package/dist/apps/mcp.d.ts +1 -1
  188. package/dist/apps/mcp.js +7 -7
  189. package/dist/apps/mcp.js.map +1 -1
  190. package/dist/apps/mpp/App.d.ts.map +1 -1
  191. package/dist/apps/mpp/App.js +35 -7
  192. package/dist/apps/mpp/App.js.map +1 -1
  193. package/dist/apps/mpp/internal/Adapter.d.ts +2 -0
  194. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  195. package/dist/apps/mpp/internal/Adapter.js +30 -1
  196. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  197. package/dist/apps/mpp/internal/Policy.d.ts +22 -4
  198. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  199. package/dist/apps/mpp/internal/Policy.js +24 -6
  200. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  201. package/dist/apps/mpp/internal/Sponsorship.d.ts +3 -0
  202. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  203. package/dist/apps/mpp/internal/Sponsorship.js +6 -3
  204. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  205. package/dist/apps/relay/App.d.ts +2 -0
  206. package/dist/apps/relay/App.d.ts.map +1 -1
  207. package/dist/apps/relay/App.js +177 -26
  208. package/dist/apps/relay/App.js.map +1 -1
  209. package/dist/apps/relay/Sponsorships.d.ts +5 -3
  210. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  211. package/dist/apps/relay/Sponsorships.js +232 -25
  212. package/dist/apps/relay/Sponsorships.js.map +1 -1
  213. package/dist/apps/{funding → routes}/Access.d.ts +4 -4
  214. package/dist/apps/routes/Access.d.ts.map +1 -0
  215. package/dist/apps/{funding → routes}/Access.js +4 -4
  216. package/dist/apps/routes/Access.js.map +1 -0
  217. package/dist/apps/{funding → routes}/App.d.ts +841 -136
  218. package/dist/apps/{funding → routes}/App.d.ts.map +1 -1
  219. package/dist/apps/{funding → routes}/App.js +17 -17
  220. package/dist/apps/routes/App.js.map +1 -0
  221. package/dist/apps/routes/Inventory.d.ts.map +1 -0
  222. package/dist/apps/{funding → routes}/Inventory.js +2 -2
  223. package/dist/apps/routes/Inventory.js.map +1 -0
  224. package/dist/apps/routes/index.d.ts +2 -0
  225. package/dist/apps/routes/index.d.ts.map +1 -0
  226. package/dist/apps/routes/index.js +2 -0
  227. package/dist/apps/routes/index.js.map +1 -0
  228. package/dist/apps/{funding → routes}/routes/chains.d.ts +7 -7
  229. package/dist/apps/routes/routes/chains.d.ts.map +1 -0
  230. package/dist/apps/{funding → routes}/routes/chains.js +25 -25
  231. package/dist/apps/routes/routes/chains.js.map +1 -0
  232. package/dist/apps/{funding → routes}/routes/deposit-addresses.d.ts +123 -59
  233. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -0
  234. package/dist/apps/{funding → routes}/routes/deposit-addresses.js +498 -223
  235. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -0
  236. package/dist/apps/{funding → routes}/routes/providers.d.ts +8 -8
  237. package/dist/apps/routes/routes/providers.d.ts.map +1 -0
  238. package/dist/apps/routes/routes/providers.js +57 -0
  239. package/dist/apps/routes/routes/providers.js.map +1 -0
  240. package/dist/apps/{funding → routes}/routes/quotes.d.ts +19 -16
  241. package/dist/apps/routes/routes/quotes.d.ts.map +1 -0
  242. package/dist/apps/{funding → routes}/routes/quotes.js +55 -38
  243. package/dist/apps/routes/routes/quotes.js.map +1 -0
  244. package/dist/apps/{funding → routes}/routes/transfers.d.ts +957 -71
  245. package/dist/apps/routes/routes/transfers.d.ts.map +1 -0
  246. package/dist/apps/routes/routes/transfers.js +1140 -0
  247. package/dist/apps/routes/routes/transfers.js.map +1 -0
  248. package/dist/cli/Cli.d.ts +30 -0
  249. package/dist/cli/Cli.d.ts.map +1 -1
  250. package/dist/cli/commands/admin.d.ts +36 -0
  251. package/dist/cli/commands/admin.d.ts.map +1 -1
  252. package/dist/cli/commands/admin.js +273 -0
  253. package/dist/cli/commands/admin.js.map +1 -1
  254. package/dist/cloudflare.d.ts +16 -14
  255. package/dist/cloudflare.d.ts.map +1 -1
  256. package/dist/cloudflare.js +26 -21
  257. package/dist/cloudflare.js.map +1 -1
  258. package/dist/db/Db.d.ts +63 -21
  259. package/dist/db/Db.d.ts.map +1 -1
  260. package/dist/db/Db.js +1052 -15
  261. package/dist/db/Db.js.map +1 -1
  262. package/dist/db/Schema.d.ts +785 -133
  263. package/dist/db/Schema.d.ts.map +1 -1
  264. package/dist/db/Schema.js +590 -162
  265. package/dist/db/Schema.js.map +1 -1
  266. package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts +4 -0
  267. package/dist/db/tables/apiKeyAdmissionBootstraps.d.ts.map +1 -0
  268. package/dist/db/tables/apiKeyAdmissionBootstraps.js +2 -0
  269. package/dist/db/tables/apiKeyAdmissionBootstraps.js.map +1 -0
  270. package/dist/db/tables/apiKeyAdmissions.d.ts +73 -0
  271. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -0
  272. package/dist/db/tables/apiKeyAdmissions.js +142 -0
  273. package/dist/db/tables/apiKeyAdmissions.js.map +1 -0
  274. package/dist/db/tables/apiKeyOwnerAdmissions.d.ts +4 -0
  275. package/dist/db/tables/apiKeyOwnerAdmissions.d.ts.map +1 -0
  276. package/dist/db/tables/apiKeyOwnerAdmissions.js +2 -0
  277. package/dist/db/tables/apiKeyOwnerAdmissions.js.map +1 -0
  278. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +20 -0
  279. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -0
  280. package/dist/db/tables/apiKeyOwnerTombstones.js +57 -0
  281. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -0
  282. package/dist/db/tables/apiKeyRevocations.d.ts +21 -0
  283. package/dist/db/tables/apiKeyRevocations.d.ts.map +1 -0
  284. package/dist/db/tables/apiKeyRevocations.js +98 -0
  285. package/dist/db/tables/apiKeyRevocations.js.map +1 -0
  286. package/dist/db/tables/authAccounts.d.ts +47 -0
  287. package/dist/db/tables/authAccounts.d.ts.map +1 -0
  288. package/dist/db/tables/authAccounts.js +72 -0
  289. package/dist/db/tables/authAccounts.js.map +1 -0
  290. package/dist/db/tables/authSessions.d.ts +12 -0
  291. package/dist/db/tables/authSessions.d.ts.map +1 -0
  292. package/dist/db/tables/authSessions.js +2 -0
  293. package/dist/db/tables/authSessions.js.map +1 -0
  294. package/dist/db/tables/authVerifications.d.ts +12 -0
  295. package/dist/db/tables/authVerifications.d.ts.map +1 -0
  296. package/dist/db/tables/authVerifications.js +2 -0
  297. package/dist/db/tables/authVerifications.js.map +1 -0
  298. package/dist/db/tables/invitations.d.ts +17 -1
  299. package/dist/db/tables/invitations.d.ts.map +1 -1
  300. package/dist/db/tables/invitations.js +123 -43
  301. package/dist/db/tables/invitations.js.map +1 -1
  302. package/dist/db/tables/memberships.d.ts +8 -0
  303. package/dist/db/tables/memberships.d.ts.map +1 -1
  304. package/dist/db/tables/memberships.js +51 -2
  305. package/dist/db/tables/memberships.js.map +1 -1
  306. package/dist/db/tables/organizations.d.ts +51 -5
  307. package/dist/db/tables/organizations.d.ts.map +1 -1
  308. package/dist/db/tables/organizations.js +135 -47
  309. package/dist/db/tables/organizations.js.map +1 -1
  310. package/dist/db/tables/projects.d.ts +27 -1
  311. package/dist/db/tables/projects.d.ts.map +1 -1
  312. package/dist/db/tables/projects.js +38 -3
  313. package/dist/db/tables/projects.js.map +1 -1
  314. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  315. package/dist/db/tables/requestUsage.js.map +1 -1
  316. package/dist/db/tables/rewardAccounts.d.ts +86 -0
  317. package/dist/db/tables/rewardAccounts.d.ts.map +1 -0
  318. package/dist/db/tables/rewardAccounts.js +88 -0
  319. package/dist/db/tables/rewardAccounts.js.map +1 -0
  320. package/dist/db/tables/rewardCampaignDistributors.d.ts +36 -0
  321. package/dist/db/tables/rewardCampaignDistributors.d.ts.map +1 -0
  322. package/dist/db/tables/rewardCampaignDistributors.js +30 -0
  323. package/dist/db/tables/rewardCampaignDistributors.js.map +1 -0
  324. package/dist/db/tables/rewardCampaigns.d.ts +171 -0
  325. package/dist/db/tables/rewardCampaigns.d.ts.map +1 -0
  326. package/dist/db/tables/rewardCampaigns.js +392 -0
  327. package/dist/db/tables/rewardCampaigns.js.map +1 -0
  328. package/dist/db/tables/rewardCredits.d.ts +53 -0
  329. package/dist/db/tables/rewardCredits.d.ts.map +1 -0
  330. package/dist/db/tables/rewardCredits.js +63 -0
  331. package/dist/db/tables/rewardCredits.js.map +1 -0
  332. package/dist/db/tables/rewardEligibilityAssociations.d.ts +61 -0
  333. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -0
  334. package/dist/db/tables/rewardEligibilityAssociations.js +103 -0
  335. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -0
  336. package/dist/db/tables/rewardRuns.d.ts +188 -0
  337. package/dist/db/tables/rewardRuns.d.ts.map +1 -0
  338. package/dist/db/tables/rewardRuns.js +278 -0
  339. package/dist/db/tables/rewardRuns.js.map +1 -0
  340. package/dist/db/tables/rewardTransactionAttempts.d.ts +100 -0
  341. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -0
  342. package/dist/db/tables/rewardTransactionAttempts.js +163 -0
  343. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -0
  344. package/dist/db/tables/routesCatalog.d.ts +58 -0
  345. package/dist/db/tables/routesCatalog.d.ts.map +1 -0
  346. package/dist/db/tables/{fundingCatalog.js → routesCatalog.js} +19 -19
  347. package/dist/db/tables/routesCatalog.js.map +1 -0
  348. package/dist/db/tables/routesDepositAddresses.d.ts +476 -0
  349. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -0
  350. package/dist/db/tables/routesDepositAddresses.js +587 -0
  351. package/dist/db/tables/routesDepositAddresses.js.map +1 -0
  352. package/dist/db/tables/{fundingDepositRequestObservations.d.ts → routesDepositRequestObservations.d.ts} +6 -6
  353. package/dist/db/tables/routesDepositRequestObservations.d.ts.map +1 -0
  354. package/dist/db/tables/{fundingDepositRequestObservations.js → routesDepositRequestObservations.js} +6 -6
  355. package/dist/db/tables/routesDepositRequestObservations.js.map +1 -0
  356. package/dist/db/tables/{fundingDeposits.d.ts → routesDeposits.d.ts} +210 -22
  357. package/dist/db/tables/routesDeposits.d.ts.map +1 -0
  358. package/dist/db/tables/routesDeposits.js +576 -0
  359. package/dist/db/tables/routesDeposits.js.map +1 -0
  360. package/dist/db/tables/routesIdempotency.d.ts +166 -0
  361. package/dist/db/tables/routesIdempotency.d.ts.map +1 -0
  362. package/dist/db/tables/routesIdempotency.js +330 -0
  363. package/dist/db/tables/routesIdempotency.js.map +1 -0
  364. package/dist/db/tables/routesSubsidies.d.ts +27 -0
  365. package/dist/db/tables/routesSubsidies.d.ts.map +1 -0
  366. package/dist/db/tables/routesSubsidies.js +45 -0
  367. package/dist/db/tables/routesSubsidies.js.map +1 -0
  368. package/dist/db/tables/{fundingTransferEvents.d.ts → routesTransferEvents.d.ts} +3 -3
  369. package/dist/db/tables/routesTransferEvents.d.ts.map +1 -0
  370. package/dist/db/tables/{fundingTransferEvents.js → routesTransferEvents.js} +3 -3
  371. package/dist/db/tables/routesTransferEvents.js.map +1 -0
  372. package/dist/db/tables/routesTransferSubsidies.d.ts +19 -0
  373. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -0
  374. package/dist/db/tables/routesTransferSubsidies.js +17 -0
  375. package/dist/db/tables/routesTransferSubsidies.js.map +1 -0
  376. package/dist/db/tables/routesTransferSubsidyNonces.d.ts +51 -0
  377. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -0
  378. package/dist/db/tables/routesTransferSubsidyNonces.js +82 -0
  379. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -0
  380. package/dist/db/tables/routesTransferTransactions.d.ts +77 -0
  381. package/dist/db/tables/routesTransferTransactions.d.ts.map +1 -0
  382. package/dist/db/tables/routesTransferTransactions.js +86 -0
  383. package/dist/db/tables/routesTransferTransactions.js.map +1 -0
  384. package/dist/db/tables/routesTransfers.d.ts +319 -0
  385. package/dist/db/tables/routesTransfers.d.ts.map +1 -0
  386. package/dist/db/tables/routesTransfers.js +372 -0
  387. package/dist/db/tables/routesTransfers.js.map +1 -0
  388. package/dist/db/tables/sponsoredTransactions.d.ts +112 -13
  389. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  390. package/dist/db/tables/sponsoredTransactions.js +241 -38
  391. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  392. package/dist/db/tables/sponsorshipAttributions.d.ts +69 -0
  393. package/dist/db/tables/sponsorshipAttributions.d.ts.map +1 -0
  394. package/dist/db/tables/sponsorshipAttributions.js +77 -0
  395. package/dist/db/tables/sponsorshipAttributions.js.map +1 -0
  396. package/dist/db/tables/sponsorshipReconciliationCursors.d.ts +22 -0
  397. package/dist/db/tables/sponsorshipReconciliationCursors.d.ts.map +1 -0
  398. package/dist/db/tables/sponsorshipReconciliationCursors.js +45 -0
  399. package/dist/db/tables/sponsorshipReconciliationCursors.js.map +1 -0
  400. package/dist/db/tables/stripeCustomers.d.ts +11 -0
  401. package/dist/db/tables/stripeCustomers.d.ts.map +1 -1
  402. package/dist/db/tables/stripeCustomers.js +13 -0
  403. package/dist/db/tables/stripeCustomers.js.map +1 -1
  404. package/dist/db/tables/users.d.ts +17 -1
  405. package/dist/db/tables/users.d.ts.map +1 -1
  406. package/dist/db/tables/users.js +47 -2
  407. package/dist/db/tables/users.js.map +1 -1
  408. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  409. package/dist/db/tables/webhookQueueEvents.js +5 -1
  410. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  411. package/dist/db/tables/webhookSubscriptions.d.ts +22 -10
  412. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  413. package/dist/db/tables/webhookSubscriptions.js +50 -15
  414. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  415. package/dist/handlers/internal/executionError.d.ts +2 -2
  416. package/dist/handlers/internal/executionError.d.ts.map +1 -1
  417. package/dist/handlers/internal/executionError.js +1 -2
  418. package/dist/handlers/internal/executionError.js.map +1 -1
  419. package/dist/handlers/internal/multisig.d.ts +4 -232
  420. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  421. package/dist/handlers/internal/multisig.js +11 -537
  422. package/dist/handlers/internal/multisig.js.map +1 -1
  423. package/dist/handlers/internal/sponsorship.d.ts +19 -8
  424. package/dist/handlers/internal/sponsorship.d.ts.map +1 -1
  425. package/dist/handlers/internal/sponsorship.js +13 -9
  426. package/dist/handlers/internal/sponsorship.js.map +1 -1
  427. package/dist/handlers/relay.d.ts +9 -12
  428. package/dist/handlers/relay.d.ts.map +1 -1
  429. package/dist/handlers/relay.js +81 -85
  430. package/dist/handlers/relay.js.map +1 -1
  431. package/dist/index.d.ts +0 -17
  432. package/dist/index.d.ts.map +1 -1
  433. package/dist/index.js +0 -17
  434. package/dist/index.js.map +1 -1
  435. package/dist/internal/AssetResponse.d.ts +12 -0
  436. package/dist/internal/AssetResponse.d.ts.map +1 -0
  437. package/dist/internal/AssetResponse.js +21 -0
  438. package/dist/internal/AssetResponse.js.map +1 -0
  439. package/dist/internal/Auth.d.ts +48 -12
  440. package/dist/internal/Auth.d.ts.map +1 -1
  441. package/dist/internal/Auth.js +603 -175
  442. package/dist/internal/Auth.js.map +1 -1
  443. package/dist/internal/BetterAuth.d.ts +1488 -0
  444. package/dist/internal/BetterAuth.d.ts.map +1 -0
  445. package/dist/internal/BetterAuth.js +253 -0
  446. package/dist/internal/BetterAuth.js.map +1 -0
  447. package/dist/internal/Cache.d.ts +2 -0
  448. package/dist/internal/Cache.d.ts.map +1 -1
  449. package/dist/internal/Cache.js +2 -0
  450. package/dist/internal/Cache.js.map +1 -1
  451. package/dist/internal/EarnRates.d.ts +26 -3
  452. package/dist/internal/EarnRates.d.ts.map +1 -1
  453. package/dist/internal/EarnRates.js +84 -19
  454. package/dist/internal/EarnRates.js.map +1 -1
  455. package/dist/internal/EarnSharePrices.d.ts +120 -0
  456. package/dist/internal/EarnSharePrices.d.ts.map +1 -0
  457. package/dist/internal/EarnSharePrices.js +179 -0
  458. package/dist/internal/EarnSharePrices.js.map +1 -0
  459. package/dist/internal/EarnVaults.d.ts +4 -0
  460. package/dist/internal/EarnVaults.d.ts.map +1 -1
  461. package/dist/internal/EarnVaults.js +31 -14
  462. package/dist/internal/EarnVaults.js.map +1 -1
  463. package/dist/internal/Email.d.ts +37 -0
  464. package/dist/internal/Email.d.ts.map +1 -0
  465. package/dist/internal/Email.js +16 -0
  466. package/dist/internal/Email.js.map +1 -0
  467. package/dist/internal/Log.d.ts +32 -28
  468. package/dist/internal/Log.d.ts.map +1 -1
  469. package/dist/internal/Log.js +18 -11
  470. package/dist/internal/Log.js.map +1 -1
  471. package/dist/internal/MetricSink.d.ts +3 -0
  472. package/dist/internal/MetricSink.d.ts.map +1 -1
  473. package/dist/internal/MetricSink.js +67 -8
  474. package/dist/internal/MetricSink.js.map +1 -1
  475. package/dist/internal/Mpp.d.ts.map +1 -1
  476. package/dist/internal/Mpp.js +20 -25
  477. package/dist/internal/Mpp.js.map +1 -1
  478. package/dist/internal/OpenApi.d.ts +26 -3
  479. package/dist/internal/OpenApi.d.ts.map +1 -1
  480. package/dist/internal/OpenApi.js +25 -10
  481. package/dist/internal/OpenApi.js.map +1 -1
  482. package/dist/internal/Provider.d.ts +1 -1
  483. package/dist/internal/Provider.d.ts.map +1 -1
  484. package/dist/internal/RateLimit.d.ts.map +1 -1
  485. package/dist/internal/RateLimit.js +13 -1
  486. package/dist/internal/RateLimit.js.map +1 -1
  487. package/dist/internal/Store.d.ts +16 -0
  488. package/dist/internal/Store.d.ts.map +1 -1
  489. package/dist/internal/Store.js +59 -8
  490. package/dist/internal/Store.js.map +1 -1
  491. package/dist/internal/Tidx.d.ts +9 -2
  492. package/dist/internal/Tidx.d.ts.map +1 -1
  493. package/dist/internal/Tidx.js +78 -11
  494. package/dist/internal/Tidx.js.map +1 -1
  495. package/dist/internal/Timing.d.ts +26 -0
  496. package/dist/internal/Timing.d.ts.map +1 -1
  497. package/dist/internal/Timing.js +63 -5
  498. package/dist/internal/Timing.js.map +1 -1
  499. package/dist/internal/VercelOidc.d.ts +94 -0
  500. package/dist/internal/VercelOidc.d.ts.map +1 -0
  501. package/dist/internal/VercelOidc.js +128 -0
  502. package/dist/internal/VercelOidc.js.map +1 -0
  503. package/dist/internal/VerifiedTokens.d.ts +2 -8
  504. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  505. package/dist/internal/VerifiedTokens.js +24 -24
  506. package/dist/internal/VerifiedTokens.js.map +1 -1
  507. package/dist/internal/Viem.d.ts +46 -2068
  508. package/dist/internal/Viem.d.ts.map +1 -1
  509. package/dist/internal/Viem.js +171 -11
  510. package/dist/internal/Viem.js.map +1 -1
  511. package/dist/internal/Webhooks.d.ts +12 -4
  512. package/dist/internal/Webhooks.d.ts.map +1 -1
  513. package/dist/internal/Webhooks.js +9 -3
  514. package/dist/internal/Webhooks.js.map +1 -1
  515. package/dist/internal/ZoneRpc.d.ts +7 -0
  516. package/dist/internal/ZoneRpc.d.ts.map +1 -0
  517. package/dist/internal/ZoneRpc.js +49 -0
  518. package/dist/internal/ZoneRpc.js.map +1 -0
  519. package/dist/internal/index.d.ts +3 -1
  520. package/dist/internal/index.d.ts.map +1 -1
  521. package/dist/internal/index.js +3 -1
  522. package/dist/internal/index.js.map +1 -1
  523. package/dist/internal/rewards/Audit.d.ts +88 -0
  524. package/dist/internal/rewards/Audit.d.ts.map +1 -0
  525. package/dist/internal/rewards/Audit.js +134 -0
  526. package/dist/internal/rewards/Audit.js.map +1 -0
  527. package/dist/internal/rewards/Campaigns.d.ts +572 -0
  528. package/dist/internal/rewards/Campaigns.d.ts.map +1 -0
  529. package/dist/internal/rewards/Campaigns.js +531 -0
  530. package/dist/internal/rewards/Campaigns.js.map +1 -0
  531. package/dist/internal/rewards/Credits.d.ts +76 -0
  532. package/dist/internal/rewards/Credits.d.ts.map +1 -0
  533. package/dist/internal/rewards/Credits.js +95 -0
  534. package/dist/internal/rewards/Credits.js.map +1 -0
  535. package/dist/internal/rewards/Events.d.ts +100 -0
  536. package/dist/internal/rewards/Events.d.ts.map +1 -0
  537. package/dist/internal/rewards/Events.js +340 -0
  538. package/dist/internal/rewards/Events.js.map +1 -0
  539. package/dist/internal/rewards/Projection.d.ts +237 -0
  540. package/dist/internal/rewards/Projection.d.ts.map +1 -0
  541. package/dist/internal/rewards/Projection.js +616 -0
  542. package/dist/internal/rewards/Projection.js.map +1 -0
  543. package/dist/internal/rewards/Rates.d.ts +44 -0
  544. package/dist/internal/rewards/Rates.d.ts.map +1 -0
  545. package/dist/internal/rewards/Rates.js +60 -0
  546. package/dist/internal/rewards/Rates.js.map +1 -0
  547. package/dist/internal/rewards/Read.d.ts +158 -0
  548. package/dist/internal/rewards/Read.d.ts.map +1 -0
  549. package/dist/internal/rewards/Read.js +292 -0
  550. package/dist/internal/rewards/Read.js.map +1 -0
  551. package/dist/internal/rewards/Runner.d.ts +164 -0
  552. package/dist/internal/rewards/Runner.d.ts.map +1 -0
  553. package/dist/internal/rewards/Runner.js +1778 -0
  554. package/dist/internal/rewards/Runner.js.map +1 -0
  555. package/dist/internal/rewards/Signer.d.ts +224 -0
  556. package/dist/internal/rewards/Signer.d.ts.map +1 -0
  557. package/dist/internal/rewards/Signer.js +135 -0
  558. package/dist/internal/rewards/Signer.js.map +1 -0
  559. package/dist/internal/rewards/index.d.ts +15 -0
  560. package/dist/internal/rewards/index.d.ts.map +1 -0
  561. package/dist/internal/rewards/index.js +15 -0
  562. package/dist/internal/rewards/index.js.map +1 -0
  563. package/dist/internal/{funding → routes}/Action.d.ts +12 -1
  564. package/dist/internal/routes/Action.d.ts.map +1 -0
  565. package/dist/internal/{funding → routes}/Action.js +17 -9
  566. package/dist/internal/routes/Action.js.map +1 -0
  567. package/dist/internal/{funding → routes}/Catalog.d.ts +20 -20
  568. package/dist/internal/routes/Catalog.d.ts.map +1 -0
  569. package/dist/internal/{funding → routes}/Catalog.js +29 -29
  570. package/dist/internal/routes/Catalog.js.map +1 -0
  571. package/dist/internal/{funding → routes}/Chain.d.ts +10 -10
  572. package/dist/internal/routes/Chain.d.ts.map +1 -0
  573. package/dist/internal/{funding → routes}/Chain.js +3 -3
  574. package/dist/internal/routes/Chain.js.map +1 -0
  575. package/dist/internal/{funding → routes}/Deposit.d.ts +45 -23
  576. package/dist/internal/routes/Deposit.d.ts.map +1 -0
  577. package/dist/internal/{funding → routes}/Deposit.js +60 -27
  578. package/dist/internal/routes/Deposit.js.map +1 -0
  579. package/dist/internal/{funding → routes}/DepositAddress.d.ts +56 -27
  580. package/dist/internal/routes/DepositAddress.d.ts.map +1 -0
  581. package/dist/internal/{funding → routes}/DepositAddress.js +95 -33
  582. package/dist/internal/routes/DepositAddress.js.map +1 -0
  583. package/dist/internal/{funding → routes}/DepositWebhook.d.ts +4 -4
  584. package/dist/internal/routes/DepositWebhook.d.ts.map +1 -0
  585. package/dist/internal/{funding → routes}/DepositWebhook.js +4 -3
  586. package/dist/internal/routes/DepositWebhook.js.map +1 -0
  587. package/dist/internal/routes/Economics.d.ts +25 -0
  588. package/dist/internal/routes/Economics.d.ts.map +1 -0
  589. package/dist/internal/routes/Economics.js +28 -0
  590. package/dist/internal/routes/Economics.js.map +1 -0
  591. package/dist/internal/{funding → routes}/Evidence.d.ts +3 -3
  592. package/dist/internal/routes/Evidence.d.ts.map +1 -0
  593. package/dist/internal/{funding → routes}/Evidence.js +9 -17
  594. package/dist/internal/routes/Evidence.js.map +1 -0
  595. package/dist/internal/routes/Observability.d.ts +154 -0
  596. package/dist/internal/routes/Observability.d.ts.map +1 -0
  597. package/dist/internal/routes/Observability.js +389 -0
  598. package/dist/internal/routes/Observability.js.map +1 -0
  599. package/dist/internal/{funding → routes}/Provider.d.ts +350 -104
  600. package/dist/internal/routes/Provider.d.ts.map +1 -0
  601. package/dist/internal/{funding → routes}/Provider.js +233 -97
  602. package/dist/internal/routes/Provider.js.map +1 -0
  603. package/dist/internal/{funding → routes}/Reconciliation.d.ts +11 -6
  604. package/dist/internal/routes/Reconciliation.d.ts.map +1 -0
  605. package/dist/internal/{funding → routes}/Reconciliation.js +408 -158
  606. package/dist/internal/routes/Reconciliation.js.map +1 -0
  607. package/dist/internal/routes/Route.d.ts +21 -0
  608. package/dist/internal/routes/Route.d.ts.map +1 -0
  609. package/dist/internal/{funding → routes}/Route.js +1 -1
  610. package/dist/internal/routes/Route.js.map +1 -0
  611. package/dist/internal/{funding → routes}/SourceObservation.d.ts +6 -6
  612. package/dist/internal/routes/SourceObservation.d.ts.map +1 -0
  613. package/dist/internal/{funding → routes}/SourceObservation.js +13 -15
  614. package/dist/internal/routes/SourceObservation.js.map +1 -0
  615. package/dist/internal/{funding → routes}/Subsidy.d.ts +48 -3
  616. package/dist/internal/routes/Subsidy.d.ts.map +1 -0
  617. package/dist/internal/{funding → routes}/Subsidy.js +43 -3
  618. package/dist/internal/routes/Subsidy.js.map +1 -0
  619. package/dist/internal/{funding → routes}/Token.d.ts +4 -4
  620. package/dist/internal/routes/Token.d.ts.map +1 -0
  621. package/dist/internal/{funding → routes}/Token.js +3 -3
  622. package/dist/internal/routes/Token.js.map +1 -0
  623. package/dist/internal/{funding → routes}/Transfer.d.ts +324 -34
  624. package/dist/internal/routes/Transfer.d.ts.map +1 -0
  625. package/dist/internal/routes/Transfer.js +728 -0
  626. package/dist/internal/routes/Transfer.js.map +1 -0
  627. package/dist/internal/routes/TransferReconciliation.d.ts +55 -0
  628. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -0
  629. package/dist/internal/routes/TransferReconciliation.js +422 -0
  630. package/dist/internal/routes/TransferReconciliation.js.map +1 -0
  631. package/dist/internal/routes/TransferSubsidy.d.ts +201 -0
  632. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -0
  633. package/dist/internal/routes/TransferSubsidy.js +256 -0
  634. package/dist/internal/routes/TransferSubsidy.js.map +1 -0
  635. package/dist/internal/routes/TransferWebhook.d.ts +21 -0
  636. package/dist/internal/routes/TransferWebhook.d.ts.map +1 -0
  637. package/dist/internal/routes/TransferWebhook.js +43 -0
  638. package/dist/internal/routes/TransferWebhook.js.map +1 -0
  639. package/dist/internal/{funding → routes}/index.d.ts +3 -0
  640. package/dist/internal/routes/index.d.ts.map +1 -0
  641. package/dist/internal/{funding → routes}/index.js +3 -0
  642. package/dist/internal/routes/index.js.map +1 -0
  643. package/dist/internal/{funding → routes}/providers/across.d.ts +4 -4
  644. package/dist/internal/routes/providers/across.d.ts.map +1 -0
  645. package/dist/internal/{funding → routes}/providers/across.js +13 -13
  646. package/dist/internal/routes/providers/across.js.map +1 -0
  647. package/dist/internal/{funding → routes}/providers/relay.d.ts +21 -12
  648. package/dist/internal/routes/providers/relay.d.ts.map +1 -0
  649. package/dist/internal/{funding → routes}/providers/relay.js +197 -122
  650. package/dist/internal/routes/providers/relay.js.map +1 -0
  651. package/dist/internal/{funding → routes}/providers/rhino.d.ts +4 -4
  652. package/dist/internal/routes/providers/rhino.d.ts.map +1 -0
  653. package/dist/internal/{funding → routes}/providers/rhino.js +10 -10
  654. package/dist/internal/routes/providers/rhino.js.map +1 -0
  655. package/dist/internal/{funding → routes}/providers/squid.d.ts +4 -4
  656. package/dist/internal/routes/providers/squid.d.ts.map +1 -0
  657. package/dist/internal/{funding → routes}/providers/squid.js +14 -14
  658. package/dist/internal/routes/providers/squid.js.map +1 -0
  659. package/dist/internal/routes/providers/stargate.d.ts +165 -0
  660. package/dist/internal/routes/providers/stargate.d.ts.map +1 -0
  661. package/dist/internal/routes/providers/stargate.js +898 -0
  662. package/dist/internal/routes/providers/stargate.js.map +1 -0
  663. package/dist/internal/{funding → routes}/providers/symbiosis.d.ts +4 -4
  664. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -0
  665. package/dist/internal/{funding → routes}/providers/symbiosis.js +30 -20
  666. package/dist/internal/routes/providers/symbiosis.js.map +1 -0
  667. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
  668. package/dist/internal/webhookDestinations/slack.js +22 -6
  669. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  670. package/dist/providers/index.d.ts +12 -12
  671. package/dist/providers/index.d.ts.map +1 -1
  672. package/dist/providers/index.js +12 -12
  673. package/dist/providers/index.js.map +1 -1
  674. package/dist/server.d.ts +19 -0
  675. package/dist/server.d.ts.map +1 -0
  676. package/dist/server.js +19 -0
  677. package/dist/server.js.map +1 -0
  678. package/package.json +15 -4
  679. package/src/ApiKey.ts +1 -1
  680. package/src/ApiKeys.test.ts +1033 -3
  681. package/src/ApiKeys.ts +489 -48
  682. package/src/App.test-d.ts +1 -1
  683. package/src/App.test.ts +216 -25
  684. package/src/App.ts +335 -31
  685. package/src/Assets.test.ts +2 -2
  686. package/src/Assets.ts +3 -1
  687. package/src/Auth.test-d.ts +1 -1
  688. package/src/Client.test-d.ts +611 -101
  689. package/src/Handler.ts +0 -1
  690. package/src/OpenApi.contract.test.ts +195 -0
  691. package/src/Scope.ts +17 -5
  692. package/src/Webhooks.ts +2 -2
  693. package/src/admin/App.test.ts +30 -2
  694. package/src/admin/App.ts +42 -6
  695. package/src/admin/apps/api-keys.test.ts +267 -5
  696. package/src/admin/apps/api-keys.ts +100 -50
  697. package/src/admin/apps/earn-vaults.test.ts +158 -0
  698. package/src/admin/apps/earn-vaults.ts +681 -7
  699. package/src/admin/apps/organizations.test.ts +342 -1
  700. package/src/admin/apps/organizations.ts +368 -8
  701. package/src/admin/apps/routes-support.test.ts +200 -0
  702. package/src/admin/apps/routes-support.ts +201 -0
  703. package/src/admin/apps/routes.test.ts +450 -0
  704. package/src/admin/apps/routes.ts +896 -0
  705. package/src/admin/apps/scopes.test.ts +15 -5
  706. package/src/admin/apps/subsidies.test.ts +306 -0
  707. package/src/admin/apps/subsidies.ts +457 -0
  708. package/src/admin/apps/verified-tokens.test.ts +8 -3
  709. package/src/admin/apps/verified-tokens.ts +3 -3
  710. package/src/admin/ui/plugin.ts +1 -2
  711. package/src/admin/ui/src/components/RewardCampaignForm.tsx +1009 -0
  712. package/src/admin/ui/src/lib/config.ts +11 -2
  713. package/src/admin/ui/src/lib/earn-vaults.ts +2 -2
  714. package/src/admin/ui/src/lib/organizations.test.ts +147 -3
  715. package/src/admin/ui/src/lib/organizations.ts +136 -0
  716. package/src/admin/ui/src/lib/query-client.ts +1 -1
  717. package/src/admin/ui/src/lib/reward-campaigns.ts +136 -0
  718. package/src/admin/ui/src/lib/routes.test.ts +88 -0
  719. package/src/admin/ui/src/lib/routes.ts +304 -0
  720. package/src/admin/ui/src/lib/subsidies.ts +75 -0
  721. package/src/admin/ui/src/routeTree.gen.ts +63 -0
  722. package/src/admin/ui/src/routes/__root.tsx +12 -1
  723. package/src/admin/ui/src/routes/api-keys.tsx +196 -84
  724. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +105 -70
  725. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +334 -2
  726. package/src/admin/ui/src/routes/routes.tsx +1615 -0
  727. package/src/admin/ui/src/routes/routes_.support.tsx +248 -0
  728. package/src/admin/ui/src/routes/subsidies.tsx +799 -0
  729. package/src/admin/ui.generated.ts +144 -69
  730. package/src/analytics/Analytics.test.ts +108 -18
  731. package/src/analytics/Analytics.ts +38 -6
  732. package/src/analytics/tables/requestEvents.test.ts +100 -0
  733. package/src/analytics/tables/requestEvents.ts +10 -1
  734. package/src/analytics/tables/routesLifecycleIntervals.ts +140 -0
  735. package/src/apps/Zones.test.ts +18 -3
  736. package/src/apps/Zones.ts +55 -8
  737. package/src/apps/composition.test.ts +68 -59
  738. package/src/apps/data/App.test.ts +154 -2
  739. package/src/apps/data/App.ts +102 -33
  740. package/src/apps/data/routes/activities.test.ts +419 -7
  741. package/src/apps/data/routes/activities.ts +683 -216
  742. package/src/apps/data/routes/balances.test.ts +2 -2
  743. package/src/apps/data/routes/blocks.test.ts +46 -1
  744. package/src/apps/data/routes/coingecko.test.ts +419 -1
  745. package/src/apps/data/routes/coingecko.ts +309 -253
  746. package/src/apps/data/routes/earn.discovery.test.ts +274 -0
  747. package/src/apps/data/routes/earn.test.ts +1661 -29
  748. package/src/apps/data/routes/earn.ts +2314 -328
  749. package/src/apps/data/routes/exchanges.test.ts +752 -30
  750. package/src/apps/data/routes/exchanges.ts +954 -753
  751. package/src/apps/data/routes/fee-amm.test.ts +224 -0
  752. package/src/apps/data/routes/fee-amm.ts +208 -178
  753. package/src/apps/data/routes/indexer.test.ts +389 -0
  754. package/src/apps/data/routes/indexer.ts +165 -69
  755. package/src/apps/data/routes/receipts.test.ts +1 -1
  756. package/src/apps/data/routes/rpc.test.ts +352 -8
  757. package/src/apps/data/routes/rpc.ts +407 -219
  758. package/src/apps/data/routes/rpc.zone.test.ts +340 -0
  759. package/src/apps/data/routes/tokenlist.test.ts +285 -0
  760. package/src/apps/data/routes/tokenlist.ts +173 -88
  761. package/src/apps/data/routes/tokens.test.ts +93 -3
  762. package/src/apps/data/routes/tokens.ts +39 -23
  763. package/src/apps/data/routes/transactions.test.ts +1 -1
  764. package/src/apps/data/routes/transfers.test.ts +56 -24
  765. package/src/apps/data/routes/transfers.ts +19 -8
  766. package/src/apps/data/routes/valuation.test.ts +1 -1
  767. package/src/apps/data/routes/verified-tokens.test.ts +345 -0
  768. package/src/apps/data/routes/verified-tokens.ts +99 -29
  769. package/src/apps/data/routes/webhooks.test.ts +659 -81
  770. package/src/apps/data/routes/webhooks.ts +1104 -817
  771. package/src/apps/data/routes/zones.test.ts +148 -71
  772. package/src/apps/data/routes/zones.ts +71 -55
  773. package/src/apps/docs/reference.ts +2 -2
  774. package/src/apps/index.ts +1 -1
  775. package/src/apps/management/App.ts +9 -51
  776. package/src/apps/management/Billing.test.ts +375 -14
  777. package/src/apps/management/Billing.ts +283 -34
  778. package/src/apps/management/routes/api-keys.test.ts +269 -7
  779. package/src/apps/management/routes/api-keys.ts +61 -20
  780. package/src/apps/management/routes/billing.test.ts +477 -15
  781. package/src/apps/management/routes/billing.ts +377 -50
  782. package/src/apps/management/routes/faucet.test.ts +1 -1
  783. package/src/apps/management/routes/faucet.ts +1 -1
  784. package/src/apps/management/routes/invitations.test.ts +270 -3
  785. package/src/apps/management/routes/invitations.ts +185 -15
  786. package/src/apps/management/routes/invoicePreview.test.ts +549 -0
  787. package/src/apps/management/routes/me.test.ts +246 -5
  788. package/src/apps/management/routes/me.ts +7 -2
  789. package/src/apps/management/routes/members.test.ts +108 -0
  790. package/src/apps/management/routes/orgs.test.ts +191 -3
  791. package/src/apps/management/routes/orgs.ts +58 -11
  792. package/src/apps/management/routes/projects.test.ts +33 -3
  793. package/src/apps/management/routes/projects.ts +6 -1
  794. package/src/apps/management/routes/scopes.test.ts +30 -2
  795. package/src/apps/management/routes/scopes.ts +4 -1
  796. package/src/apps/management/routes/usage.test.ts +32 -0
  797. package/src/apps/management/routes/usage.ts +22 -4
  798. package/src/apps/management/routes/webhooks.test.ts +49 -26
  799. package/src/apps/management/routes/webhooks.ts +93 -38
  800. package/src/apps/mcp.test.ts +6 -6
  801. package/src/apps/mcp.ts +7 -7
  802. package/src/apps/mpp/App.ts +37 -7
  803. package/src/apps/mpp/Mpp.test.ts +49 -8
  804. package/src/apps/mpp/Mpp.zone.test.ts +219 -0
  805. package/src/apps/mpp/internal/Adapter.ts +34 -0
  806. package/src/apps/mpp/internal/Policy.test.ts +86 -31
  807. package/src/apps/mpp/internal/Policy.ts +49 -7
  808. package/src/apps/mpp/internal/Sponsorship.test.ts +207 -0
  809. package/src/apps/mpp/internal/Sponsorship.ts +9 -3
  810. package/src/apps/relay/App.test.ts +1024 -38
  811. package/src/apps/relay/App.ts +228 -32
  812. package/src/apps/relay/App.zone-billing.test.ts +257 -0
  813. package/src/apps/relay/Sponsorships.test.ts +67 -4
  814. package/src/apps/relay/Sponsorships.ts +253 -29
  815. package/src/apps/relay/Sponsorships.zone.test.ts +102 -0
  816. package/src/apps/{funding → routes}/Access.ts +6 -6
  817. package/src/apps/routes/App.test.ts +165 -0
  818. package/src/apps/routes/App.ts +96 -0
  819. package/src/apps/{funding → routes}/Inventory.ts +2 -2
  820. package/src/apps/routes/index.ts +1 -0
  821. package/src/apps/{funding → routes}/routes/chains.test.ts +66 -66
  822. package/src/apps/{funding → routes}/routes/chains.ts +23 -23
  823. package/src/apps/{funding → routes}/routes/deposit-addresses.test.ts +1362 -462
  824. package/src/apps/{funding → routes}/routes/deposit-addresses.ts +568 -248
  825. package/src/apps/{funding → routes}/routes/providers.test.ts +27 -33
  826. package/src/apps/{funding → routes}/routes/providers.ts +23 -23
  827. package/src/apps/{funding → routes}/routes/quotes.test.ts +298 -41
  828. package/src/apps/{funding → routes}/routes/quotes.ts +57 -40
  829. package/src/apps/routes/routes/transfers.test.ts +2876 -0
  830. package/src/apps/routes/routes/transfers.ts +1332 -0
  831. package/src/cli/Cli.test.ts +1 -1
  832. package/src/cli/commands/admin.test.ts +748 -1
  833. package/src/cli/commands/admin.ts +278 -0
  834. package/src/cloudflare.ts +52 -47
  835. package/src/db/Db.test.ts +245 -2
  836. package/src/db/Db.ts +1511 -34
  837. package/src/db/Schema.ts +744 -228
  838. package/src/db/tables/apiKeyAdmissionBootstraps.ts +4 -0
  839. package/src/db/tables/apiKeyAdmissions.ts +218 -0
  840. package/src/db/tables/apiKeyOwnerAdmissions.ts +4 -0
  841. package/src/db/tables/apiKeyOwnerTombstones.ts +81 -0
  842. package/src/db/tables/apiKeyRevocations.test.ts +74 -0
  843. package/src/db/tables/apiKeyRevocations.ts +121 -0
  844. package/src/db/tables/authAccounts.ts +105 -0
  845. package/src/db/tables/authSessions.ts +13 -0
  846. package/src/db/tables/authVerifications.ts +13 -0
  847. package/src/db/tables/invitations.ts +142 -45
  848. package/src/db/tables/memberships.ts +79 -3
  849. package/src/db/tables/organizations.test.ts +725 -7
  850. package/src/db/tables/organizations.ts +182 -49
  851. package/src/db/tables/projects.test.ts +71 -0
  852. package/src/db/tables/projects.ts +59 -4
  853. package/src/db/tables/requestUsage.ts +4 -1
  854. package/src/db/tables/rewardAccounts.ts +178 -0
  855. package/src/db/tables/rewardCampaignDistributors.ts +68 -0
  856. package/src/db/tables/rewardCampaigns.test.ts +1388 -0
  857. package/src/db/tables/rewardCampaigns.ts +647 -0
  858. package/src/db/tables/rewardCredits.ts +110 -0
  859. package/src/db/tables/rewardEligibilityAssociations.test.ts +271 -0
  860. package/src/db/tables/rewardEligibilityAssociations.ts +184 -0
  861. package/src/db/tables/rewardRuns.ts +514 -0
  862. package/src/db/tables/rewardTransactionAttempts.ts +272 -0
  863. package/src/db/tables/routesCatalog.test.ts +185 -0
  864. package/src/db/tables/routesCatalog.ts +163 -0
  865. package/src/db/tables/routesDepositAddresses.test.ts +1048 -0
  866. package/src/db/tables/routesDepositAddresses.ts +1008 -0
  867. package/src/db/tables/{fundingDepositRequestObservations.test.ts → routesDepositRequestObservations.test.ts} +13 -14
  868. package/src/db/tables/{fundingDepositRequestObservations.ts → routesDepositRequestObservations.ts} +10 -10
  869. package/src/db/tables/{fundingDeposits.test.ts → routesDeposits.test.ts} +316 -46
  870. package/src/db/tables/routesDeposits.ts +1062 -0
  871. package/src/db/tables/routesIdempotency.test.ts +796 -0
  872. package/src/db/tables/routesIdempotency.ts +496 -0
  873. package/src/db/tables/routesSubsidies.test.ts +120 -0
  874. package/src/db/tables/routesSubsidies.ts +71 -0
  875. package/src/db/tables/{fundingTransferEvents.ts → routesTransferEvents.ts} +4 -4
  876. package/src/db/tables/routesTransferSubsidies.ts +38 -0
  877. package/src/db/tables/routesTransferSubsidyNonces.ts +124 -0
  878. package/src/db/tables/routesTransferTransactions.test.ts +195 -0
  879. package/src/db/tables/routesTransferTransactions.ts +158 -0
  880. package/src/db/tables/routesTransfers.test.ts +338 -0
  881. package/src/db/tables/routesTransfers.ts +662 -0
  882. package/src/db/tables/sponsoredTransactions.test.ts +563 -1
  883. package/src/db/tables/sponsoredTransactions.ts +386 -42
  884. package/src/db/tables/sponsorshipAttributions.test.ts +160 -0
  885. package/src/db/tables/sponsorshipAttributions.ts +168 -0
  886. package/src/db/tables/sponsorshipReconciliationCursors.test.ts +115 -0
  887. package/src/db/tables/sponsorshipReconciliationCursors.ts +67 -0
  888. package/src/db/tables/stripeCustomers.test.ts +85 -0
  889. package/src/db/tables/stripeCustomers.ts +24 -0
  890. package/src/db/tables/users.test.ts +129 -0
  891. package/src/db/tables/users.ts +49 -3
  892. package/src/db/tables/webhookQueueEvents.ts +8 -1
  893. package/src/db/tables/webhookSubscriptions.ts +103 -21
  894. package/src/handlers/internal/executionError.ts +3 -4
  895. package/src/handlers/internal/multisig.ts +13 -816
  896. package/src/handlers/internal/sponsorship.ts +26 -10
  897. package/src/handlers/relay.test-d.ts +9 -1
  898. package/src/handlers/relay.test.ts +823 -3
  899. package/src/handlers/relay.ts +127 -107
  900. package/src/index.test-d.ts +7 -0
  901. package/src/index.ts +0 -17
  902. package/src/internal/AssetResponse.ts +26 -0
  903. package/src/internal/Auth.test.ts +1564 -9
  904. package/src/internal/Auth.ts +833 -239
  905. package/src/internal/BetterAuth.test.ts +242 -0
  906. package/src/internal/BetterAuth.ts +349 -0
  907. package/src/internal/Cache.ts +2 -0
  908. package/src/internal/EarnRates.test.ts +17 -0
  909. package/src/internal/EarnRates.ts +124 -31
  910. package/src/internal/EarnSharePrices.test.ts +182 -0
  911. package/src/internal/EarnSharePrices.ts +313 -0
  912. package/src/internal/EarnVaults.test.ts +21 -0
  913. package/src/internal/EarnVaults.ts +37 -15
  914. package/src/internal/Email.ts +54 -0
  915. package/src/internal/Idempotency.test.ts +2 -2
  916. package/src/internal/Log.test-d.ts +10 -7
  917. package/src/internal/Log.test.ts +114 -16
  918. package/src/internal/Log.ts +55 -40
  919. package/src/internal/MetricSink.test.ts +313 -26
  920. package/src/internal/MetricSink.ts +73 -8
  921. package/src/internal/Mpp.test.ts +31 -0
  922. package/src/internal/Mpp.ts +21 -24
  923. package/src/internal/OpenApi.ts +45 -12
  924. package/src/internal/Provider.test.ts +1 -1
  925. package/src/internal/Provider.ts +1 -1
  926. package/src/internal/RateLimit.test.ts +21 -3
  927. package/src/internal/RateLimit.ts +12 -1
  928. package/src/internal/Store.test-d.ts +1 -1
  929. package/src/internal/Store.test.ts +151 -8
  930. package/src/internal/Store.ts +76 -9
  931. package/src/internal/Tidx.test.ts +59 -8
  932. package/src/internal/Tidx.ts +86 -14
  933. package/src/internal/Timing.test.ts +77 -0
  934. package/src/internal/Timing.ts +83 -6
  935. package/src/internal/VercelOidc.test.ts +188 -0
  936. package/src/internal/VercelOidc.ts +193 -0
  937. package/src/internal/VerifiedTokens.test.ts +60 -6
  938. package/src/internal/VerifiedTokens.ts +21 -24
  939. package/src/internal/Viem.batch.test.ts +80 -0
  940. package/src/internal/Viem.test.ts +201 -2
  941. package/src/internal/Viem.ts +249 -17
  942. package/src/internal/Webhooks.test.ts +125 -1
  943. package/src/internal/Webhooks.ts +22 -4
  944. package/src/internal/ZoneRpc.ts +50 -0
  945. package/src/internal/exchange/Provider.test.ts +2 -2
  946. package/src/internal/index.test.ts +3 -1
  947. package/src/internal/index.ts +3 -1
  948. package/src/internal/rewards/Audit.ts +231 -0
  949. package/src/internal/rewards/Campaigns.test.ts +1234 -0
  950. package/src/internal/rewards/Campaigns.ts +1205 -0
  951. package/src/internal/rewards/Credits.ts +165 -0
  952. package/src/internal/rewards/Events.local.test.ts +113 -0
  953. package/src/internal/rewards/Events.test.ts +152 -0
  954. package/src/internal/rewards/Events.ts +468 -0
  955. package/src/internal/rewards/Projection.test.ts +681 -0
  956. package/src/internal/rewards/Projection.ts +987 -0
  957. package/src/internal/rewards/Rates.test.ts +171 -0
  958. package/src/internal/rewards/Rates.ts +110 -0
  959. package/src/internal/rewards/Read.test.ts +501 -0
  960. package/src/internal/rewards/Read.ts +476 -0
  961. package/src/internal/rewards/Runner.checkpoint.test.ts +80 -0
  962. package/src/internal/rewards/Runner.states.test.ts +188 -0
  963. package/src/internal/rewards/Runner.test.ts +90 -0
  964. package/src/internal/rewards/Runner.ts +2229 -0
  965. package/src/internal/rewards/Signer.test.ts +79 -0
  966. package/src/internal/rewards/Signer.ts +180 -0
  967. package/src/internal/rewards/index.ts +14 -0
  968. package/src/internal/{funding → routes}/Action.test.ts +63 -14
  969. package/src/internal/{funding → routes}/Action.ts +35 -8
  970. package/src/internal/{funding → routes}/Catalog.test.ts +3 -3
  971. package/src/internal/{funding → routes}/Catalog.ts +39 -39
  972. package/src/internal/{funding → routes}/Chain.test.ts +1 -1
  973. package/src/internal/{funding → routes}/Chain.ts +11 -11
  974. package/src/internal/{funding → routes}/Deposit.test.ts +1 -1
  975. package/src/internal/{funding → routes}/Deposit.ts +93 -45
  976. package/src/internal/{funding → routes}/DepositAddress.test.ts +11 -3
  977. package/src/internal/{funding → routes}/DepositAddress.ts +132 -53
  978. package/src/internal/{funding → routes}/DepositWebhook.test.ts +61 -18
  979. package/src/internal/{funding → routes}/DepositWebhook.ts +9 -8
  980. package/src/internal/routes/Economics.test.ts +42 -0
  981. package/src/internal/routes/Economics.ts +47 -0
  982. package/src/internal/{funding → routes}/Evidence.test.ts +6 -6
  983. package/src/internal/{funding → routes}/Evidence.ts +11 -22
  984. package/src/internal/routes/Observability.test.ts +636 -0
  985. package/src/internal/routes/Observability.ts +668 -0
  986. package/src/internal/{funding → routes}/Provider.test.ts +489 -153
  987. package/src/internal/{funding → routes}/Provider.ts +531 -185
  988. package/src/internal/{funding → routes}/Reconciliation.local.test.ts +84 -12
  989. package/src/internal/{funding → routes}/Reconciliation.test.ts +1213 -279
  990. package/src/internal/{funding → routes}/Reconciliation.ts +501 -203
  991. package/src/internal/routes/Reconciliation.unattributed.test.ts +250 -0
  992. package/src/internal/{funding → routes}/Route.ts +7 -7
  993. package/src/internal/{funding → routes}/SourceObservation.test.ts +13 -14
  994. package/src/internal/{funding → routes}/SourceObservation.ts +18 -22
  995. package/src/internal/{funding → routes}/Subsidy.local.test.ts +7 -7
  996. package/src/internal/routes/Subsidy.test.ts +169 -0
  997. package/src/internal/{funding → routes}/Subsidy.ts +86 -6
  998. package/src/internal/{funding → routes}/Token.test.ts +1 -1
  999. package/src/internal/{funding → routes}/Token.ts +5 -5
  1000. package/src/internal/routes/Transfer.test.ts +1199 -0
  1001. package/src/internal/routes/Transfer.ts +1206 -0
  1002. package/src/internal/routes/TransferReconciliation.test.ts +731 -0
  1003. package/src/internal/routes/TransferReconciliation.ts +527 -0
  1004. package/src/internal/routes/TransferSubsidy.test.ts +172 -0
  1005. package/src/internal/routes/TransferSubsidy.ts +447 -0
  1006. package/src/internal/routes/TransferWebhook.test.ts +128 -0
  1007. package/src/internal/routes/TransferWebhook.ts +67 -0
  1008. package/src/internal/{funding → routes}/index.test.ts +6 -3
  1009. package/src/internal/{funding → routes}/index.ts +3 -0
  1010. package/src/internal/{funding → routes}/providers/across.ts +16 -16
  1011. package/src/internal/{funding → routes}/providers/index.test.ts +157 -44
  1012. package/src/internal/{funding → routes}/providers/relay.test.ts +165 -32
  1013. package/src/internal/{funding → routes}/providers/relay.ts +231 -136
  1014. package/src/internal/{funding → routes}/providers/rhino.ts +16 -16
  1015. package/src/internal/{funding → routes}/providers/squid.ts +17 -17
  1016. package/src/internal/routes/providers/stargate.test.ts +728 -0
  1017. package/src/internal/routes/providers/stargate.ts +1276 -0
  1018. package/src/internal/{funding → routes}/providers/symbiosis.ts +64 -24
  1019. package/src/internal/webhookDestinations/slack.ts +20 -5
  1020. package/src/providers/index.ts +13 -13
  1021. package/src/server.ts +18 -0
  1022. package/dist/apps/funding/Access.d.ts.map +0 -1
  1023. package/dist/apps/funding/Access.js.map +0 -1
  1024. package/dist/apps/funding/App.js.map +0 -1
  1025. package/dist/apps/funding/Inventory.d.ts.map +0 -1
  1026. package/dist/apps/funding/Inventory.js.map +0 -1
  1027. package/dist/apps/funding/ProviderAttempts.d.ts +0 -5
  1028. package/dist/apps/funding/ProviderAttempts.d.ts.map +0 -1
  1029. package/dist/apps/funding/ProviderAttempts.js +0 -24
  1030. package/dist/apps/funding/ProviderAttempts.js.map +0 -1
  1031. package/dist/apps/funding/index.d.ts +0 -2
  1032. package/dist/apps/funding/index.d.ts.map +0 -1
  1033. package/dist/apps/funding/index.js +0 -2
  1034. package/dist/apps/funding/index.js.map +0 -1
  1035. package/dist/apps/funding/routes/chains.d.ts.map +0 -1
  1036. package/dist/apps/funding/routes/chains.js.map +0 -1
  1037. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +0 -1
  1038. package/dist/apps/funding/routes/deposit-addresses.js.map +0 -1
  1039. package/dist/apps/funding/routes/providers.d.ts.map +0 -1
  1040. package/dist/apps/funding/routes/providers.js +0 -57
  1041. package/dist/apps/funding/routes/providers.js.map +0 -1
  1042. package/dist/apps/funding/routes/quotes.d.ts.map +0 -1
  1043. package/dist/apps/funding/routes/quotes.js.map +0 -1
  1044. package/dist/apps/funding/routes/transfers.d.ts.map +0 -1
  1045. package/dist/apps/funding/routes/transfers.js +0 -622
  1046. package/dist/apps/funding/routes/transfers.js.map +0 -1
  1047. package/dist/db/tables/fundingCatalog.d.ts +0 -58
  1048. package/dist/db/tables/fundingCatalog.d.ts.map +0 -1
  1049. package/dist/db/tables/fundingCatalog.js.map +0 -1
  1050. package/dist/db/tables/fundingDepositAddresses.d.ts +0 -192
  1051. package/dist/db/tables/fundingDepositAddresses.d.ts.map +0 -1
  1052. package/dist/db/tables/fundingDepositAddresses.js +0 -235
  1053. package/dist/db/tables/fundingDepositAddresses.js.map +0 -1
  1054. package/dist/db/tables/fundingDepositRequestObservations.d.ts.map +0 -1
  1055. package/dist/db/tables/fundingDepositRequestObservations.js.map +0 -1
  1056. package/dist/db/tables/fundingDeposits.d.ts.map +0 -1
  1057. package/dist/db/tables/fundingDeposits.js +0 -295
  1058. package/dist/db/tables/fundingDeposits.js.map +0 -1
  1059. package/dist/db/tables/fundingIdempotency.d.ts +0 -91
  1060. package/dist/db/tables/fundingIdempotency.d.ts.map +0 -1
  1061. package/dist/db/tables/fundingIdempotency.js +0 -103
  1062. package/dist/db/tables/fundingIdempotency.js.map +0 -1
  1063. package/dist/db/tables/fundingTransferEvents.d.ts.map +0 -1
  1064. package/dist/db/tables/fundingTransferEvents.js.map +0 -1
  1065. package/dist/db/tables/fundingTransferTransactions.d.ts +0 -15
  1066. package/dist/db/tables/fundingTransferTransactions.d.ts.map +0 -1
  1067. package/dist/db/tables/fundingTransferTransactions.js +0 -27
  1068. package/dist/db/tables/fundingTransferTransactions.js.map +0 -1
  1069. package/dist/db/tables/fundingTransfers.d.ts +0 -82
  1070. package/dist/db/tables/fundingTransfers.d.ts.map +0 -1
  1071. package/dist/db/tables/fundingTransfers.js +0 -89
  1072. package/dist/db/tables/fundingTransfers.js.map +0 -1
  1073. package/dist/internal/funding/Action.d.ts.map +0 -1
  1074. package/dist/internal/funding/Action.js.map +0 -1
  1075. package/dist/internal/funding/Catalog.d.ts.map +0 -1
  1076. package/dist/internal/funding/Catalog.js.map +0 -1
  1077. package/dist/internal/funding/Chain.d.ts.map +0 -1
  1078. package/dist/internal/funding/Chain.js.map +0 -1
  1079. package/dist/internal/funding/Deposit.d.ts.map +0 -1
  1080. package/dist/internal/funding/Deposit.js.map +0 -1
  1081. package/dist/internal/funding/DepositAddress.d.ts.map +0 -1
  1082. package/dist/internal/funding/DepositAddress.js.map +0 -1
  1083. package/dist/internal/funding/DepositWebhook.d.ts.map +0 -1
  1084. package/dist/internal/funding/DepositWebhook.js.map +0 -1
  1085. package/dist/internal/funding/Evidence.d.ts.map +0 -1
  1086. package/dist/internal/funding/Evidence.js.map +0 -1
  1087. package/dist/internal/funding/Provider.d.ts.map +0 -1
  1088. package/dist/internal/funding/Provider.js.map +0 -1
  1089. package/dist/internal/funding/Reconciliation.d.ts.map +0 -1
  1090. package/dist/internal/funding/Reconciliation.js.map +0 -1
  1091. package/dist/internal/funding/Route.d.ts +0 -21
  1092. package/dist/internal/funding/Route.d.ts.map +0 -1
  1093. package/dist/internal/funding/Route.js.map +0 -1
  1094. package/dist/internal/funding/SourceObservation.d.ts.map +0 -1
  1095. package/dist/internal/funding/SourceObservation.js.map +0 -1
  1096. package/dist/internal/funding/Subsidy.d.ts.map +0 -1
  1097. package/dist/internal/funding/Subsidy.js.map +0 -1
  1098. package/dist/internal/funding/Token.d.ts.map +0 -1
  1099. package/dist/internal/funding/Token.js.map +0 -1
  1100. package/dist/internal/funding/Transfer.d.ts.map +0 -1
  1101. package/dist/internal/funding/Transfer.js +0 -334
  1102. package/dist/internal/funding/Transfer.js.map +0 -1
  1103. package/dist/internal/funding/index.d.ts.map +0 -1
  1104. package/dist/internal/funding/index.js.map +0 -1
  1105. package/dist/internal/funding/providers/across.d.ts.map +0 -1
  1106. package/dist/internal/funding/providers/across.js.map +0 -1
  1107. package/dist/internal/funding/providers/relay.d.ts.map +0 -1
  1108. package/dist/internal/funding/providers/relay.js.map +0 -1
  1109. package/dist/internal/funding/providers/rhino.d.ts.map +0 -1
  1110. package/dist/internal/funding/providers/rhino.js.map +0 -1
  1111. package/dist/internal/funding/providers/squid.d.ts.map +0 -1
  1112. package/dist/internal/funding/providers/squid.js.map +0 -1
  1113. package/dist/internal/funding/providers/stargate.d.ts +0 -38
  1114. package/dist/internal/funding/providers/stargate.d.ts.map +0 -1
  1115. package/dist/internal/funding/providers/stargate.js +0 -277
  1116. package/dist/internal/funding/providers/stargate.js.map +0 -1
  1117. package/dist/internal/funding/providers/symbiosis.d.ts.map +0 -1
  1118. package/dist/internal/funding/providers/symbiosis.js.map +0 -1
  1119. package/src/apps/funding/App.test.ts +0 -78
  1120. package/src/apps/funding/App.ts +0 -78
  1121. package/src/apps/funding/ProviderAttempts.ts +0 -26
  1122. package/src/apps/funding/index.ts +0 -1
  1123. package/src/apps/funding/routes/transfers.test.ts +0 -1638
  1124. package/src/apps/funding/routes/transfers.ts +0 -721
  1125. package/src/db/tables/fundingCatalog.test.ts +0 -122
  1126. package/src/db/tables/fundingCatalog.ts +0 -163
  1127. package/src/db/tables/fundingDepositAddresses.test.ts +0 -608
  1128. package/src/db/tables/fundingDepositAddresses.ts +0 -443
  1129. package/src/db/tables/fundingDeposits.ts +0 -572
  1130. package/src/db/tables/fundingIdempotency.test.ts +0 -182
  1131. package/src/db/tables/fundingIdempotency.ts +0 -180
  1132. package/src/db/tables/fundingTransferTransactions.test.ts +0 -69
  1133. package/src/db/tables/fundingTransferTransactions.ts +0 -37
  1134. package/src/db/tables/fundingTransfers.test.ts +0 -89
  1135. package/src/db/tables/fundingTransfers.ts +0 -153
  1136. package/src/handlers/internal/multisig.test.ts +0 -818
  1137. package/src/internal/funding/Subsidy.test.ts +0 -75
  1138. package/src/internal/funding/Transfer.test.ts +0 -369
  1139. package/src/internal/funding/Transfer.ts +0 -545
  1140. package/src/internal/funding/providers/stargate.test.ts +0 -163
  1141. package/src/internal/funding/providers/stargate.ts +0 -409
  1142. /package/dist/apps/{funding → routes}/Inventory.d.ts +0 -0
  1143. /package/src/internal/{funding → routes}/Route.test.ts +0 -0
@@ -0,0 +1,1778 @@
1
+ import { erc20Abi, getAddress, isAddress, isAddressEqual, parseAbi, parseEventLogs, } from 'viem';
2
+ import * as RewardAccounts from '../../db/tables/rewardAccounts.js';
3
+ import * as RewardCampaigns from '../../db/tables/rewardCampaigns.js';
4
+ import * as RewardEligibilityAssociations from '../../db/tables/rewardEligibilityAssociations.js';
5
+ import * as RewardRuns from '../../db/tables/rewardRuns.js';
6
+ import * as RewardTransactionAttempts from '../../db/tables/rewardTransactionAttempts.js';
7
+ import * as EarnVaultRecords from '../../db/tables/earnVaults.js';
8
+ import * as Campaigns from './Campaigns.js';
9
+ import * as Events from './Events.js';
10
+ import * as Projection from './Projection.js';
11
+ import * as Rates from './Rates.js';
12
+ import * as Signer from './Signer.js';
13
+ import * as Viem from '../Viem.js';
14
+ const claimDeadline = Number((1n << 40n) - 1n);
15
+ const maximumIntervalsPerRun = 12;
16
+ // Each wave produces at most 64 historical multicalls per RPC round.
17
+ const capitalStateBatchSize = 64;
18
+ // Keep enough headroom below the Worker's 128 MiB memory limit for account projection,
19
+ // the cumulative Merkle tree, and payout construction to coexist in one invocation.
20
+ const maximumRecipients = 10_000;
21
+ // The Earn operator's Tempo gas model budgets 200k per transfer and 250k per
22
+ // push call. Two 60-recipient calls stay below 90% of the signer's 28M cap.
23
+ const payoutBatchSize = 60;
24
+ const payoutCallsPerTransaction = 2;
25
+ const payoutTransactionConcurrency = 16;
26
+ const runLeaseMilliseconds = 2 * 60 * 1_000;
27
+ const factoryAbi = parseAbi([
28
+ 'function predictContributionController(address earnVault,address owner) view returns (address)',
29
+ 'function predictMerkleDistributor(address earnVault,address owner,address treasury,uint40 claimDeadline) view returns (address)',
30
+ ]);
31
+ const vaultAbi = parseAbi([
32
+ 'function earnFees() view returns (address)',
33
+ 'function engine() view returns (address)',
34
+ 'function previewRedeem(uint256 earnShares) view returns (uint256)',
35
+ 'function totalAssets() view returns (uint256)',
36
+ 'function totalEarnShares() view returns (uint256)',
37
+ ]);
38
+ const feesAbi = parseAbi([
39
+ 'function previewAccruedFees() view returns ((uint256 activeAssets,uint256 positiveAccrualAssets,uint256 fixedFeeAssets,uint256 excessFeeAssets,uint256 totalFeeAssets,uint256 totalFeeEarnShares,uint256 preFeeValuePerEarnShare,uint256 postFeeValuePerEarnShare,uint256 targetValuePerEarnShare,uint8 allocationCount,(address account,uint256 feeAssets,uint256 feeEarnShares)[5] allocations) result)',
40
+ ]);
41
+ const controllerAbi = parseAbi([
42
+ 'event Funded(address indexed funder,uint256 requestedAssets,uint256 fundedAssets)',
43
+ ]);
44
+ const distributorAbi = parseAbi([
45
+ 'function cumulativePaid(address recipient) view returns (uint256)',
46
+ 'function merkleRoot() view returns (bytes32)',
47
+ 'function rootTotalEntitlement() view returns (uint256)',
48
+ 'function rootVersion() view returns (uint64)',
49
+ 'function statementHash() view returns (bytes32)',
50
+ 'function totalPaid() view returns (uint256)',
51
+ ]);
52
+ /** Lists due campaigns as compact queue references. */
53
+ export async function due(db, now = Date.now()) {
54
+ const campaigns = [];
55
+ const pageSize = 100;
56
+ for (let offset = 0;; offset += pageSize) {
57
+ const page = await RewardCampaigns.listDue(db, {
58
+ limit: pageSize,
59
+ offset,
60
+ through: Math.floor(now / 1_000),
61
+ });
62
+ campaigns.push(...page);
63
+ if (page.length < pageSize)
64
+ break;
65
+ }
66
+ for (let offset = 0;; offset += pageSize) {
67
+ const page = await RewardCampaigns.listUnprovisioned(db, { limit: pageSize, offset });
68
+ campaigns.push(...page);
69
+ if (page.length < pageSize)
70
+ break;
71
+ }
72
+ return [
73
+ ...new Map(campaigns.map((campaign) => [`${campaign.chainId}:${campaign.vaultAddress}`, campaign])).values(),
74
+ ]
75
+ .filter((campaign) => Number(campaign.deliveredThrough) < Campaigns.finalBoundary(campaign.config) ||
76
+ [campaign.config, campaign.pendingConfig].some((config) => Boolean(config?.targetYield && !campaign.controllerAddress) ||
77
+ Boolean(config?.boostRewards && !campaign.distributorAddress)))
78
+ .map((campaign) => ({
79
+ chainId: campaign.chainId,
80
+ type: 'earn:reward:run',
81
+ vaultAddress: getAddress(campaign.vaultAddress),
82
+ }));
83
+ }
84
+ /** Selects resumable state only when its eligibility snapshot is unchanged. */
85
+ export function resumeCheckpoint(checkpoint, options) {
86
+ return checkpoint?.progress.eligibilityVersion === options.eligibilityVersion &&
87
+ checkpoint.progress.exclusionVersion === options.exclusionVersion
88
+ ? checkpoint
89
+ : undefined;
90
+ }
91
+ /** Keeps the committed campaign cursor ahead of replay-only history. */
92
+ export function reconciledCursor(options) {
93
+ return options.committed ?? options.replayed ?? null;
94
+ }
95
+ /** Restores the target rate selected before a calculation checkpoint. */
96
+ export function checkpointTargetRate(checkpoint, config) {
97
+ const progress = checkpoint?.progress;
98
+ if (progress?.targetRateBps === undefined || !progress.targetRateObservedAt)
99
+ return undefined;
100
+ return {
101
+ annualRateBps: progress.targetRateBps,
102
+ config,
103
+ observedAt: progress.targetRateObservedAt,
104
+ ...(progress.staleRates?.includes('target') ? { stale: true } : {}),
105
+ };
106
+ }
107
+ /** Advances one campaign through its durable, fenced execution phases. */
108
+ export async function run(options) {
109
+ const campaign = await RewardCampaigns.get(options.db, options.message);
110
+ if (!campaign || campaign.paused)
111
+ return { status: 'idle' };
112
+ if (campaign.chainId !== Viem.chainId.mainnet)
113
+ throw new Error('Reward execution is currently supported only on Tempo mainnet.');
114
+ const { bindings, signer } = await (async () => {
115
+ try {
116
+ const signer = await Signer.health(options.signerFetch);
117
+ const bindings = await provision(options, campaign, signer.signer);
118
+ return { bindings, signer };
119
+ }
120
+ catch (cause) {
121
+ await RewardCampaigns.setProvisioningError(options.db, {
122
+ chainId: campaign.chainId,
123
+ config: provisioningPlan(campaign).configMatch,
124
+ error: cause instanceof Error ? cause.message : 'Reward provisioning failed.',
125
+ vaultAddress: getAddress(campaign.vaultAddress),
126
+ });
127
+ throw cause;
128
+ }
129
+ })();
130
+ const start = Number(campaign.deliveredThrough);
131
+ const scheduleEnd = Campaigns.finalBoundary(campaign.config);
132
+ const intervalSeconds = Campaigns.intervalSeconds(campaign.config);
133
+ const clock = Math.floor(options.now() / 1_000);
134
+ const completeIntervals = Math.max(0, Math.floor((Math.min(clock, scheduleEnd) - start) / intervalSeconds));
135
+ let end = start + Math.min(completeIntervals, maximumIntervalsPerRun) * intervalSeconds;
136
+ const nextScheduleStart = [
137
+ campaign.config.targetYield?.startTimestamp,
138
+ campaign.config.boostRewards?.startTimestamp,
139
+ ]
140
+ .filter((timestamp) => timestamp !== undefined && timestamp > start)
141
+ .sort((left, right) => left - right)[0];
142
+ if (nextScheduleStart !== undefined)
143
+ end = Math.min(end, nextScheduleStart);
144
+ if (campaign.pendingEffectiveAt !== null)
145
+ end = Math.min(end, Number(campaign.pendingEffectiveAt));
146
+ if (end <= start)
147
+ return { status: 'idle' };
148
+ const ensured = await RewardRuns.ensure(options.db, {
149
+ chainId: campaign.chainId,
150
+ config: campaign.config,
151
+ endsAt: end,
152
+ startsAfter: start,
153
+ vaultAddress: getAddress(campaign.vaultAddress),
154
+ });
155
+ const leased = await RewardRuns.acquire(options.db, {
156
+ id: ensured.id,
157
+ leaseMilliseconds: runLeaseMilliseconds,
158
+ });
159
+ if (!leased)
160
+ return { runId: ensured.id, status: 'busy' };
161
+ const heartbeat = maintainLease(options.db, leased, options.now);
162
+ const executionOptions = { ...options, assertLease: () => heartbeat.assert() };
163
+ try {
164
+ await heartbeat.ready();
165
+ if (leased.phase === 'paying' && leased.statement && leased.evidence) {
166
+ await deliver(executionOptions, campaign, leased, bindings, leased.statement, restoreCalculation(leased.evidence), signer.signer);
167
+ const result = {
168
+ notification: await notificationSummary(options.db, campaign, leased.id),
169
+ runId: leased.id,
170
+ staleRates: leased.evidence.staleRates ?? [],
171
+ status: 'delivered',
172
+ };
173
+ const leaseFailure = await heartbeat.stop();
174
+ if (leaseFailure !== undefined)
175
+ throw leaseFailure;
176
+ return result;
177
+ }
178
+ if (!['indexing', 'calculating', 'targetYield', 'statement'].includes(leased.phase))
179
+ throw new Error(`Unsupported reward recovery phase ${leased.phase}.`);
180
+ const checkpoint = await RewardRuns.getCheckpoint(options.db, { id: leased.id });
181
+ const calculated = leased.evidence && !checkpoint
182
+ ? restoreCalculation(leased.evidence)
183
+ : await calculate(executionOptions, campaign, leased, bindings);
184
+ const targetAttempt = leased.phase === 'statement'
185
+ ? undefined
186
+ : await settleTargetYield(executionOptions, campaign, leased, bindings, calculated, signer.signer);
187
+ const settlement = await settleBoost(executionOptions, campaign, leased, bindings, calculated, signer.signer);
188
+ // The leased record and initial calculation predate settlement, so delivery consumes the evidence returned by settlement.
189
+ await deliver(executionOptions, campaign, leased, bindings, settlement?.statement, settlement ? { ...calculated, evidence: settlement.evidence } : calculated, signer.signer);
190
+ const result = {
191
+ notification: await notificationSummary(options.db, campaign, leased.id),
192
+ runId: leased.id,
193
+ staleRates: calculated.evidence.staleRates ?? [],
194
+ status: 'delivered',
195
+ targetAttempt,
196
+ };
197
+ const leaseFailure = await heartbeat.stop();
198
+ if (leaseFailure !== undefined)
199
+ throw leaseFailure;
200
+ return result;
201
+ }
202
+ catch (cause) {
203
+ await heartbeat.stop();
204
+ await RewardRuns.releaseWithError(options.db, {
205
+ error: cause instanceof Error ? cause.message : 'Reward run failed.',
206
+ fence: leased.fence,
207
+ id: leased.id,
208
+ });
209
+ throw cause;
210
+ }
211
+ }
212
+ function provisioningPlan(campaign) {
213
+ const pending = campaign.pendingConfig;
214
+ const needsPendingController = Boolean(pending?.targetYield && !campaign.controllerAddress);
215
+ const needsPendingDistributor = Boolean(pending?.boostRewards && !campaign.distributorAddress);
216
+ return {
217
+ boostRewards: campaign.config.boostRewards ?? pending?.boostRewards,
218
+ configMatch: pending && (needsPendingController || needsPendingDistributor) ? pending : campaign.config,
219
+ targetYield: campaign.config.targetYield ?? pending?.targetYield,
220
+ };
221
+ }
222
+ async function provision(options, campaign, signer) {
223
+ const plan = provisioningPlan(campaign);
224
+ if (campaign.signerAddress && !isAddressEqual(campaign.signerAddress, signer))
225
+ throw new Error('Reward signer does not match the campaign signer.');
226
+ const client = options.getClient(campaign.chainId);
227
+ const vault = getAddress(campaign.vaultAddress);
228
+ const treasury = plan.boostRewards?.treasury;
229
+ const [predictedController, predictedDistributor] = await Promise.all([
230
+ plan.targetYield
231
+ ? client.readContract({
232
+ abi: factoryAbi,
233
+ address: options.factory,
234
+ args: [vault, signer],
235
+ functionName: 'predictContributionController',
236
+ })
237
+ : undefined,
238
+ plan.boostRewards && treasury
239
+ ? client.readContract({
240
+ abi: factoryAbi,
241
+ address: options.factory,
242
+ args: [vault, signer, treasury, claimDeadline],
243
+ functionName: 'predictMerkleDistributor',
244
+ })
245
+ : undefined,
246
+ ]);
247
+ if (campaign.controllerAddress &&
248
+ predictedController &&
249
+ !isAddressEqual(campaign.controllerAddress, predictedController))
250
+ throw new Error('Stored contribution controller does not match the campaign signer.');
251
+ if (campaign.distributorAddress &&
252
+ predictedDistributor &&
253
+ !isAddressEqual(campaign.distributorAddress, predictedDistributor))
254
+ throw new Error('Stored Merkle distributor does not match the campaign signer.');
255
+ const controller = plan.targetYield
256
+ ? getAddress(campaign.controllerAddress ?? predictedController)
257
+ : undefined;
258
+ const distributor = plan.boostRewards
259
+ ? getAddress(campaign.distributorAddress ?? predictedDistributor)
260
+ : undefined;
261
+ const code = await Promise.all([controller, distributor]
262
+ .filter((address) => Boolean(address))
263
+ .map((address) => client.getCode({ address })));
264
+ if (code.some((runtime) => !runtime)) {
265
+ const intent = {
266
+ boostRewards: Boolean(plan.boostRewards),
267
+ domain: domain(options, campaign, {
268
+ ...(plan.boostRewards ? { boostRewards: plan.boostRewards } : {}),
269
+ ...(plan.targetYield ? { targetYield: plan.targetYield } : {}),
270
+ }),
271
+ operation: 'deploy',
272
+ targetYield: Boolean(plan.targetYield),
273
+ treasury: treasury ?? '0x0000000000000000000000000000000000000000',
274
+ };
275
+ await execute(options, campaign, undefined, signer, intent);
276
+ }
277
+ for (const address of [controller, distributor])
278
+ if (address && !(await client.getCode({ address })))
279
+ throw new Error(`Reward periphery was not deployed at ${address}.`);
280
+ // A failed first deployment must not permanently bind a misconfigured signer.
281
+ const bound = await RewardCampaigns.bindSigner(options.db, {
282
+ chainId: campaign.chainId,
283
+ signerAddress: signer,
284
+ vaultAddress: vault,
285
+ });
286
+ if (!bound)
287
+ throw new Error('Reward signer does not match the campaign signer.');
288
+ const stored = await RewardCampaigns.setBindings(options.db, {
289
+ chainId: campaign.chainId,
290
+ config: plan.configMatch,
291
+ ...(controller ? { controllerAddress: controller } : {}),
292
+ ...(distributor ? { distributorAddress: distributor } : {}),
293
+ error: null,
294
+ signerAddress: signer,
295
+ vaultAddress: vault,
296
+ });
297
+ if (!stored)
298
+ throw new Error('Reward campaign changed during periphery provisioning.');
299
+ return {
300
+ ...(controller ? { controller } : {}),
301
+ ...(distributor ? { distributor } : {}),
302
+ };
303
+ }
304
+ async function calculate(options, campaign, runRecord, bindings) {
305
+ await requireTransition(options.db, runRecord, 'calculating', {});
306
+ const client = options.getClient(campaign.chainId);
307
+ const tidx = options.getTidx(campaign.chainId);
308
+ const startsAfter = Number(runRecord.startsAfter);
309
+ const endsAt = Number(runRecord.endsAt);
310
+ const intervalSeconds = Campaigns.intervalSeconds(campaign.config);
311
+ const openingBoundary = await Events.boundary(tidx, startsAfter);
312
+ const closingBoundary = await Events.boundary(tidx, endsAt);
313
+ const boost = campaign.config.boostRewards;
314
+ const boostTracks = Boolean(boost && Campaigns.overlapsCompleteIntervals(boost, { endsAt, startsAfter }));
315
+ const storedCheckpoint = await RewardRuns.getCheckpoint(options.db, { id: runRecord.id });
316
+ const eligible = boostTracks ? await allEligible(options.db, campaign) : [];
317
+ const eligibilityCheckpoint = eligible.at(-1)?.registrationOrder ?? '0';
318
+ const eligibilityVersion = Campaigns.eligibilityVersion(eligible);
319
+ const excluded = boostTracks ? await exclusions(options, campaign, bindings) : [];
320
+ const exclusionVersion = Campaigns.exclusionVersion(excluded);
321
+ const saved = resumeCheckpoint(storedCheckpoint, { eligibilityVersion, exclusionVersion });
322
+ const stored = await RewardAccounts.list(options.db, campaign);
323
+ let accounts = stored.map(Projection.fromRecord);
324
+ let startingCursor = campaign.eventCursor;
325
+ if (boost && boostTracks) {
326
+ const excludedSet = new Set(excluded.map((address) => address.toLowerCase()));
327
+ const registrations = eligible
328
+ .filter((entry) => {
329
+ const address = entry.walletAddress.toLowerCase();
330
+ return !excludedSet.has(address);
331
+ })
332
+ .map((entry) => ({
333
+ recipient: entry.walletAddress,
334
+ registeredAt: entry.latestRegisteredAt,
335
+ registrationOrder: BigInt(entry.registrationOrder),
336
+ }));
337
+ const accountsByRecipient = new Map(accounts.map((account) => [account.recipient.toLowerCase(), account]));
338
+ const reconcile = registrations.some((entry) => {
339
+ const account = accountsByRecipient.get(entry.recipient.toLowerCase());
340
+ return account?.eligibilityRegisteredAt !== entry.registeredAt;
341
+ });
342
+ const replayRegistrations = registrations.filter((entry) => {
343
+ const account = accountsByRecipient.get(entry.recipient.toLowerCase());
344
+ return (account?.eligibilityRegisteredAt !== entry.registeredAt &&
345
+ (!account ||
346
+ (account.allocatedPrincipalAssets === 0n &&
347
+ account.lots.length === 0 &&
348
+ account.qualifiedEarnShares === 0n)));
349
+ });
350
+ if (reconcile && saved?.stage !== 'calculate') {
351
+ const resume = saved?.stage === 'reconcile' && saved.projection.pass ? saved : undefined;
352
+ let cursor = resume?.projection.replayedThrough;
353
+ const principalAllocationOrder = stored.length === 0 && Number(campaign.deliveredThrough) === boost.startTimestamp
354
+ ? 'deposit'
355
+ : 'registration';
356
+ accounts = [
357
+ ...(await Projection.reconcilePages({
358
+ accounts,
359
+ ...(resume
360
+ ? {
361
+ checkpoint: {
362
+ accounts: resume.projection.accounts,
363
+ ...(resume.projection.allocationRecipient
364
+ ? { allocationRecipient: resume.projection.allocationRecipient }
365
+ : {}),
366
+ ...(resume.projection.consumedEarnShares
367
+ ? { consumedEarnShares: resume.projection.consumedEarnShares }
368
+ : {}),
369
+ depositedEarnShares: resume.projection.depositedEarnShares ?? {},
370
+ ...(resume.cursor ? { cursor: resume.cursor } : {}),
371
+ pass: resume.projection.pass,
372
+ ...(resume.projection.replayedThrough
373
+ ? { replayedThrough: resume.projection.replayedThrough }
374
+ : {}),
375
+ },
376
+ }
377
+ : {}),
378
+ checkpointState: async (projection) => {
379
+ cursor = projection.replayedThrough;
380
+ const persisted = await RewardRuns.writeCheckpoint(options.db, {
381
+ evidence: {
382
+ ...(projection.cursor ? { cursor: projection.cursor } : {}),
383
+ kind: 'checkpoint',
384
+ progress: { eligibilityCheckpoint, eligibilityVersion, exclusionVersion },
385
+ projection,
386
+ stage: 'reconcile',
387
+ },
388
+ fence: runRecord.fence,
389
+ id: runRecord.id,
390
+ });
391
+ if (!persisted)
392
+ throw new Error('Reward run lease was lost.');
393
+ },
394
+ eligible: registrations,
395
+ excluded,
396
+ pages: (pass, after) => pass === 'survival' || principalAllocationOrder === 'deposit'
397
+ ? reconciliationEventPages(Events.accountEventPages(tidx, {
398
+ ...(after ? { after } : {}),
399
+ accounts: replayRegistrations.map((entry) => entry.recipient),
400
+ earnShare: campaign.earnShareAddress,
401
+ earnVault: campaign.vaultAddress,
402
+ throughBlock: openingBoundary.blockNumber,
403
+ }))
404
+ : registrationDepositPages(tidx, {
405
+ ...(after ? { after } : {}),
406
+ ...(resume?.projection.allocationRecipient
407
+ ? { afterRecipient: resume.projection.allocationRecipient }
408
+ : {}),
409
+ accounts: replayRegistrations,
410
+ earnVault: campaign.vaultAddress,
411
+ throughBlock: openingBoundary.blockNumber,
412
+ }),
413
+ perUserPrincipalCapAssets: BigInt(boost.perUserPrincipalCapAssets),
414
+ // Initial allocation follows deposits; later registrations share the remaining cap by registration order.
415
+ principalAllocationOrder,
416
+ totalPrincipalCapAssets: BigInt(boost.totalPrincipalCapAssets),
417
+ })).accounts,
418
+ ];
419
+ startingCursor = reconciledCursor({ committed: startingCursor, replayed: cursor });
420
+ }
421
+ }
422
+ const targetConfig = campaign.config.targetYield;
423
+ const targetActive = Boolean(targetConfig && Campaigns.overlapsCompleteIntervals(targetConfig, { endsAt, startsAfter }));
424
+ if (saved?.stage === 'calculate') {
425
+ accounts = saved.projection.accounts.map(Projection.fromSnapshot);
426
+ startingCursor = saved.cursor ?? startingCursor;
427
+ }
428
+ let eventCursor = boost && accounts.length > 0
429
+ ? startingCursor
430
+ : {
431
+ blockNumber: openingBoundary.blockNumber,
432
+ logIndex: Number.MAX_SAFE_INTEGER,
433
+ transactionIndex: Number.MAX_SAFE_INTEGER,
434
+ };
435
+ const capitalChanges = targetActive
436
+ ? await Events.capitalChanges(tidx, {
437
+ afterBlock: openingBoundary.blockNumber,
438
+ earnShare: campaign.earnShareAddress,
439
+ throughBlock: closingBoundary.blockNumber,
440
+ })
441
+ : [];
442
+ const boostAccrues = Boolean(boost &&
443
+ boost.enabled !== false &&
444
+ Campaigns.overlapsCompleteIntervals(boost, { endsAt, startsAfter }));
445
+ // Carry external target observations and exact funding remainders through inactive intervals
446
+ // so a later schedule resumption reads the latest durable evidence.
447
+ const previous = await RewardRuns.latestDelivered(options.db, campaign);
448
+ const target = targetActive
449
+ ? (checkpointTargetRate(saved, targetConfig) ??
450
+ (await targetRate(options, campaign, runRecord)))
451
+ : undefined;
452
+ const targetRateProgress = target
453
+ ? {
454
+ ...(target.stale ? { staleRates: ['target'] } : {}),
455
+ targetRateBps: target.annualRateBps,
456
+ targetRateObservedAt: target.observedAt,
457
+ }
458
+ : {};
459
+ const contributions = target || boostAccrues
460
+ ? await Events.contributions(tidx, {
461
+ afterBlock: openingBoundary.blockNumber,
462
+ earnVault: campaign.vaultAddress,
463
+ throughBlock: closingBoundary.blockNumber,
464
+ })
465
+ : [];
466
+ let latestBoostRate = saved?.progress.boostRateBps ?? 0;
467
+ let latestOrganicRate = saved?.progress.organicRateBps !== undefined && saved.progress.organicRateObservedAt
468
+ ? {
469
+ observedAt: saved.progress.organicRateObservedAt,
470
+ rate: saved.progress.organicRateBps,
471
+ }
472
+ : undefined;
473
+ const intervals = [
474
+ ...(saved?.progress.intervals ?? []),
475
+ ];
476
+ const targetAssets = target
477
+ ? (saved?.progress.targetFundingAssets?.map(BigInt) ?? target.config.funding.map(() => 0n))
478
+ : [];
479
+ const carryTargetRemainders = Boolean(targetConfig && sameTargetFunding(previous?.config.targetYield?.funding, targetConfig.funding));
480
+ const targetRemainders = targetConfig
481
+ ? (saved?.progress.targetFundingRemainders?.map(BigInt) ??
482
+ targetConfig.funding.map((_, index) => BigInt(carryTargetRemainders ? (previous?.evidence?.targetFundingRemainders?.[index] ?? 0) : 0)))
483
+ : [];
484
+ let projectionCheckpoint = saved?.stage === 'calculate' ? saved : undefined;
485
+ for (let end = startsAfter + (intervals.length + 1) * intervalSeconds; end <= endsAt; end += intervalSeconds) {
486
+ const start = end - intervalSeconds;
487
+ const intervalOpening = start === startsAfter ? openingBoundary : await Events.boundary(tidx, start);
488
+ const boundary = end === endsAt ? closingBoundary : await Events.boundary(tidx, end);
489
+ const sharePrice = await client.readContract({
490
+ abi: vaultAbi,
491
+ address: campaign.vaultAddress,
492
+ args: [10n ** 18n],
493
+ blockNumber: BigInt(intervalOpening.blockNumber),
494
+ functionName: 'previewRedeem',
495
+ });
496
+ const closingSharePrice = await client.readContract({
497
+ abi: vaultAbi,
498
+ address: campaign.vaultAddress,
499
+ args: [10n ** 18n],
500
+ blockNumber: BigInt(boundary.blockNumber),
501
+ functionName: 'previewRedeem',
502
+ });
503
+ const targetIntervalActive = Boolean(target && end > target.config.startTimestamp && end <= target.config.endTimestamp);
504
+ const boostActive = Boolean(boost && boost.enabled !== false && end > boost.startTimestamp && end <= boost.endTimestamp);
505
+ const intervalContributions = contributions
506
+ .filter((entry) => entry.timestamp >= start && entry.timestamp < end)
507
+ .map((entry) => ({ assets: entry.assets, earnShareSupply: entry.earnShareSupply }));
508
+ const growth = targetIntervalActive || boostActive
509
+ ? await (async () => {
510
+ const [totalAssets, openingEarnShareSupply] = await Promise.all([
511
+ client.readContract({
512
+ abi: vaultAbi,
513
+ address: campaign.vaultAddress,
514
+ blockNumber: BigInt(intervalOpening.blockNumber),
515
+ functionName: 'totalAssets',
516
+ }),
517
+ feeInclusiveEarnShareSupply(client, campaign.vaultAddress, BigInt(intervalOpening.blockNumber)),
518
+ ]);
519
+ const assets = Campaigns.organicGrowth({
520
+ closingValuePerEarnShare: closingSharePrice,
521
+ contributions: intervalContributions,
522
+ openingAssets: totalAssets,
523
+ openingEarnShareSupply,
524
+ openingValuePerEarnShare: sharePrice,
525
+ });
526
+ return {
527
+ annualRateBps: Campaigns.annualRateBps({
528
+ elapsedSeconds: intervalSeconds,
529
+ growthAssets: assets,
530
+ principalAssets: totalAssets,
531
+ }),
532
+ opening: {
533
+ openingAssets: totalAssets,
534
+ openingEarnShareSupply,
535
+ openingValuePerEarnShare: sharePrice,
536
+ },
537
+ };
538
+ })()
539
+ : undefined;
540
+ if (boostActive && growth)
541
+ latestOrganicRate = {
542
+ observedAt: new Date(end * 1_000).toISOString(),
543
+ rate: growth.annualRateBps,
544
+ };
545
+ const intervalBoostRate = boost && boostActive
546
+ ? Campaigns.rewardRates({
547
+ boostTargetRateBps: boost.targetAnnualRateBps,
548
+ organicRateBps: growth?.annualRateBps ?? 0,
549
+ ...(targetIntervalActive ? { targetRateBps: target.annualRateBps } : {}),
550
+ }).boostRateBps
551
+ : 0;
552
+ if (boostActive)
553
+ latestBoostRate = intervalBoostRate;
554
+ const resume = projectionCheckpoint;
555
+ const pages = boost && accounts.length > 0
556
+ ? Events.accountEventPages(tidx, {
557
+ ...(eventCursor ? { after: eventCursor } : {}),
558
+ accounts: accounts.map((account) => account.recipient),
559
+ earnShare: campaign.earnShareAddress,
560
+ earnVault: campaign.vaultAddress,
561
+ throughBlock: boundary.blockNumber,
562
+ })
563
+ : emptyEventPages();
564
+ const result = boost
565
+ ? await Projection.calculatePages({
566
+ accounts,
567
+ annualRateBps: intervalBoostRate,
568
+ assetPerEarnShareWad: sharePrice,
569
+ ...(resume
570
+ ? {
571
+ checkpoint: {
572
+ accounts: resume.projection.accounts,
573
+ accruedThrough: resume.projection.accruedThrough ?? {},
574
+ weightedEarnShareSeconds: resume.projection.weightedEarnShareSeconds ?? {},
575
+ },
576
+ }
577
+ : {}),
578
+ checkpointState: async (projection, cursor) => {
579
+ eventCursor = cursor;
580
+ const persisted = await RewardRuns.writeCheckpoint(options.db, {
581
+ evidence: {
582
+ cursor,
583
+ kind: 'checkpoint',
584
+ progress: {
585
+ boostRateBps: latestBoostRate,
586
+ eligibilityCheckpoint,
587
+ eligibilityVersion,
588
+ exclusionVersion,
589
+ intervals,
590
+ ...(latestOrganicRate
591
+ ? {
592
+ organicRateBps: latestOrganicRate.rate,
593
+ organicRateObservedAt: latestOrganicRate.observedAt,
594
+ }
595
+ : {}),
596
+ ...targetRateProgress,
597
+ targetFundingAssets: targetAssets.map(String),
598
+ targetFundingRemainders: targetRemainders.map(String),
599
+ },
600
+ projection,
601
+ stage: 'calculate',
602
+ },
603
+ fence: runRecord.fence,
604
+ id: runRecord.id,
605
+ });
606
+ if (!persisted)
607
+ throw new Error('Reward run lease was lost.');
608
+ },
609
+ endsAt: end,
610
+ excluded,
611
+ pages,
612
+ perUserPrincipalCapAssets: BigInt(boost.perUserPrincipalCapAssets),
613
+ startsAt: start,
614
+ totalPrincipalCapAssets: BigInt(boost.totalPrincipalCapAssets),
615
+ })
616
+ : { accounts, rewards: new Map() };
617
+ projectionCheckpoint = undefined;
618
+ accounts = [...result.accounts];
619
+ intervals.push({
620
+ assetPerEarnShareWad: sharePrice.toString(),
621
+ assetRewards: Object.fromEntries([...result.rewards].map(([recipient, amount]) => [
622
+ recipient.toLowerCase(),
623
+ amount.toString(),
624
+ ])),
625
+ blockNumber: boundary.blockNumber,
626
+ ...(boost ? { boostRateBps: intervalBoostRate } : {}),
627
+ endsAt: end,
628
+ ...(growth ? { organicRateBps: growth.annualRateBps } : {}),
629
+ startsAt: start,
630
+ });
631
+ if (target && targetIntervalActive) {
632
+ if (!growth)
633
+ throw new Error('Target-yield interval lacks organic growth evidence.');
634
+ const periods = [];
635
+ let opening = {
636
+ ...growth.opening,
637
+ blockNumber: intervalOpening.blockNumber,
638
+ timestamp: start,
639
+ };
640
+ // Read post-change principal so a boundary deposit earns only until its redemption block.
641
+ const states = await capitalStates(client, {
642
+ boundaries: capitalChanges.filter((entry) => entry.timestamp >= start && entry.timestamp < end),
643
+ vaultAddress: campaign.vaultAddress,
644
+ });
645
+ for (const closing of [
646
+ ...states,
647
+ {
648
+ ...growth.opening,
649
+ blockNumber: boundary.blockNumber,
650
+ openingValuePerEarnShare: closingSharePrice,
651
+ timestamp: end,
652
+ },
653
+ ]) {
654
+ periods.push({
655
+ closingValuePerEarnShare: closing.openingValuePerEarnShare,
656
+ contributions: contributions.filter((entry) => entry.cursor.blockNumber > opening.blockNumber &&
657
+ entry.cursor.blockNumber <= closing.blockNumber),
658
+ elapsedSeconds: closing.timestamp - opening.timestamp,
659
+ openingAssets: opening.openingAssets,
660
+ openingEarnShareSupply: opening.openingEarnShareSupply,
661
+ openingValuePerEarnShare: opening.openingValuePerEarnShare,
662
+ });
663
+ opening = closing;
664
+ }
665
+ const funding = Campaigns.targetFunding({
666
+ annualRateBps: target.annualRateBps,
667
+ funding: target.config.funding,
668
+ periods,
669
+ remainders: targetRemainders,
670
+ });
671
+ funding.assets.forEach((amount, index) => {
672
+ targetAssets[index] = (targetAssets[index] ?? 0n) + amount;
673
+ targetRemainders[index] = funding.remainders[index];
674
+ });
675
+ }
676
+ const persisted = await RewardRuns.writeCheckpoint(options.db, {
677
+ evidence: {
678
+ ...(eventCursor ? { cursor: eventCursor } : {}),
679
+ kind: 'checkpoint',
680
+ progress: {
681
+ boostRateBps: latestBoostRate,
682
+ eligibilityCheckpoint,
683
+ eligibilityVersion,
684
+ exclusionVersion,
685
+ intervals,
686
+ ...(latestOrganicRate
687
+ ? {
688
+ organicRateBps: latestOrganicRate.rate,
689
+ organicRateObservedAt: latestOrganicRate.observedAt,
690
+ }
691
+ : {}),
692
+ ...targetRateProgress,
693
+ targetFundingAssets: targetAssets.map(String),
694
+ targetFundingRemainders: targetRemainders.map(String),
695
+ },
696
+ projection: { accounts: accounts.map(Projection.snapshot) },
697
+ stage: 'calculate',
698
+ },
699
+ fence: runRecord.fence,
700
+ id: runRecord.id,
701
+ });
702
+ if (!persisted)
703
+ throw new Error('Reward run lease was lost.');
704
+ }
705
+ const priorTarget = (() => {
706
+ if (!targetConfig ||
707
+ target ||
708
+ previous?.evidence?.targetRateBps === undefined ||
709
+ !previous.evidence.targetRateObservedAt ||
710
+ !sameRateSource(previous.config.targetYield?.annualRate, targetConfig.annualRate))
711
+ return undefined;
712
+ return {
713
+ observedAt: previous.evidence.targetRateObservedAt,
714
+ rate: previous.evidence.targetRateBps,
715
+ };
716
+ })();
717
+ const targetEvidence = (() => {
718
+ if (target)
719
+ return {
720
+ appliedTargetRateBps: target.annualRateBps,
721
+ targetFundingAssets: targetAssets.map(String),
722
+ targetFundingRemainders: targetRemainders.map(String),
723
+ targetPrincipalMethod: 'time-weighted:v1',
724
+ targetRateBps: target.annualRateBps,
725
+ targetRateObservedAt: target.observedAt,
726
+ };
727
+ if (!targetConfig)
728
+ return {};
729
+ return {
730
+ targetFundingRemainders: targetRemainders.map(String),
731
+ ...(priorTarget
732
+ ? {
733
+ targetRateBps: priorTarget.rate,
734
+ targetRateObservedAt: priorTarget.observedAt,
735
+ }
736
+ : {}),
737
+ };
738
+ })();
739
+ const evidence = {
740
+ ...(boost ? { boostRateBps: latestBoostRate } : {}),
741
+ closingAccounts: accounts.map(Projection.snapshot),
742
+ eligibilityCheckpoint,
743
+ eligibilityVersion,
744
+ exclusionVersion,
745
+ ...(eventCursor ? { eventCursor } : {}),
746
+ intervals,
747
+ ...(target?.stale
748
+ ? {
749
+ staleRates: ['target'],
750
+ }
751
+ : {}),
752
+ ...(latestOrganicRate
753
+ ? {
754
+ organicRateBps: latestOrganicRate.rate,
755
+ organicRateObservedAt: latestOrganicRate.observedAt,
756
+ }
757
+ : {}),
758
+ stateChecksum: Projection.checksum(accounts),
759
+ ...targetEvidence,
760
+ };
761
+ await requireTransition(options.db, runRecord, 'targetYield', { evidence });
762
+ return { accounts, ...(eventCursor ? { closingCursor: eventCursor } : {}), evidence };
763
+ }
764
+ async function settleTargetYield(options, campaign, runRecord, bindings, calculation, signer) {
765
+ const target = campaign.config.targetYield;
766
+ if (!target || !bindings.controller)
767
+ return undefined;
768
+ const requestedAssets = Campaigns.targetFundingAssets(calculation.evidence);
769
+ if (requestedAssets.every((amount) => amount === 0n))
770
+ return undefined;
771
+ const active = target.funding.flatMap((leg, index) => {
772
+ const amount = requestedAssets[index] ?? 0n;
773
+ return amount > 0n ? [{ amount, wallet: leg.wallet }] : [];
774
+ });
775
+ const previous = await RewardTransactionAttempts.latestRecoverable(options.db, {
776
+ operation: 'targetYield',
777
+ runId: runRecord.id,
778
+ });
779
+ const intent = previous?.signedBytes
780
+ ? Signer.schema.Request.parse({
781
+ attemptId: previous.id,
782
+ id: previous.intentId,
783
+ intent: previous.intent.payload,
784
+ }).intent
785
+ : {
786
+ controller: bindings.controller,
787
+ domain: domain(options, campaign),
788
+ funders: active.map((leg) => leg.wallet),
789
+ maxEarnShareSupply: (await feeInclusiveEarnShareSupply(options.getClient(campaign.chainId), campaign.vaultAddress)).toString(),
790
+ operation: 'targetYield',
791
+ requestedAssets: active.map((leg) => leg.amount.toString()),
792
+ };
793
+ if (intent.operation !== 'targetYield')
794
+ throw new Error('Stored target-yield attempt contains another operation.');
795
+ const attempt = await execute(options, campaign, runRecord.id, signer, intent);
796
+ if (!attempt.transactionHash)
797
+ throw new Error('Target-yield transaction lacks a hash.');
798
+ const receipt = await options
799
+ .getClient(campaign.chainId)
800
+ .getTransactionReceipt({ hash: attempt.transactionHash });
801
+ const funded = parseEventLogs({
802
+ abi: controllerAbi,
803
+ eventName: 'Funded',
804
+ logs: receipt.logs,
805
+ strict: true,
806
+ }).filter((event) => isAddressEqual(event.address, bindings.controller));
807
+ const exact = funded.length === active.length &&
808
+ funded.every((event, index) => {
809
+ const expected = active[index];
810
+ return (isAddressEqual(event.args.funder, expected.wallet) &&
811
+ event.args.requestedAssets === expected.amount &&
812
+ event.args.fundedAssets === expected.amount);
813
+ });
814
+ if (!exact) {
815
+ const retryableZeroFunding = active.length === 1 &&
816
+ funded.length === 1 &&
817
+ isAddressEqual(funded[0].args.funder, active[0].wallet) &&
818
+ funded[0].args.requestedAssets === active[0].amount &&
819
+ funded[0].args.fundedAssets === 0n;
820
+ if (retryableZeroFunding) {
821
+ const ineffective = await RewardTransactionAttempts.markIneffective(options.db, attempt.id);
822
+ if (!ineffective)
823
+ throw new Error('Confirmed zero target-yield funding could not be marked for retry.');
824
+ throw new Error('Target-yield funding settled zero assets and will be retried.');
825
+ }
826
+ throw new Error('Target-yield funding did not settle every requested asset exactly.');
827
+ }
828
+ return attempt.transactionHash ?? undefined;
829
+ }
830
+ /** Reads historical capital states in bounded waves, preserving order and rejecting incomplete evidence. */
831
+ export async function capitalStates(client, options) {
832
+ const states = [];
833
+ for (let offset = 0; offset < options.boundaries.length; offset += capitalStateBatchSize) {
834
+ const results = await Promise.allSettled(options.boundaries.slice(offset, offset + capitalStateBatchSize).map(async (boundary) => {
835
+ const blockNumber = BigInt(boundary.blockNumber);
836
+ const reads = await Promise.allSettled([
837
+ client.readContract({
838
+ abi: vaultAbi,
839
+ address: options.vaultAddress,
840
+ blockNumber,
841
+ functionName: 'totalAssets',
842
+ }),
843
+ feeInclusiveEarnShareSupply(client, options.vaultAddress, blockNumber),
844
+ client.readContract({
845
+ abi: vaultAbi,
846
+ address: options.vaultAddress,
847
+ args: [10n ** 18n],
848
+ blockNumber,
849
+ functionName: 'previewRedeem',
850
+ }),
851
+ ]);
852
+ const [openingAssets, openingEarnShareSupply, openingValuePerEarnShare] = reads.map((result) => {
853
+ if (result.status === 'rejected')
854
+ throw result.reason;
855
+ return result.value;
856
+ });
857
+ return {
858
+ ...boundary,
859
+ openingAssets: openingAssets,
860
+ openingEarnShareSupply: openingEarnShareSupply,
861
+ openingValuePerEarnShare: openingValuePerEarnShare,
862
+ };
863
+ }));
864
+ for (const result of results) {
865
+ if (result.status === 'rejected')
866
+ throw result.reason;
867
+ states.push(result.value);
868
+ }
869
+ }
870
+ return states;
871
+ }
872
+ async function feeInclusiveEarnShareSupply(client, vault, blockNumber) {
873
+ const [earnFees, supply] = await Promise.all([
874
+ client.readContract({ abi: vaultAbi, address: vault, blockNumber, functionName: 'earnFees' }),
875
+ client.readContract({
876
+ abi: vaultAbi,
877
+ address: vault,
878
+ blockNumber,
879
+ functionName: 'totalEarnShares',
880
+ }),
881
+ ]);
882
+ const preview = await client.readContract({
883
+ abi: feesAbi,
884
+ address: earnFees,
885
+ blockNumber,
886
+ functionName: 'previewAccruedFees',
887
+ });
888
+ return supply + preview.totalFeeEarnShares;
889
+ }
890
+ async function settleBoost(options, campaign, runRecord, bindings, calculation, signer) {
891
+ const boost = campaign.config.boostRewards;
892
+ if (!boost || !bindings.distributor) {
893
+ await commit(options.db, campaign, runRecord, calculation.accounts, calculation.closingCursor);
894
+ return undefined;
895
+ }
896
+ if (runRecord.phase === 'statement')
897
+ return publishPreparedStatement(options, campaign, runRecord, bindings.distributor, signer);
898
+ const rewardAssets = calculation.accounts.reduce((sum, account) => sum + account.pendingRewardAssets, 0n);
899
+ if (rewardAssets <= 1n) {
900
+ const hasDeferred = calculation.accounts.some((account) => account.cumulativePaid < account.cumulativeEntitlement);
901
+ const previous = hasDeferred
902
+ ? await RewardRuns.latestStatement(options.db, campaign)
903
+ : undefined;
904
+ if (previous?.statement &&
905
+ previous.root &&
906
+ previous.rootVersion &&
907
+ previous.statementHash &&
908
+ previous.liability) {
909
+ const evidence = {
910
+ ...calculation.evidence,
911
+ closingAccounts: calculation.accounts.map(Projection.snapshot),
912
+ };
913
+ await requireTransition(options.db, runRecord, 'paying', {
914
+ evidence,
915
+ fundedAssets: '0',
916
+ liability: previous.liability,
917
+ mintedEarnShares: '0',
918
+ root: previous.root,
919
+ rootVersion: previous.rootVersion,
920
+ statement: previous.statement,
921
+ statementHash: previous.statementHash,
922
+ });
923
+ return { evidence, statement: previous.statement };
924
+ }
925
+ await commit(options.db, campaign, runRecord, calculation.accounts, calculation.closingCursor);
926
+ return undefined;
927
+ }
928
+ const client = options.getClient(campaign.chainId);
929
+ const quote = await vaultQuote(client, campaign.vaultAddress);
930
+ const desiredShares = Campaigns.assetsToEarnShares({ assets: rewardAssets, ...quote });
931
+ // Preserve sub-share rewards until enough assets accrue to mint at least one EarnShare.
932
+ if (desiredShares === 0n) {
933
+ await commit(options.db, campaign, runRecord, calculation.accounts, calculation.closingCursor);
934
+ return undefined;
935
+ }
936
+ const allocation = Campaigns.allocate({
937
+ earnShares: desiredShares,
938
+ rewards: calculation.accounts.map((account) => ({
939
+ assets: account.pendingRewardAssets,
940
+ recipient: account.recipient,
941
+ })),
942
+ });
943
+ const settlementRecipientAddresses = [...allocation.entries()]
944
+ .filter(([, amount]) => amount > 0n)
945
+ .map(([recipient]) => recipient);
946
+ for (const account of calculation.accounts) {
947
+ account.cumulativeEntitlement += allocation.get(account.recipient) ?? 0n;
948
+ account.pendingRewardAssets = 0n;
949
+ }
950
+ const statement = Campaigns.buildStatement({
951
+ campaignId: campaignId(campaign.vaultAddress),
952
+ chainId: campaign.chainId,
953
+ distributor: bindings.distributor,
954
+ entitlements: calculation.accounts
955
+ .filter((account) => account.cumulativeEntitlement > 0n)
956
+ .map((account) => ({
957
+ cumulativeAmount: account.cumulativeEntitlement.toString(),
958
+ recipient: account.recipient,
959
+ })),
960
+ });
961
+ const [version, entitlement, paid, inventory] = await Promise.all([
962
+ client.readContract({
963
+ abi: distributorAbi,
964
+ address: bindings.distributor,
965
+ functionName: 'rootVersion',
966
+ }),
967
+ client.readContract({
968
+ abi: distributorAbi,
969
+ address: bindings.distributor,
970
+ functionName: 'rootTotalEntitlement',
971
+ }),
972
+ client.readContract({
973
+ abi: distributorAbi,
974
+ address: bindings.distributor,
975
+ functionName: 'totalPaid',
976
+ }),
977
+ client.readContract({
978
+ abi: erc20Abi,
979
+ address: campaign.earnShareAddress,
980
+ args: [bindings.distributor],
981
+ functionName: 'balanceOf',
982
+ }),
983
+ ]);
984
+ if (paid > entitlement)
985
+ throw new Error('Reward distributor paid total exceeds its published entitlement.');
986
+ const outstanding = entitlement - paid;
987
+ if (inventory < outstanding)
988
+ throw new Error('Reward distributor inventory is below its current unpaid liability.');
989
+ const unreserved = inventory - outstanding;
990
+ const missingEarnShares = desiredShares > unreserved ? desiredShares - unreserved : 0n;
991
+ const fundingEarnShares = Campaigns.settlementFundingEarnShares(missingEarnShares);
992
+ const fundedAssets = fundingEarnShares > 0n
993
+ ? Campaigns.earnSharesToAssets({ earnShares: fundingEarnShares, ...quote })
994
+ : 0n;
995
+ const prepared = await requireTransition(options.db, runRecord, 'statement', {
996
+ evidence: {
997
+ ...calculation.evidence,
998
+ closingAccounts: calculation.accounts.map(Projection.snapshot),
999
+ publishedRoot: true,
1000
+ settledRewardAssets: rewardAssets.toString(),
1001
+ settlementRecipientAddresses,
1002
+ settlementRecipients: settlementRecipientAddresses.length,
1003
+ },
1004
+ fundedAssets: fundedAssets.toString(),
1005
+ liability: statement.totalEntitlement,
1006
+ mintedEarnShares: missingEarnShares.toString(),
1007
+ root: statement.root,
1008
+ rootVersion: version.toString(),
1009
+ statement,
1010
+ statementHash: statement.statementHash,
1011
+ });
1012
+ return publishPreparedStatement(options, campaign, prepared, bindings.distributor, signer);
1013
+ }
1014
+ async function publishPreparedStatement(options, campaign, runRecord, distributor, signer) {
1015
+ runRecord = await refreshPreparedStatement(options, campaign, runRecord, distributor);
1016
+ const { evidence, fundedAssets, mintedEarnShares, rootVersion, statement } = runRecord;
1017
+ if (!evidence ||
1018
+ !statement ||
1019
+ fundedAssets === null ||
1020
+ mintedEarnShares === null ||
1021
+ rootVersion === null)
1022
+ throw new Error('Prepared reward statement is incomplete.');
1023
+ const publish = {
1024
+ distributor,
1025
+ domain: domain(options, campaign),
1026
+ expectedRootVersion: rootVersion,
1027
+ operation: 'publish',
1028
+ statement,
1029
+ };
1030
+ const intent = BigInt(fundedAssets) === 0n
1031
+ ? publish
1032
+ : {
1033
+ assets: fundedAssets,
1034
+ distributor,
1035
+ domain: publish.domain,
1036
+ expectedRootVersion: rootVersion,
1037
+ funder: campaign.config.boostRewards.funding.wallet,
1038
+ minEarnShares: mintedEarnShares,
1039
+ operation: 'settle',
1040
+ settlementId: Signer.id(publish),
1041
+ statement,
1042
+ };
1043
+ const attempt = await execute(options, campaign, runRecord.id, signer, intent);
1044
+ if (!attempt.transactionHash)
1045
+ throw new Error('Reward root transaction lacks a hash.');
1046
+ const client = options.getClient(campaign.chainId);
1047
+ const [confirmedVersion, confirmedRoot, confirmedStatementHash, confirmedEntitlement] = await Promise.all([
1048
+ client.readContract({
1049
+ abi: distributorAbi,
1050
+ address: distributor,
1051
+ functionName: 'rootVersion',
1052
+ }),
1053
+ client.readContract({
1054
+ abi: distributorAbi,
1055
+ address: distributor,
1056
+ functionName: 'merkleRoot',
1057
+ }),
1058
+ client.readContract({
1059
+ abi: distributorAbi,
1060
+ address: distributor,
1061
+ functionName: 'statementHash',
1062
+ }),
1063
+ client.readContract({
1064
+ abi: distributorAbi,
1065
+ address: distributor,
1066
+ functionName: 'rootTotalEntitlement',
1067
+ }),
1068
+ ]);
1069
+ if (confirmedVersion !== BigInt(rootVersion) + 1n ||
1070
+ confirmedRoot !== statement.root ||
1071
+ confirmedStatementHash !== statement.statementHash ||
1072
+ confirmedEntitlement !== BigInt(statement.totalEntitlement))
1073
+ throw new Error('Confirmed reward statement does not match the prepared root.');
1074
+ await requireTransition(options.db, runRecord, 'paying', {
1075
+ error: null,
1076
+ rootVersion: confirmedVersion.toString(),
1077
+ });
1078
+ return { evidence, statement };
1079
+ }
1080
+ async function refreshPreparedStatement(options, campaign, runRecord, distributor) {
1081
+ const attempts = await RewardTransactionAttempts.listForRun(options.db, runRecord.id);
1082
+ if (attempts.some((attempt) => (attempt.intent.operation === 'publish' || attempt.intent.operation === 'settle') &&
1083
+ ['signed', 'broadcast', 'confirmed'].includes(attempt.state)))
1084
+ return runRecord;
1085
+ if (!runRecord.statement || runRecord.rootVersion === null)
1086
+ throw new Error('Prepared reward statement is incomplete.');
1087
+ const client = options.getClient(campaign.chainId);
1088
+ const [version, paid, inventory] = await Promise.all([
1089
+ client.readContract({
1090
+ abi: distributorAbi,
1091
+ address: distributor,
1092
+ functionName: 'rootVersion',
1093
+ }),
1094
+ client.readContract({
1095
+ abi: distributorAbi,
1096
+ address: distributor,
1097
+ functionName: 'totalPaid',
1098
+ }),
1099
+ client.readContract({
1100
+ abi: erc20Abi,
1101
+ address: campaign.earnShareAddress,
1102
+ args: [distributor],
1103
+ functionName: 'balanceOf',
1104
+ }),
1105
+ ]);
1106
+ if (version !== BigInt(runRecord.rootVersion))
1107
+ throw new Error('Reward root changed after statement preparation.');
1108
+ const entitlement = BigInt(runRecord.statement.totalEntitlement);
1109
+ if (paid > entitlement)
1110
+ throw new Error('Reward paid total exceeds the prepared entitlement.');
1111
+ const available = paid + inventory;
1112
+ const missingEarnShares = entitlement > available ? entitlement - available : 0n;
1113
+ const fundingEarnShares = Campaigns.settlementFundingEarnShares(missingEarnShares);
1114
+ const fundedAssets = fundingEarnShares > 0n
1115
+ ? Campaigns.earnSharesToAssets({
1116
+ earnShares: fundingEarnShares,
1117
+ ...(await vaultQuote(client, campaign.vaultAddress)),
1118
+ })
1119
+ : 0n;
1120
+ if (runRecord.fundedAssets === fundedAssets.toString() &&
1121
+ runRecord.mintedEarnShares === missingEarnShares.toString())
1122
+ return runRecord;
1123
+ return requireTransition(options.db, runRecord, 'statement', {
1124
+ fundedAssets: fundedAssets.toString(),
1125
+ mintedEarnShares: missingEarnShares.toString(),
1126
+ });
1127
+ }
1128
+ async function vaultQuote(client, vault) {
1129
+ const [totalAssets, totalEarnShares] = await Promise.all([
1130
+ client.readContract({ abi: vaultAbi, address: vault, functionName: 'totalAssets' }),
1131
+ feeInclusiveEarnShareSupply(client, vault),
1132
+ ]);
1133
+ return { totalAssets, totalEarnShares };
1134
+ }
1135
+ async function deliver(options, campaign, runRecord, bindings, statement, calculation, signer) {
1136
+ if (!statement || !bindings.distributor)
1137
+ return;
1138
+ const { accounts, closingCursor, evidence } = calculation;
1139
+ const working = accounts.map((account) => ({
1140
+ ...account,
1141
+ lots: account.lots.map((lot) => ({ ...lot })),
1142
+ }));
1143
+ const client = options.getClient(campaign.chainId);
1144
+ const paidBefore = new Map(working.map((account) => [account.recipient.toLowerCase(), account.cumulativePaid]));
1145
+ await reconcilePaid(client, { accounts: working, distributor: bindings.distributor });
1146
+ const payoutRecipients = await (async () => {
1147
+ if (evidence.payoutRecipients !== undefined)
1148
+ return evidence.payoutRecipients;
1149
+ const endsAt = Number(runRecord.endsAt);
1150
+ // Payout decisions use the immutable schedule that accrued this run's rewards. A pending
1151
+ // schedule applies only after promotion creates a run with its own configuration snapshot.
1152
+ const closingBoost = runRecord.config.boostRewards;
1153
+ const push = Campaigns.shouldPushPayout(closingBoost, {
1154
+ endsAt,
1155
+ startsAfter: Number(runRecord.startsAfter),
1156
+ });
1157
+ const flush = endsAt >= Campaigns.finalBoundary({ boostRewards: closingBoost });
1158
+ const quote = push && !flush ? await vaultQuote(client, campaign.vaultAddress) : undefined;
1159
+ // Preserve visible small balance increases while avoiding automatic pushes worth less than gas.
1160
+ const minimumAssets = 10n ** BigInt(Math.max(campaign.assetDecimals - 4, 0));
1161
+ const selected = working
1162
+ .filter((account) => push &&
1163
+ account.cumulativePaid < account.cumulativeEntitlement &&
1164
+ (flush ||
1165
+ (quote &&
1166
+ Campaigns.meetsPayoutMinimum({
1167
+ cumulativeEntitlement: account.cumulativeEntitlement,
1168
+ cumulativePaid: account.cumulativePaid,
1169
+ minimumAssets,
1170
+ ...quote,
1171
+ }))))
1172
+ .map((account) => account.recipient);
1173
+ await requireTransition(options.db, runRecord, 'paying', {
1174
+ evidence: {
1175
+ ...evidence,
1176
+ closingAccounts: working.map(Projection.snapshot),
1177
+ payoutRecipients: selected,
1178
+ },
1179
+ });
1180
+ return selected;
1181
+ })();
1182
+ const unpaidRecipients = new Set(payoutRecipients.map((recipient) => recipient.toLowerCase()));
1183
+ const batches = Campaigns.buildPayoutBatches(statement, {
1184
+ maximumSize: payoutBatchSize,
1185
+ recipients: unpaidRecipients,
1186
+ });
1187
+ const bundles = chunks(batches, payoutCallsPerTransaction);
1188
+ const version = await client.readContract({
1189
+ abi: distributorAbi,
1190
+ address: bindings.distributor,
1191
+ functionName: 'rootVersion',
1192
+ });
1193
+ // Recipient-disjoint cumulative pushes commute. Tempo expiring nonces let each packed transaction
1194
+ // confirm independently, while bounded waves avoid overwhelming the signer and RPC.
1195
+ for (const wave of chunks(bundles, payoutTransactionConcurrency)) {
1196
+ const results = await Promise.allSettled(wave.map((bundle) => execute(options, campaign, runRecord.id, signer, {
1197
+ batches: bundle,
1198
+ distributor: bindings.distributor,
1199
+ domain: domain(options, campaign),
1200
+ operation: 'push',
1201
+ rootVersion: version.toString(),
1202
+ statementHash: statement.statementHash,
1203
+ })));
1204
+ const failure = results.find((result) => result.status === 'rejected');
1205
+ if (failure?.status === 'rejected')
1206
+ throw failure.reason;
1207
+ }
1208
+ await reconcilePaid(client, { accounts: working, distributor: bindings.distributor });
1209
+ for (const account of working)
1210
+ account.deferral = (() => {
1211
+ if (account.cumulativePaid >= account.cumulativeEntitlement)
1212
+ return undefined;
1213
+ if (unpaidRecipients.has(account.recipient.toLowerCase()))
1214
+ return 'transfer_unavailable';
1215
+ return account.deferral;
1216
+ })();
1217
+ const settlementRecipients = new Set((evidence.settlementRecipientAddresses ?? []).map((recipient) => recipient.toLowerCase()));
1218
+ const paidRecipients = evidence.paidRecipients ??
1219
+ (settlementRecipients.size > 0
1220
+ ? working.filter((account) => settlementRecipients.has(account.recipient.toLowerCase()) &&
1221
+ account.cumulativePaid >= account.cumulativeEntitlement).length
1222
+ : working.filter((account) => unpaidRecipients.has(account.recipient.toLowerCase()) &&
1223
+ account.cumulativePaid > (paidBefore.get(account.recipient.toLowerCase()) ?? 0n)).length);
1224
+ const payoutPaidRecipients = evidence.payoutPaidRecipients ??
1225
+ working.filter((account) => account.cumulativePaid > (paidBefore.get(account.recipient.toLowerCase()) ?? 0n)).length;
1226
+ const deferredRecipients = evidence.deferredRecipients ??
1227
+ Math.max((settlementRecipients.size > 0
1228
+ ? settlementRecipients.size
1229
+ : (evidence.settlementRecipients ?? 0)) - paidRecipients, 0);
1230
+ const pendingRecipients = evidence.pendingRecipients ??
1231
+ working.filter((account) => account.cumulativePaid < account.cumulativeEntitlement).length;
1232
+ await requireTransition(options.db, runRecord, 'paying', {
1233
+ evidence: {
1234
+ ...evidence,
1235
+ closingAccounts: working.map(Projection.snapshot),
1236
+ deferredRecipients,
1237
+ paidRecipients,
1238
+ payoutPaidRecipients,
1239
+ payoutRecipients,
1240
+ pendingRecipients,
1241
+ },
1242
+ });
1243
+ await commit(options.db, campaign, runRecord, working, closingCursor, statement);
1244
+ }
1245
+ async function reconcilePaid(client, options) {
1246
+ for (const group of chunks(options.accounts, 500)) {
1247
+ const paid = await client.multicall({
1248
+ allowFailure: true,
1249
+ contracts: group.map((account) => ({
1250
+ abi: distributorAbi,
1251
+ address: options.distributor,
1252
+ args: [account.recipient],
1253
+ functionName: 'cumulativePaid',
1254
+ })),
1255
+ });
1256
+ paid.forEach((result, index) => {
1257
+ if (result.status !== 'success')
1258
+ throw new Error('Reward payment reconciliation failed.');
1259
+ group[index].cumulativePaid = result.result;
1260
+ });
1261
+ }
1262
+ }
1263
+ async function execute(options, campaign, runId, signer, signerIntent) {
1264
+ const intentId = Signer.id(signerIntent);
1265
+ let attempt = await RewardTransactionAttempts.latestForIntent(options.db, {
1266
+ intentId,
1267
+ ...(runId ? { runId } : {}),
1268
+ });
1269
+ if (attempt?.state === 'confirmed')
1270
+ return attempt;
1271
+ const replacementOf = attempt?.state === 'expired' ||
1272
+ attempt?.state === 'ineffective' ||
1273
+ attempt?.state === 'reverted'
1274
+ ? attempt.id
1275
+ : undefined;
1276
+ if (replacementOf)
1277
+ attempt = undefined;
1278
+ if (!attempt) {
1279
+ try {
1280
+ attempt = await RewardTransactionAttempts.create(options.db, {
1281
+ chainId: campaign.chainId,
1282
+ intent: { id: intentId, operation: signerIntent.operation, payload: signerIntent },
1283
+ ...(replacementOf ? { replacementOf } : {}),
1284
+ ...(runId ? { runId } : {}),
1285
+ signer,
1286
+ vaultAddress: campaign.vaultAddress,
1287
+ });
1288
+ }
1289
+ catch (cause) {
1290
+ // Queue redelivery can race before either invocation observes the other's journal row.
1291
+ // The unique live-intent constraint elects one attempt; the loser resumes that evidence.
1292
+ if (!isUniqueViolation(cause))
1293
+ throw cause;
1294
+ attempt = await RewardTransactionAttempts.latestForIntent(options.db, {
1295
+ intentId,
1296
+ ...(runId ? { runId } : {}),
1297
+ });
1298
+ if (!attempt)
1299
+ throw cause;
1300
+ }
1301
+ }
1302
+ if (attempt.state === 'created') {
1303
+ const signed = await Signer.sign({
1304
+ fetch: options.signerFetch,
1305
+ request: { attemptId: attempt.id, id: intentId, intent: signerIntent },
1306
+ });
1307
+ if (!isAddressEqual(signed.signer, signer))
1308
+ throw new Error('Reward signer account changed.');
1309
+ attempt =
1310
+ (await RewardTransactionAttempts.recordSignature(options.db, {
1311
+ expiresAt: signed.expiresAt,
1312
+ id: attempt.id,
1313
+ nonce: signed.nonce,
1314
+ signedBytes: signed.signedBytes,
1315
+ transactionHash: signed.transactionHash,
1316
+ })) ?? attempt;
1317
+ }
1318
+ if (!attempt.signedBytes || !attempt.transactionHash)
1319
+ throw new Error('Reward transaction was not durably signed.');
1320
+ const client = options.getClient(campaign.chainId);
1321
+ let receipt = await client
1322
+ .getTransactionReceipt({ hash: attempt.transactionHash })
1323
+ .catch(() => undefined);
1324
+ const expiredBeforeBroadcast = !receipt &&
1325
+ attempt.expiresAt &&
1326
+ Number((await client.getBlock()).timestamp) * 1_000 >= Date.parse(attempt.expiresAt);
1327
+ if (expiredBeforeBroadcast) {
1328
+ const expired = await RewardTransactionAttempts.expire(options.db, attempt.id);
1329
+ if (!expired)
1330
+ throw new Error('Expired reward transaction could not be replaced.');
1331
+ return execute(options, campaign, runId, signer, signerIntent);
1332
+ }
1333
+ if (!receipt && (attempt.state === 'signed' || attempt.state === 'broadcast')) {
1334
+ await options.assertLease?.();
1335
+ try {
1336
+ await client.sendRawTransaction({ serializedTransaction: attempt.signedBytes });
1337
+ }
1338
+ catch (cause) {
1339
+ receipt = await client
1340
+ .getTransactionReceipt({ hash: attempt.transactionHash })
1341
+ .catch(() => undefined);
1342
+ if (!receipt &&
1343
+ (!(cause instanceof Error) ||
1344
+ !/already known|already imported|known transaction/i.test(cause.message)))
1345
+ throw cause;
1346
+ }
1347
+ await RewardTransactionAttempts.recordBroadcast(options.db, attempt.id);
1348
+ }
1349
+ if (!receipt)
1350
+ receipt = await client
1351
+ .waitForTransactionReceipt({
1352
+ confirmations: 1,
1353
+ hash: attempt.transactionHash,
1354
+ timeout: 60_000,
1355
+ })
1356
+ .catch(async (cause) => {
1357
+ const recovered = await client
1358
+ .getTransactionReceipt({ hash: attempt.transactionHash })
1359
+ .catch(() => undefined);
1360
+ if (recovered)
1361
+ return recovered;
1362
+ const expiredOnchain = attempt.expiresAt &&
1363
+ Number((await client.getBlock()).timestamp) * 1_000 >= Date.parse(attempt.expiresAt);
1364
+ if (!expiredOnchain)
1365
+ throw cause;
1366
+ const expiredAttempt = await RewardTransactionAttempts.expire(options.db, attempt.id);
1367
+ if (!expiredAttempt)
1368
+ throw cause;
1369
+ return undefined;
1370
+ });
1371
+ if (!receipt)
1372
+ return execute(options, campaign, runId, signer, signerIntent);
1373
+ if (receipt.status === 'pending')
1374
+ throw new Error(`Reward transaction ${attempt.transactionHash} is still pending.`);
1375
+ const canonical = await client.getBlock({ blockNumber: receipt.blockNumber });
1376
+ if (canonical.hash !== receipt.blockHash)
1377
+ throw new Error('Reward receipt block is not canonical.');
1378
+ const confirmed = await RewardTransactionAttempts.confirm(options.db, {
1379
+ id: attempt.id,
1380
+ intent: compactIntent(intentId, signerIntent),
1381
+ receipt: {
1382
+ blockHash: receipt.blockHash,
1383
+ blockNumber: receipt.blockNumber.toString(),
1384
+ gasUsed: receipt.gasUsed.toString(),
1385
+ status: receipt.status,
1386
+ transactionHash: receipt.transactionHash,
1387
+ },
1388
+ });
1389
+ if (!confirmed || confirmed.receipt?.status !== 'success')
1390
+ throw new Error(`Reward transaction ${attempt.transactionHash} reverted.`);
1391
+ return confirmed;
1392
+ }
1393
+ function isUniqueViolation(cause) {
1394
+ return typeof cause === 'object' && cause !== null && 'code' in cause && cause.code === '23505';
1395
+ }
1396
+ function compactIntent(id, intent) {
1397
+ if (intent.operation === 'push')
1398
+ return {
1399
+ id,
1400
+ operation: intent.operation,
1401
+ payload: {
1402
+ batchCount: intent.batches.length,
1403
+ distributor: intent.distributor,
1404
+ domain: intent.domain,
1405
+ recipientCount: intent.batches.reduce((sum, batch) => sum + batch.recipients.length, 0),
1406
+ rootVersion: intent.rootVersion,
1407
+ statementHash: intent.statementHash,
1408
+ },
1409
+ };
1410
+ if (intent.operation === 'publish' || intent.operation === 'settle') {
1411
+ const { statement, ...payload } = intent;
1412
+ return {
1413
+ id,
1414
+ operation: intent.operation,
1415
+ payload: {
1416
+ ...payload,
1417
+ statement: {
1418
+ campaignId: statement.campaignId,
1419
+ chainId: statement.chainId,
1420
+ distributor: statement.distributor,
1421
+ entryCount: statement.entries.length,
1422
+ root: statement.root,
1423
+ schemaVersion: statement.schemaVersion,
1424
+ statementHash: statement.statementHash,
1425
+ totalEntitlement: statement.totalEntitlement,
1426
+ },
1427
+ },
1428
+ };
1429
+ }
1430
+ return { id, operation: intent.operation, payload: intent };
1431
+ }
1432
+ function maintainLease(db, runRecord, now) {
1433
+ let failure;
1434
+ let stopped = false;
1435
+ const extend = async () => {
1436
+ if (stopped || failure !== undefined)
1437
+ return;
1438
+ const renewed = await RewardRuns.renew(db, {
1439
+ fence: runRecord.fence,
1440
+ id: runRecord.id,
1441
+ leaseExpiresAt: new Date(now() + runLeaseMilliseconds).toISOString(),
1442
+ });
1443
+ if (!renewed)
1444
+ failure = new Error('Reward run lease was lost.');
1445
+ };
1446
+ const captureFailure = (cause) => {
1447
+ failure = cause;
1448
+ };
1449
+ let renewal = extend().catch(captureFailure);
1450
+ const timer = setInterval(() => {
1451
+ renewal = renewal.then(extend).catch(captureFailure);
1452
+ }, Math.floor(runLeaseMilliseconds / 2));
1453
+ return {
1454
+ async assert() {
1455
+ await renewal;
1456
+ await extend();
1457
+ if (failure !== undefined)
1458
+ throw failure;
1459
+ },
1460
+ async ready() {
1461
+ await renewal;
1462
+ if (failure !== undefined)
1463
+ throw failure;
1464
+ },
1465
+ async stop() {
1466
+ stopped = true;
1467
+ clearInterval(timer);
1468
+ await renewal;
1469
+ return failure;
1470
+ },
1471
+ };
1472
+ }
1473
+ async function commit(db, campaign, runRecord, accounts, eventCursor, statement) {
1474
+ const now = new Date().toISOString();
1475
+ await db.transaction(async (tx) => {
1476
+ await RewardAccounts.replace(tx, {
1477
+ accounts: accounts.map((account) => ({
1478
+ accrualRemainder: account.accrualRemainder.toString(),
1479
+ allocatedPrincipalAssets: account.allocatedPrincipalAssets.toString(),
1480
+ cumulativeEntitlement: account.cumulativeEntitlement.toString(),
1481
+ cumulativePaid: account.cumulativePaid.toString(),
1482
+ deferral: account.deferral ?? null,
1483
+ eligibilityRegisteredAt: account.eligibilityRegisteredAt ?? null,
1484
+ lots: account.lots,
1485
+ pendingRewardAssets: account.pendingRewardAssets.toString(),
1486
+ publicEarnShares: account.publicEarnShares.toString(),
1487
+ qualifiedEarnShares: account.qualifiedEarnShares.toString(),
1488
+ recipient: account.recipient,
1489
+ registrationOrder: account.registrationOrder.toString(),
1490
+ updatedAt: now,
1491
+ })),
1492
+ chainId: campaign.chainId,
1493
+ vaultAddress: campaign.vaultAddress,
1494
+ });
1495
+ const advanced = await RewardCampaigns.advance(tx, {
1496
+ chainId: campaign.chainId,
1497
+ deliveredThrough: Number(runRecord.endsAt),
1498
+ ...(eventCursor ? { eventCursor } : {}),
1499
+ expectedDeliveredThrough: Number(runRecord.startsAfter),
1500
+ vaultAddress: campaign.vaultAddress,
1501
+ });
1502
+ if (!advanced)
1503
+ throw new Error('Reward campaign cursor changed before commit.');
1504
+ const current = await RewardRuns.get(tx, runRecord.id);
1505
+ const delivered = await RewardRuns.transition(tx, {
1506
+ fence: runRecord.fence,
1507
+ id: runRecord.id,
1508
+ patch: {
1509
+ error: null,
1510
+ ...(current?.evidence ? { evidence: Campaigns.compactEvidence(current.evidence) } : {}),
1511
+ },
1512
+ phase: 'delivered',
1513
+ });
1514
+ if (!delivered)
1515
+ throw new Error('Reward run lease changed before commit.');
1516
+ if (statement)
1517
+ await RewardRuns.pruneStatements(tx, {
1518
+ chainId: campaign.chainId,
1519
+ keepRunId: runRecord.id,
1520
+ vaultAddress: campaign.vaultAddress,
1521
+ });
1522
+ });
1523
+ }
1524
+ async function requireTransition(db, runRecord, phase, patch) {
1525
+ const result = await RewardRuns.transition(db, {
1526
+ fence: runRecord.fence,
1527
+ id: runRecord.id,
1528
+ patch,
1529
+ phase,
1530
+ });
1531
+ if (!result)
1532
+ throw new Error('Reward run lease was lost.');
1533
+ return result;
1534
+ }
1535
+ function restoreCalculation(evidence) {
1536
+ return {
1537
+ accounts: evidence.closingAccounts.map(Projection.fromSnapshot),
1538
+ ...(evidence.eventCursor ? { closingCursor: evidence.eventCursor } : {}),
1539
+ evidence,
1540
+ };
1541
+ }
1542
+ async function* emptyEventPages() { }
1543
+ async function* reconciliationEventPages(pages) {
1544
+ for await (const events of pages)
1545
+ yield { events };
1546
+ }
1547
+ async function* registrationDepositPages(tidx, options) {
1548
+ const accounts = [...options.accounts].sort((left, right) => left.registrationOrder < right.registrationOrder
1549
+ ? -1
1550
+ : left.registrationOrder > right.registrationOrder
1551
+ ? 1
1552
+ : left.recipient.toLowerCase().localeCompare(right.recipient.toLowerCase()));
1553
+ const afterOrder = options.afterRecipient
1554
+ ? accounts.find((entry) => isAddressEqual(entry.recipient, options.afterRecipient))
1555
+ ?.registrationOrder
1556
+ : undefined;
1557
+ if (options.afterRecipient && afterOrder === undefined)
1558
+ throw new Error('Reward reconciliation recipient is no longer registered.');
1559
+ for (const account of accounts) {
1560
+ if (afterOrder !== undefined &&
1561
+ (account.registrationOrder < afterOrder ||
1562
+ (account.registrationOrder === afterOrder && !options.after)))
1563
+ continue;
1564
+ const pages = Events.accountDepositPages(tidx, {
1565
+ ...(afterOrder === account.registrationOrder && options.after
1566
+ ? { after: options.after }
1567
+ : {}),
1568
+ account: account.recipient,
1569
+ earnVault: options.earnVault,
1570
+ throughBlock: options.throughBlock,
1571
+ });
1572
+ for await (const events of pages)
1573
+ yield { allocationRecipient: account.recipient, events };
1574
+ yield { allocationRecipient: account.recipient, events: [] };
1575
+ }
1576
+ }
1577
+ async function notificationSummary(db, campaign, runId) {
1578
+ const record = await RewardRuns.get(db, runId);
1579
+ const evidence = record?.evidence;
1580
+ if (!record || !evidence)
1581
+ return undefined;
1582
+ const [attempts, vault] = await Promise.all([
1583
+ RewardTransactionAttempts.confirmedForRun(db, runId),
1584
+ EarnVaultRecords.get(db, campaign),
1585
+ ]);
1586
+ const root = attempts.find((attempt) => attempt.intent.operation === 'publish' || attempt.intent.operation === 'settle');
1587
+ const targetAttempt = attempts.find((attempt) => attempt.intent.operation === 'targetYield');
1588
+ const payoutTransactionHashes = attempts
1589
+ .filter((attempt) => attempt.intent.operation === 'push' && attempt.transactionHash)
1590
+ .map((attempt) => attempt.transactionHash);
1591
+ const closingInterval = evidence.intervals.at(-1);
1592
+ const targetActive = Boolean(record.config.targetYield &&
1593
+ Campaigns.overlapsCompleteIntervals(record.config.targetYield, {
1594
+ endsAt: Number(record.endsAt),
1595
+ startsAfter: Number(record.startsAfter),
1596
+ }));
1597
+ const targetActiveAtClose = Boolean(record.config.targetYield &&
1598
+ closingInterval &&
1599
+ closingInterval.endsAt > record.config.targetYield.startTimestamp &&
1600
+ closingInterval.endsAt <= record.config.targetYield.endTimestamp);
1601
+ const boostActiveAtClose = Boolean(record.config.boostRewards &&
1602
+ record.config.boostRewards.enabled !== false &&
1603
+ closingInterval &&
1604
+ closingInterval.endsAt > record.config.boostRewards.startTimestamp &&
1605
+ closingInterval.endsAt <= record.config.boostRewards.endTimestamp);
1606
+ const targetRateBps = targetActiveAtClose
1607
+ ? (evidence.appliedTargetRateBps ?? evidence.targetRateBps)
1608
+ : undefined;
1609
+ const settlement = (() => {
1610
+ if (!evidence.publishedRoot ||
1611
+ evidence.settledRewardAssets === undefined ||
1612
+ evidence.settlementRecipients === undefined ||
1613
+ !root?.transactionHash)
1614
+ return undefined;
1615
+ return {
1616
+ assetAmount: evidence.settledRewardAssets,
1617
+ creditedRecipients: evidence.settlementRecipients,
1618
+ deferredRecipients: evidence.deferredRecipients ??
1619
+ Math.max(evidence.settlementRecipients - (evidence.paidRecipients ?? 0), 0),
1620
+ transactionHash: root.transactionHash,
1621
+ };
1622
+ })();
1623
+ if (!targetActive && !settlement && payoutTransactionHashes.length === 0)
1624
+ return undefined;
1625
+ return {
1626
+ assetDecimals: campaign.assetDecimals,
1627
+ baseRateBps: Math.max(closingInterval?.organicRateBps ?? 0, targetRateBps ?? 0),
1628
+ ...(boostActiveAtClose ? { boostRateBps: closingInterval?.boostRateBps ?? 0 } : {}),
1629
+ intervalCount: evidence.intervals.length,
1630
+ ...(payoutTransactionHashes.length > 0
1631
+ ? {
1632
+ payout: {
1633
+ deferredRecipients: evidence.pendingRecipients ?? 0,
1634
+ paidRecipients: evidence.payoutPaidRecipients ?? evidence.paidRecipients ?? 0,
1635
+ transactionHashes: payoutTransactionHashes,
1636
+ },
1637
+ }
1638
+ : {}),
1639
+ ...(settlement ? { settlement } : {}),
1640
+ ...(targetActive
1641
+ ? {
1642
+ targetYield: {
1643
+ assetAmount: (evidence.targetFundingAssets ?? [])
1644
+ .reduce((sum, amount) => sum + BigInt(amount), 0n)
1645
+ .toString(),
1646
+ ...(targetAttempt?.transactionHash
1647
+ ? { transactionHash: targetAttempt.transactionHash }
1648
+ : {}),
1649
+ },
1650
+ }
1651
+ : {}),
1652
+ vaultLabel: vault?.label ?? campaign.vaultAddress,
1653
+ };
1654
+ }
1655
+ async function allEligible(db, campaign) {
1656
+ const records = [];
1657
+ let cursor;
1658
+ do {
1659
+ const page = await RewardEligibilityAssociations.list(db, {
1660
+ chainId: campaign.chainId,
1661
+ ...(cursor ? { cursor } : {}),
1662
+ limit: 1_000,
1663
+ vaultAddress: campaign.vaultAddress,
1664
+ });
1665
+ if (records.length + page.data.length > maximumRecipients)
1666
+ throw new Error(`Reward campaign exceeds ${maximumRecipients} registered recipients.`);
1667
+ records.push(...page.data);
1668
+ cursor = page.nextCursor ?? undefined;
1669
+ } while (cursor);
1670
+ return records;
1671
+ }
1672
+ async function targetRate(options, campaign, runRecord) {
1673
+ const config = campaign.config.targetYield;
1674
+ const previous = await RewardRuns.latestDelivered(options.db, campaign);
1675
+ const fallback = previous?.evidence?.targetRateBps !== undefined &&
1676
+ previous.evidence.targetRateObservedAt &&
1677
+ sameRateSource(previous.config.targetYield?.annualRate, config.annualRate)
1678
+ ? {
1679
+ annualRateBps: previous.evidence.targetRateBps,
1680
+ observedAt: previous.evidence.targetRateObservedAt,
1681
+ }
1682
+ : undefined;
1683
+ const result = await Rates.target({
1684
+ boundary: new Date(Number(runRecord.endsAt) * 1_000).toISOString(),
1685
+ ...(fallback ? { fallback } : {}),
1686
+ fetch: options.fetch,
1687
+ now: () => new Date(options.now()),
1688
+ source: config.annualRate,
1689
+ });
1690
+ return { config, ...result };
1691
+ }
1692
+ function sameRateSource(left, right) {
1693
+ if (!left)
1694
+ return false;
1695
+ if ('bps' in left || 'bps' in right)
1696
+ return 'bps' in left && 'bps' in right && left.bps === right.bps;
1697
+ return (left.morphoVault.toLowerCase() === right.morphoVault.toLowerCase() &&
1698
+ left.minBps === right.minBps &&
1699
+ left.maxBps === right.maxBps &&
1700
+ left.staleAfterSeconds === right.staleAfterSeconds);
1701
+ }
1702
+ function sameTargetFunding(left, right) {
1703
+ return Boolean(left &&
1704
+ left.length === right.length &&
1705
+ left.every((leg, index) => {
1706
+ const compared = right[index];
1707
+ if (leg.wallet.toLowerCase() !== compared.wallet.toLowerCase())
1708
+ return false;
1709
+ if ('remainder' in leg || 'remainder' in compared)
1710
+ return 'remainder' in leg && 'remainder' in compared;
1711
+ return leg.upToAnnualRate.bps === compared.upToAnnualRate.bps;
1712
+ }));
1713
+ }
1714
+ async function exclusions(options, campaign, bindings) {
1715
+ const boost = campaign.config.boostRewards;
1716
+ if (!boost)
1717
+ return [];
1718
+ const client = options.getClient(campaign.chainId);
1719
+ const [earnFees, engine, vault] = await Promise.all([
1720
+ client.readContract({
1721
+ abi: vaultAbi,
1722
+ address: campaign.vaultAddress,
1723
+ functionName: 'earnFees',
1724
+ }),
1725
+ client.readContract({
1726
+ abi: vaultAbi,
1727
+ address: campaign.vaultAddress,
1728
+ functionName: 'engine',
1729
+ }),
1730
+ EarnVaultRecords.get(options.db, campaign),
1731
+ ]);
1732
+ const zoneContracts = options.zones
1733
+ .filter((zone) => zone.sourceId === campaign.chainId)
1734
+ .flatMap((zone) => Object.values(zone.contracts ?? {}))
1735
+ .flatMap(contractAddresses);
1736
+ return [
1737
+ ...new Set([
1738
+ campaign.vaultAddress,
1739
+ campaign.earnShareAddress,
1740
+ earnFees,
1741
+ engine,
1742
+ boost.treasury,
1743
+ ...(bindings.controller ? [bindings.controller] : []),
1744
+ ...(bindings.distributor ? [bindings.distributor] : []),
1745
+ ...(vault?.zones.map((zone) => zone.earnRouter) ?? []),
1746
+ ...zoneContracts,
1747
+ ...boost.excludedAddresses,
1748
+ ].map((address) => getAddress(address).toLowerCase())),
1749
+ ].map(getAddress);
1750
+ }
1751
+ function contractAddresses(contract) {
1752
+ if (!contract || typeof contract !== 'object')
1753
+ return [];
1754
+ const value = contract;
1755
+ const address = value['address'];
1756
+ if (typeof address === 'string' && isAddress(address))
1757
+ return [address];
1758
+ return Object.values(value).flatMap(contractAddresses);
1759
+ }
1760
+ function domain(options, campaign, config = campaign.config) {
1761
+ return {
1762
+ chainId: campaign.chainId,
1763
+ earnShare: getAddress(campaign.earnShareAddress),
1764
+ earnVault: getAddress(campaign.vaultAddress),
1765
+ factory: options.factory,
1766
+ treasury: config.boostRewards?.treasury ?? '0x0000000000000000000000000000000000000000',
1767
+ };
1768
+ }
1769
+ function campaignId(vault) {
1770
+ return `0x${'0'.repeat(24)}${vault.slice(2).toLowerCase()}`;
1771
+ }
1772
+ function chunks(items, size) {
1773
+ const result = [];
1774
+ for (let index = 0; index < items.length; index += size)
1775
+ result.push(items.slice(index, index + size));
1776
+ return result;
1777
+ }
1778
+ //# sourceMappingURL=Runner.js.map