tapimo 0.15.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -7,7 +7,6 @@ import * as Scope from '../../../Scope.js';
7
7
  import * as Db from '../../../db/Db.js';
8
8
  import * as core_EarnVaults from '../../../db/tables/earnVaults.js';
9
9
  import * as RewardCampaignDistributors from '../../../db/tables/rewardCampaignDistributors.js';
10
- import * as RewardCampaigns from '../../../db/tables/rewardCampaigns.js';
11
10
  import * as RewardEligibilityAssociations from '../../../db/tables/rewardEligibilityAssociations.js';
12
11
  import * as Auth from '../../../internal/Auth.js';
13
12
  import * as Cache from '../../../internal/Cache.js';
@@ -15,6 +14,7 @@ import * as Cursor from '../../../internal/Cursor.js';
15
14
  import * as EarnRates from '../../../internal/EarnRates.js';
16
15
  import * as EarnSharePrices from '../../../internal/EarnSharePrices.js';
17
16
  import * as EarnVaults from '../../../internal/EarnVaults.js';
17
+ import * as EarnWithdrawals from '../../../internal/EarnWithdrawals.js';
18
18
  import * as OpenApi from '../../../internal/OpenApi.js';
19
19
  import * as RewardRead from '../../../internal/rewards/Read.js';
20
20
  import * as Response from '../../../internal/Response.js';
@@ -377,10 +377,16 @@ export var schema;
377
377
  const position = z.strictObject({
378
378
  account: Schema.Address.check(z.describe('Account whose earn position was read.'), z.meta({ examples: ['0xbe058e1c4df8a4366a387bf595b284246a93039e'] })),
379
379
  assetAllowance: Schema.DecimalString.check(z.describe('Assets the vault may spend from a direct account, in asset base units. Always zero for Zone-routed positions, which use Zone withdrawals instead of approvals.'), z.meta({ examples: ['0'] })),
380
- assetBalance: Schema.DecimalString.check(z.describe('Assets held by this account at the observation block, in asset base units.'), z.meta({ examples: ['250000000'] })),
381
- assetToken: Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50').check(z.describe('TIP-20 asset token accepted by the vault or its selected Zone route.')),
380
+ assetBalance: Schema.DecimalString.check(z.describe('Public vault assets held by this account at the observation block, in asset base units.'), z.meta({ examples: ['250000000'] })),
381
+ assetToken: Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50').check(z.describe('TIP-20 asset token accepted by the public parent vault.')),
382
382
  chainId: Schema.ChainId.check(z.describe('Chain containing the account position.'), z.meta({ examples: [42431] })),
383
383
  id: Schema.Address.check(z.describe('Stable resource ID for this vault position, equal to the account address.'), z.meta({ examples: ['0xbe058e1c4df8a4366a387bf595b284246a93039e'] })),
384
+ privateAssetBalance: z
385
+ .optional(Schema.DecimalString)
386
+ .check(z.describe('Private Zone assets held by this account at the observation block, in private asset base units.'), z.meta({ examples: ['250000000'] })),
387
+ privateAssetToken: z
388
+ .optional(Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50'))
389
+ .check(z.describe('TIP-20 private asset used by the validated Zone route.')),
384
390
  shareAllowance: Schema.DecimalString.check(z.describe('Earn shares the vault may spend from a direct account, in share base units. Always zero for Zone-routed positions, which use Zone withdrawals instead of approvals.'), z.meta({ examples: ['0'] })),
385
391
  shareBalance: Schema.DecimalString.check(z.describe('Earn shares held by this account at the observation block, in share base units.'), z.meta({ examples: ['99500000'] })),
386
392
  shareToken: Schema.tokenAddress('0x20c000000000000000000000300e14ab91a10769').check(z.describe('TIP-20 token representing earn shares.')),
@@ -402,16 +408,16 @@ export var schema;
402
408
  .string()
403
409
  .check(z.regex(/^\d+(\.\d+)?$/), z.describe('Position amount rendered in whole vault asset units.'), z.meta({ examples: ['25000'] })),
404
410
  })
405
- .check(z.describe('Vault asset amount receiving this annual rate.'), z.meta({
411
+ .check(z.describe('Vault asset amount receiving this annual rate. Zero for an eligible boost with no currently qualified amount.'), z.meta({
406
412
  examples: [{ baseUnits: '25000000000', decimals: 6, formatted: '25000' }],
407
413
  })),
408
414
  net: EarnRates.schema.Apy.shape.net.check(z.describe('Annual rate applied to this position amount.'), z.meta({ examples: ['0.07'] })),
409
415
  type: z
410
416
  .enum(['base', 'boost'])
411
- .check(z.describe('Base vault yield or qualified depositor boost.'), z.meta({ examples: ['boost'] })),
417
+ .check(z.describe('Base vault yield or eligible depositor boost target.'), z.meta({ examples: ['boost'] })),
412
418
  })
413
419
  .check(z.describe('Position component receiving one annual rate.')))
414
- .check(z.describe('Position amounts grouped by the annual rate they receive.'), z.meta({
420
+ .check(z.describe('Position amounts grouped by annual rate. Eligible active boosts appear even with zero qualified amount and do not increase the balance-weighted net rate.'), z.meta({
415
421
  examples: [
416
422
  [
417
423
  {
@@ -435,7 +441,7 @@ export var schema;
435
441
  .literal('complete')
436
442
  .check(z.describe('Cash flows are complete through the indexed boundary.'), z.meta({ examples: ['complete'] })),
437
443
  totalDeposited: Schema.DecimalString.check(z.describe('Assets deposited with this account as receiver over indexed vault history.')),
438
- totalWithdrawn: Schema.DecimalString.check(z.describe('Assets returned by completed withdrawals over indexed vault history.')),
444
+ totalWithdrawn: Schema.DecimalString.check(z.describe('Completed withdrawal proceeds plus other outgoing shares valued at their transfer blocks.')),
439
445
  }),
440
446
  z.strictObject({
441
447
  status: z
@@ -468,19 +474,30 @@ export var schema;
468
474
  const earningsBase = z.strictObject({
469
475
  account: Schema.Address.check(z.describe('Account whose vault earnings were calculated.'), z.meta({ examples: ['0x68f94cfca22e5969c0553bbeab00a2acde88939b'] })),
470
476
  assetToken: Schema.TokenAddress.check(z.describe('TIP-20 asset token accepted by the vault.'), z.meta({ examples: ['0x20c000000000000000000000ff04042ee92fd449'] })),
471
- currentValue: Schema.DecimalString.check(z.describe('Asset value of the account’s active earn shares at the latest indexed block, in asset base units.'), z.meta({ examples: ['600000'] })),
477
+ currentValue: Schema.DecimalString.check(z.describe('Asset value of the account’s active earn shares at the ending indexed block, in asset base units.'), z.meta({ examples: ['600000'] })),
472
478
  id: Schema.Address.check(z.describe('Stable resource ID for these vault earnings, equal to the account address.'), z.meta({ examples: ['0x68f94cfca22e5969c0553bbeab00a2acde88939b'] })),
473
479
  });
474
480
  const earningsPeriod = z
475
- .enum(['30d', 'active', 'lifetime'])
476
- .check(z.describe('Earnings period to calculate: trailing 30 days, shares still held, or lifetime history.'), z.meta({ examples: ['lifetime'] }));
481
+ .enum(['7d', '30d', 'active', 'custom', 'lifetime'])
482
+ .check(z.describe('Earnings period: trailing 7 or 30 days, shares still held, explicit timestamps, or lifetime history.'), z.meta({ examples: ['lifetime'] }));
483
+ const earningsWindow = z.extend(earningsBase, {
484
+ end: z.iso
485
+ .datetime()
486
+ .check(z.describe('UTC ending boundary. Includes activity through the latest indexed block at or before this timestamp.'), z.meta({ examples: ['2026-09-18T00:00:00.000Z'] })),
487
+ period: z
488
+ .enum(['7d', '30d', 'custom'])
489
+ .check(z.describe('Rolling or explicitly bounded earnings window.'), z.meta({ examples: ['7d'] })),
490
+ start: z.iso
491
+ .datetime()
492
+ .check(z.describe('UTC opening boundary. Excludes activity through the latest indexed block at or before this timestamp.'), z.meta({ examples: ['2026-09-11T00:00:00.000Z'] })),
493
+ });
477
494
  const earnings = z.union([
478
495
  z.extend(earningsBase, {
479
496
  lifetimeEarnings: z
480
497
  .string()
481
- .check(z.regex(/^-?\d+$/), z.describe('Current share value plus completed redemptions, exact withdrawals, and finalized async assets, minus asset deposits, at the latest indexed block.'), z.meta({ examples: ['0'] })),
498
+ .check(z.regex(/^-?\d+$/), z.describe('Current share value plus withdrawals, including outgoing shares valued when transferred, minus asset deposits, at the latest indexed block.'), z.meta({ examples: ['0'] })),
482
499
  totalDeposited: Schema.DecimalString.check(z.describe('Assets deposited with this account as receiver over complete indexed vault history.'), z.meta({ examples: ['1000000'] })),
483
- totalWithdrawn: Schema.DecimalString.check(z.describe('Assets returned by completed redemptions and exact withdrawals initiated by this account over complete indexed vault history.'), z.meta({ examples: ['1000000'] })),
500
+ totalWithdrawn: Schema.DecimalString.check(z.describe('Completed vault withdrawal proceeds plus other outgoing shares valued at their transfer blocks, regardless of recipient or spender.'), z.meta({ examples: ['1000000'] })),
484
501
  period: z
485
502
  .literal('lifetime')
486
503
  .check(z.describe('Returns lifetime net asset earnings.'), z.meta({ examples: ['lifetime'] })),
@@ -499,27 +516,28 @@ export var schema;
499
516
  .literal('complete')
500
517
  .check(z.describe('Earnings include a complete asset-denominated cost basis.'), z.meta({ examples: ['complete'] })),
501
518
  }),
502
- z.extend(earningsBase, {
503
- period: z
504
- .literal('30d')
505
- .check(z.describe('Returns cash-flow-adjusted earnings over the trailing 30 days.'), z.meta({ examples: ['30d'] })),
519
+ z.extend(earningsWindow, {
506
520
  status: z
507
521
  .literal('complete')
508
522
  .check(z.describe('Earnings include a complete asset-denominated cost basis.'), z.meta({ examples: ['complete'] })),
509
523
  windowEarnings: z
510
524
  .string()
511
- .check(z.regex(/^-?\d+$/), z.describe('Ending share value plus realized assets, minus deposits and opening share value, over the trailing 30 days.'), z.meta({ examples: ['0'] })),
525
+ .check(z.regex(/^-?\d+$/), z.describe('Ending share value plus withdrawals, including outgoing shares valued when transferred, minus deposits and opening share value, over the requested window.'), z.meta({ examples: ['0'] })),
512
526
  }),
513
527
  z.extend(earningsBase, {
514
- period: earningsPeriod,
528
+ period: z
529
+ .enum(['active', 'lifetime'])
530
+ .check(z.describe('Earnings period with unavailable cost basis.'), z.meta({ examples: ['lifetime'] })),
515
531
  status: z
516
532
  .literal('incomplete_cost_basis')
517
533
  .check(z.describe('Earnings are unavailable when indexed activity cannot reconstruct the asset cost basis for the requested period.'), z.meta({ examples: ['incomplete_cost_basis'] })),
518
534
  }),
519
- z.extend(earningsBase, {
520
- period: z
521
- .literal('30d')
522
- .check(z.describe('Trailing period with an unresolved async redemption.'), z.meta({ examples: ['30d'] })),
535
+ z.extend(earningsWindow, {
536
+ status: z
537
+ .literal('incomplete_cost_basis')
538
+ .check(z.describe('Indexed activity cannot reconstruct the requested window’s asset cost basis.'), z.meta({ examples: ['incomplete_cost_basis'] })),
539
+ }),
540
+ z.extend(earningsWindow, {
523
541
  status: z
524
542
  .literal('pending_redemption')
525
543
  .check(z.describe('Earnings are unavailable while an async redemption remains open.'), z.meta({ examples: ['pending_redemption'] })),
@@ -805,12 +823,25 @@ export var schema;
805
823
  vaultId: Schema.address('0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a').check(z.describe('Earn vault contract address.')),
806
824
  })
807
825
  .check(z.describe('Path parameters identifying an earn vault account.'));
808
- /** Query parameters selecting the chain containing the vault. */
826
+ /** Query parameters selecting the chain and earnings interval. */
809
827
  getEarnVaultEarnings.Query = z
810
828
  .strictObject({
811
829
  chainId: Schema.ChainIdQuery,
830
+ end: z
831
+ .optional(z.iso.datetime({ offset: true }))
832
+ .check(z.describe('Required with period=custom. Inclusive ISO 8601 ending timestamp; indexed history must cover this time.'), z.meta({ examples: ['2026-09-18T00:00:00.000Z'] })),
812
833
  period: z._default(earningsPeriod, 'lifetime'),
834
+ start: z
835
+ .optional(z.iso.datetime({ offset: true }))
836
+ .check(z.describe('Required with period=custom. Exclusive ISO 8601 opening timestamp, earlier than end.'), z.meta({ examples: ['2026-09-11T00:00:00.000Z'] })),
813
837
  })
838
+ .check(z.refine((value) => value.period === 'custom'
839
+ ? value.start !== undefined &&
840
+ value.end !== undefined &&
841
+ Date.parse(value.start) < Date.parse(value.end)
842
+ : value.start === undefined && value.end === undefined, {
843
+ message: 'Only period=custom accepts start and end; both are required and start must be earlier than end',
844
+ }))
814
845
  .check(z.describe('Query parameters selecting an earn vault account.'));
815
846
  /** Earnings for one account and period in one Earn vault. */
816
847
  getEarnVaultEarnings.Response = OpenApi.component(Schema.describe(earnings, 'Indexed asset value and cost-basis-aware earnings for an account in one earn vault.'), 'EarnVaultEarnings');
@@ -820,7 +851,7 @@ export var schema;
820
851
  export function earn(options = {}) {
821
852
  const oracle = options.fx?.oracle ?? FxOracle.ecb();
822
853
  return new Hono()
823
- .post('/v1/earn/rewards/eligibility', Auth.policy({ apiKey: { scopes: [Scope.wildcard] } }), OpenApi.validate('json', schema.registerRewardEligibility.Body, {
854
+ .post('/v1/earn/rewards/eligibility', Auth.policy({ apiKey: { scopes: ['rewards:write'] } }), OpenApi.validate('json', schema.registerRewardEligibility.Body, {
824
855
  code: 'body_invalid',
825
856
  message: 'Invalid reward eligibility registration',
826
857
  }), OpenApi.describeRoute({
@@ -850,6 +881,21 @@ export function earn(options = {}) {
850
881
  if (!c.get('supportedChainIds').has(body.chainId))
851
882
  return Response.unsupportedChainId(c, body.chainId, c.get('supportedChainIds'));
852
883
  c.set('chainId', body.chainId);
884
+ if (c.get('zones').has(body.chainId))
885
+ return Response.error(c, {
886
+ code: 'chain_id_unsupported',
887
+ message: `Zone chain ID ${body.chainId} is not supported for rewards registration.`,
888
+ status: 400,
889
+ });
890
+ const principal = Auth.getPrincipal(c);
891
+ if (principal?.type === 'api_key' &&
892
+ principal.environment === 'sandbox' &&
893
+ Viem.isMainnet(body.chainId))
894
+ return Response.error(c, {
895
+ code: 'api_key_forbidden',
896
+ message: 'Sandbox API keys only support testnet.',
897
+ status: 403,
898
+ });
853
899
  c.header('Cache-Control', Cache.policies.noStore);
854
900
  const result = await RewardEligibilityAssociations.upsert(Db.get(c.get('db')), {
855
901
  ...body,
@@ -1263,21 +1309,24 @@ export function earn(options = {}) {
1263
1309
  if (c.get('zones').has(chainId))
1264
1310
  Cache.setPolicy(c, Cache.policies.noStore);
1265
1311
  try {
1266
- const position = await getVaultPosition(c, {
1312
+ const position_pending = Timing.time(c, 'earn_position', () => getVaultPosition(c, {
1267
1313
  account: address,
1268
1314
  asOf: query.asOf,
1269
1315
  chainId,
1270
1316
  vault: vaultId,
1271
- });
1272
- const apy = query.include.includes('apy')
1273
- ? await resolvePositionApy(c, {
1317
+ }));
1318
+ // Rate and vault reads depend only on the vault, so they overlap the
1319
+ // position's chained RPC hops instead of queueing behind them.
1320
+ const apy_pending = query.include.includes('apy')
1321
+ ? resolvePositionApy(c, {
1274
1322
  chainId,
1323
+ position: position_pending,
1275
1324
  recipient: address,
1276
- shareBalance: position.shareBalance,
1277
- value: position.value,
1278
1325
  vault: vaultId,
1279
1326
  })
1280
1327
  : undefined;
1328
+ const position = await position_pending;
1329
+ const apy = await apy_pending;
1281
1330
  const rewards = query.include.some((value) => value.startsWith('rewards'))
1282
1331
  ? await RewardRead.recipient({
1283
1332
  chainId,
@@ -1297,6 +1346,12 @@ export function earn(options = {}) {
1297
1346
  asOf: query.asOf,
1298
1347
  block: position.block,
1299
1348
  id: address,
1349
+ ...(position.privateAssetBalance === undefined
1350
+ ? {}
1351
+ : { privateAssetBalance: position.privateAssetBalance.toString() }),
1352
+ ...(position.privateAssetToken === undefined
1353
+ ? {}
1354
+ : { privateAssetToken: position.privateAssetToken }),
1300
1355
  ...(rewards
1301
1356
  ? {
1302
1357
  rewards: query.include.includes('rewards.proof')
@@ -1391,7 +1446,7 @@ export function earn(options = {}) {
1391
1446
  code: 'query_invalid',
1392
1447
  message: 'Invalid query parameters',
1393
1448
  }), OpenApi.describeRoute({
1394
- description: 'Gets an account’s indexed asset value and earnings for lifetime history, the trailing 30 days, or shares still held.',
1449
+ description: 'Gets an account’s asset value and earnings for lifetime history, shares still held, or a rolling or custom time window.',
1395
1450
  operationId: 'getEarnVaultEarnings',
1396
1451
  responses: OpenApi.responses({
1397
1452
  errors: {
@@ -1419,7 +1474,7 @@ export function earn(options = {}) {
1419
1474
  }), Cache.response({
1420
1475
  cacheControl: Cache.policies.state,
1421
1476
  key: (c) => Cache.urlKey(c, schema.getEarnVaultEarnings.Query),
1422
- name: 'tempo-api:earn-vault-earnings:v4',
1477
+ name: 'tempo-api:earn-vault-earnings:v5',
1423
1478
  }), async (c) => {
1424
1479
  if (Auth.narrowAccess)
1425
1480
  return Auth.paidAccessError(c);
@@ -1450,14 +1505,16 @@ export function earn(options = {}) {
1450
1505
  const chainId = query.chainId ?? c.get('chainId');
1451
1506
  try {
1452
1507
  const data = await getVaultEarnings(c, {
1508
+ ...query,
1453
1509
  account: address,
1454
1510
  chainId,
1455
- period: query.period,
1456
1511
  vault: vaultId,
1457
1512
  });
1458
1513
  return c.json(Response.validated(schema.getEarnVaultEarnings.Response, data), 200);
1459
1514
  }
1460
1515
  catch (cause) {
1516
+ if (cause instanceof IndexedBlockNotFoundError || cause instanceof IndexedCoverageError)
1517
+ return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 });
1461
1518
  try {
1462
1519
  await resolveVaultDiscovery(c, { chainId, include: [], vaultAddress: vaultId });
1463
1520
  }
@@ -1561,19 +1618,24 @@ export function earn(options = {}) {
1561
1618
  export async function getVaultEarnings(c, options) {
1562
1619
  const client = c.get('getClient')(options.chainId);
1563
1620
  const tidx = c.get('getTidx')(options.chainId);
1564
- const [block, rewardTransfer] = await Promise.all([
1565
- getLatestIndexedBlock(tidx),
1566
- getRewardTransferPredicate(c, options),
1621
+ const [block, earnings] = await Promise.all([
1622
+ options.period === 'custom'
1623
+ ? getIndexedBlockAtOrBefore(tidx, options.end)
1624
+ : getLatestIndexedBlock(tidx),
1625
+ getEarningsConfiguration(c, options),
1567
1626
  ]);
1568
1627
  const blockNumber = block.number;
1569
- if (options.period === '30d')
1628
+ if (options.period === '7d' || options.period === '30d' || options.period === 'custom')
1570
1629
  return getWindowVaultEarnings(c, {
1571
1630
  account: options.account,
1572
1631
  blockNumber,
1573
1632
  chainId: options.chainId,
1633
+ earnings,
1634
+ end: options.period === 'custom' ? new Date(options.end).toISOString() : block.timestamp,
1574
1635
  period: options.period,
1575
- rewardTransfer,
1576
- timestamp: block.timestamp,
1636
+ start: options.period === 'custom'
1637
+ ? new Date(options.start).toISOString()
1638
+ : new Date(Date.parse(block.timestamp) - Ttl.days(options.period === '7d' ? 7 : 30)).toISOString(),
1577
1639
  vault: options.vault,
1578
1640
  });
1579
1641
  const position = client.earn.getPosition({
@@ -1593,7 +1655,7 @@ export async function getVaultEarnings(c, options) {
1593
1655
  const activeCostBasis = await getActiveCostBasis(tidx, {
1594
1656
  account: options.account,
1595
1657
  blockNumber,
1596
- rewardTransfer,
1658
+ rewardTransfer: getRewardTransferPredicate(current.shareToken, earnings.rewardDistributors),
1597
1659
  shareBalance: current.shareBalance,
1598
1660
  shareToken: current.shareToken,
1599
1661
  vault: options.vault,
@@ -1615,10 +1677,11 @@ export async function getVaultEarnings(c, options) {
1615
1677
  }),
1616
1678
  position,
1617
1679
  ]);
1618
- const externalShareTransfer = await hasExternalShareTransfer(tidx, {
1680
+ const transfers = await getShareTransferState(tidx, {
1619
1681
  account: options.account,
1620
1682
  blockNumber,
1621
- rewardTransfer,
1683
+ client,
1684
+ rewardTransfer: getRewardTransferPredicate(current.shareToken, earnings.rewardDistributors),
1622
1685
  shareToken: current.shareToken,
1623
1686
  startBlockNumber: beforeFirstBlockNumber,
1624
1687
  vault: options.vault,
@@ -1630,9 +1693,9 @@ export async function getVaultEarnings(c, options) {
1630
1693
  id: options.account,
1631
1694
  period: options.period,
1632
1695
  };
1633
- if (history.incompleteCostBasis || externalShareTransfer)
1696
+ if (history.incompleteCostBasis || transfers.external || transfers.withdrawn === undefined)
1634
1697
  return { ...base, status: 'incomplete_cost_basis' };
1635
- const totalWithdrawn = history.redeemed + history.withdrewExact + history.finalized;
1698
+ const totalWithdrawn = history.redeemed + history.withdrewExact + history.finalized + transfers.withdrawn;
1636
1699
  const cashFlows = {
1637
1700
  totalDeposited: history.deposited.toString(),
1638
1701
  totalWithdrawn: totalWithdrawn.toString(),
@@ -1647,7 +1710,7 @@ export async function getVaultEarnings(c, options) {
1647
1710
  status: 'complete',
1648
1711
  };
1649
1712
  }
1650
- /** Reads cash-flow-adjusted earnings over a trailing indexed window. */
1713
+ /** Reads cash-flow-adjusted earnings over an indexed time window. */
1651
1714
  async function getWindowVaultEarnings(c, options) {
1652
1715
  const client = c.get('getClient')(options.chainId);
1653
1716
  const tidx = c.get('getTidx')(options.chainId);
@@ -1657,13 +1720,16 @@ async function getWindowVaultEarnings(c, options) {
1657
1720
  blockNumber: BigInt(options.blockNumber),
1658
1721
  vault: options.vault,
1659
1722
  }),
1660
- getWindowStartBlockNumber(tidx, { days: 30, timestamp: options.timestamp }),
1723
+ options.period === 'custom'
1724
+ ? getIndexedBlockAtOrBefore(tidx, options.start).then((block) => block.number)
1725
+ : getWindowStartBlockNumber(tidx, { timestamp: options.start }),
1661
1726
  ]);
1662
- const [externalShareTransfer, history, opening] = await Promise.all([
1663
- hasExternalShareTransfer(tidx, {
1727
+ const [transfers, history, opening] = await Promise.all([
1728
+ getShareTransferState(tidx, {
1664
1729
  account: options.account,
1665
1730
  blockNumber: options.blockNumber,
1666
- rewardTransfer: options.rewardTransfer,
1731
+ client,
1732
+ rewardTransfer: getRewardTransferPredicate(current.shareToken, options.earnings.rewardDistributors),
1667
1733
  shareToken: current.shareToken,
1668
1734
  startBlockNumber,
1669
1735
  vault: options.vault,
@@ -1686,11 +1752,14 @@ async function getWindowVaultEarnings(c, options) {
1686
1752
  account: options.account,
1687
1753
  assetToken: current.assetToken,
1688
1754
  currentValue: current.value.toString(),
1755
+ end: options.end,
1689
1756
  id: options.account,
1690
1757
  period: options.period,
1758
+ start: options.start,
1691
1759
  };
1692
1760
  if (opening === undefined ||
1693
- externalShareTransfer ||
1761
+ transfers.external ||
1762
+ transfers.withdrawn === undefined ||
1694
1763
  history.incompleteCostBasis ||
1695
1764
  opening.crossBoundaryRedemption ||
1696
1765
  opening.endShares !== current.shareBalance)
@@ -1710,7 +1779,7 @@ async function getWindowVaultEarnings(c, options) {
1710
1779
  finalized: history.finalized,
1711
1780
  openingValue,
1712
1781
  redeemed: history.redeemed,
1713
- withdrewExact: history.withdrewExact,
1782
+ withdrewExact: history.withdrewExact + transfers.withdrawn,
1714
1783
  });
1715
1784
  return { ...base, status: 'complete', windowEarnings: windowEarnings.toString() };
1716
1785
  }
@@ -1782,9 +1851,9 @@ export function parseIndexedBlockAtOrBefore(options) {
1782
1851
  throw new IndexedCoverageError(options.asOf);
1783
1852
  return { number, timestamp: indexedAt };
1784
1853
  }
1785
- /** Resolves the last indexed block at or before a trailing-day boundary. */
1854
+ /** Resolves a rolling boundary, allowing windows that start before the chain existed. */
1786
1855
  async function getWindowStartBlockNumber(tidx, options) {
1787
- const cutoff = new Date(Date.parse(options.timestamp) - Ttl.days(options.days)).toISOString();
1856
+ const cutoff = options.timestamp;
1788
1857
  const result = await tidx.fetch({
1789
1858
  query: `SELECT num FROM blocks WHERE timestamp <= '${cutoff}' ORDER BY num DESC LIMIT 1`,
1790
1859
  });
@@ -2001,29 +2070,37 @@ async function getWindowShareState(tidx, options) {
2001
2070
  startShares: receivedStartValue - sentStartValue,
2002
2071
  };
2003
2072
  }
2004
- /** Builds a share-transfer predicate for the vault's verified reward distributors. */
2005
- async function getRewardTransferPredicate(c, options) {
2073
+ /** Combines recorded campaign distributors with additional per-vault reward distributors. */
2074
+ async function getEarningsConfiguration(c, options) {
2006
2075
  const db = Db.get(c.get('db'));
2007
- const campaign = await RewardCampaigns.get(db, {
2076
+ const record = await core_EarnVaults.get(db, {
2008
2077
  chainId: options.chainId,
2009
2078
  vaultAddress: options.vault,
2010
2079
  });
2011
- if (!campaign)
2012
- return '0';
2013
2080
  const distributors = await RewardCampaignDistributors.list(db, {
2014
2081
  chainId: options.chainId,
2015
2082
  vaultAddress: options.vault,
2016
2083
  });
2084
+ return {
2085
+ rewardDistributors: [
2086
+ ...new Set([
2087
+ ...distributors.map(({ distributorAddress }) => distributorAddress),
2088
+ ...(record?.earnings?.rewardDistributors ?? []),
2089
+ ]),
2090
+ ],
2091
+ };
2092
+ }
2093
+ /** Builds a share-transfer predicate scoped to this vault's share token and configured distributors. */
2094
+ function getRewardTransferPredicate(shareToken, distributors) {
2017
2095
  if (distributors.length === 0)
2018
2096
  return '0';
2019
2097
  const addresses = distributors
2020
- .map(({ distributorAddress }) => Schema.Address.parse(distributorAddress))
2098
+ .map((address) => Schema.Address.parse(address))
2021
2099
  .map((address) => `'${address}'`)
2022
2100
  .join(', ');
2023
- const shareToken = Schema.Address.parse(campaign.earnShareAddress);
2024
2101
  // Batch rewards have no per-recipient event; exclude treasury returns instead. Qualify the filter so TIDX does not apply it to other event CTEs.
2025
2102
  return `
2026
- token = '${shareToken}'
2103
+ token = '${shareToken.toLowerCase()}'
2027
2104
  AND "from" IN (${addresses})
2028
2105
  AND tx_hash NOT IN (
2029
2106
  SELECT returned.tx_hash FROM UnspentReturned AS returned
@@ -2031,9 +2108,10 @@ async function getRewardTransferPredicate(c, options) {
2031
2108
  )
2032
2109
  `;
2033
2110
  }
2034
- /** Returns whether an account sent or received Earn shares outside known vault flows. */
2035
- async function hasExternalShareTransfer(tidx, options) {
2036
- // Vault exits pull shares into the vault before burning. Reconcile counts by transaction and amount so unmatched direct sends remain external.
2111
+ /** Reads unknown incoming shares and recipient-independent outgoing share values. */
2112
+ async function getShareTransferState(tidx, options) {
2113
+ const withdrawals = await EarnWithdrawals.read(tidx, options);
2114
+ // Incoming rewards and cancelled requests are known; other receipts still lack deposit basis.
2037
2115
  const result = await tidx.fetch({
2038
2116
  engine: 'clickhouse',
2039
2117
  query: `
@@ -2045,56 +2123,11 @@ async function hasExternalShareTransfer(tidx, options) {
2045
2123
  AND toUInt256(amount) > 0
2046
2124
  AND block_num > ${options.startBlockNumber}
2047
2125
  AND block_num <= ${options.blockNumber}
2048
- AND (
2049
- ("from" = '${options.account}' AND "to" != '${options.vault}')
2050
- OR (
2051
- "to" = '${options.account}'
2052
- AND "from" != '${zeroAddress}'
2053
- AND "from" != '${options.vault}'
2054
- AND NOT (${options.rewardTransfer})
2055
- )
2056
- )
2057
- ) + (
2058
- SELECT count()
2059
- FROM (
2060
- SELECT tx_hash, toUInt256(amount) AS amount, count() AS transfer_count
2061
- FROM token_transfers
2062
- WHERE token = '${options.shareToken.toLowerCase()}'
2063
- AND toUInt256(amount) > 0
2064
- AND "from" = '${options.account}'
2065
- AND "to" = '${options.vault}'
2066
- AND block_num > ${options.startBlockNumber}
2067
- AND block_num <= ${options.blockNumber}
2068
- GROUP BY tx_hash, amount
2069
- ) AS candidate
2070
- LEFT JOIN (
2071
- SELECT tx_hash, amount, count() AS exit_count
2072
- FROM (
2073
- SELECT tx_hash, toUInt256(earnShares) AS amount
2074
- FROM Redeemed
2075
- WHERE address = '${options.vault}'
2076
- AND caller = '${options.account}'
2077
- AND block_num > ${options.startBlockNumber}
2078
- AND block_num <= ${options.blockNumber}
2079
- UNION ALL
2080
- SELECT tx_hash, toUInt256(earnShares) AS amount
2081
- FROM RedeemRequested
2082
- WHERE address = '${options.vault}'
2083
- AND requester = '${options.account}'
2084
- AND block_num > ${options.startBlockNumber}
2085
- AND block_num <= ${options.blockNumber}
2086
- UNION ALL
2087
- SELECT tx_hash, toUInt256(earnSharesBurned) AS amount
2088
- FROM WithdrewExact
2089
- WHERE address = '${options.vault}'
2090
- AND caller = '${options.account}'
2091
- AND block_num > ${options.startBlockNumber}
2092
- AND block_num <= ${options.blockNumber}
2093
- ) AS protocol_exit
2094
- GROUP BY tx_hash, amount
2095
- ) AS matched
2096
- ON matched.tx_hash = candidate.tx_hash AND matched.amount = candidate.amount
2097
- WHERE candidate.transfer_count > coalesce(matched.exit_count, 0)
2126
+ AND "to" = '${options.account}'
2127
+ AND "from" != '${options.account}'
2128
+ AND "from" != '${zeroAddress}'
2129
+ AND "from" != '${options.vault}'
2130
+ AND NOT (${options.rewardTransfer})
2098
2131
  ) + (
2099
2132
  SELECT count()
2100
2133
  FROM (
@@ -2132,7 +2165,12 @@ async function hasExternalShareTransfer(tidx, options) {
2132
2165
  const count = Value.toNumber(result.rows[0]?.['count']);
2133
2166
  if (count === undefined)
2134
2167
  throw new Error('TIDX returned an invalid Earn-share transfer count.');
2135
- return count > 0;
2168
+ return {
2169
+ external: count > 0,
2170
+ withdrawn: count > 0
2171
+ ? undefined
2172
+ : await EarnWithdrawals.value(options.client, { vault: options.vault, withdrawals }),
2173
+ };
2136
2174
  }
2137
2175
  /** Calculates the asset cost basis attached to an account's remaining Earn shares. */
2138
2176
  export function calculateActiveCostBasis(options) {
@@ -2190,6 +2228,13 @@ export function calculateActiveCostBasis(options) {
2190
2228
  }
2191
2229
  /** Reads the active asset cost basis for shares held at one indexed block. */
2192
2230
  async function getActiveCostBasis(tidx, options) {
2231
+ const withdrawals = await EarnWithdrawals.read(tidx, {
2232
+ ...options,
2233
+ startBlockNumber: beforeFirstBlockNumber,
2234
+ });
2235
+ const outgoing = withdrawals.length === 0
2236
+ ? '0'
2237
+ : `(tx_hash, log_idx) IN (${withdrawals.map(({ transactionHash, logIndex }) => `('${transactionHash}', ${logIndex})`).join(', ')})`;
2193
2238
  const result = await tidx.fetch({
2194
2239
  engine: 'clickhouse',
2195
2240
  query: `
@@ -2285,6 +2330,7 @@ async function getActiveCostBasis(tidx, options) {
2285
2330
  AND "to" = '${options.account}'
2286
2331
  AND "from" != '${zeroAddress}'
2287
2332
  AND "from" != '${options.vault}'
2333
+ AND "from" != '${options.account}'
2288
2334
  AND block_num <= ${options.blockNumber}
2289
2335
  UNION ALL
2290
2336
  SELECT
@@ -2298,7 +2344,7 @@ async function getActiveCostBasis(tidx, options) {
2298
2344
  WHERE token = '${options.shareToken.toLowerCase()}'
2299
2345
  AND toUInt256(amount) > 0
2300
2346
  AND "from" = '${options.account}'
2301
- AND "to" != '${options.vault}'
2347
+ AND (${outgoing})
2302
2348
  AND block_num <= ${options.blockNumber}
2303
2349
  ) AS actions
2304
2350
  ORDER BY block_num, log_idx
@@ -2630,19 +2676,55 @@ async function resolveSharePriceVaultDiscovery(c, options) {
2630
2676
  export async function getVaultPosition(c, options) {
2631
2677
  const zone = c.get('zones').get(options.chainId);
2632
2678
  if (!zone) {
2633
- const block = options.asOf === undefined
2634
- ? undefined
2635
- : await getIndexedBlockAtOrBefore(c.get('getTidx')(options.chainId), options.asOf);
2679
+ if (options.asOf === undefined)
2680
+ return readLivePosition(c, options);
2681
+ const block = await getIndexedBlockAtOrBefore(c.get('getTidx')(options.chainId), options.asOf);
2636
2682
  const position = await c
2637
2683
  .get('getClient')(options.chainId)
2638
2684
  .earn.getPosition({
2639
2685
  account: options.account,
2640
- ...(block ? { blockNumber: BigInt(block.number) } : {}),
2686
+ blockNumber: BigInt(block.number),
2641
2687
  vault: options.vault,
2642
2688
  });
2643
2689
  return { ...position, block, valueToken: position.assetToken };
2644
2690
  }
2645
- const route = await resolveZonePositionRoute(c, {
2691
+ const { blockNumber, discovery, position, sourceBlock } = await getZoneVaultPositionCore(c, options);
2692
+ const privateAsset = await resolveZonePositionPrivateAsset(c, {
2693
+ chainId: options.chainId,
2694
+ discovery,
2695
+ vault: options.vault,
2696
+ }).catch((cause) => {
2697
+ recordZonePositionEnrichmentFailure(c, {
2698
+ cause,
2699
+ chainId: discovery.chainId,
2700
+ operation: 'resolvePrivateAsset',
2701
+ });
2702
+ return undefined;
2703
+ });
2704
+ const privateAssetBalance = privateAsset && sourceBlock >= privateAsset.deploymentBlock
2705
+ ? await readZoneBalance(c.get('getClient')(options.chainId), {
2706
+ account: options.account,
2707
+ blockNumber,
2708
+ token: privateAsset.token,
2709
+ }).catch((cause) => {
2710
+ recordZonePositionEnrichmentFailure(c, {
2711
+ cause,
2712
+ chainId: options.chainId,
2713
+ operation: 'eth_call',
2714
+ });
2715
+ return undefined;
2716
+ })
2717
+ : undefined;
2718
+ return {
2719
+ ...position,
2720
+ ...(privateAssetBalance === undefined || privateAsset === undefined
2721
+ ? {}
2722
+ : { privateAssetBalance, privateAssetToken: privateAsset.token }),
2723
+ };
2724
+ }
2725
+ /** Reads the on-chain Zone position without optional private-route enrichment. */
2726
+ async function getZoneVaultPositionCore(c, options) {
2727
+ const core = await resolveZonePositionCore(c, {
2646
2728
  chainId: options.chainId,
2647
2729
  vault: options.vault,
2648
2730
  });
@@ -2655,43 +2737,130 @@ export async function getVaultPosition(c, options) {
2655
2737
  readZoneBalance(zoneClient, {
2656
2738
  account: options.account,
2657
2739
  blockNumber,
2658
- token: route.privateAsset,
2740
+ token: core.vaultAsset,
2741
+ }).catch(async (cause) => {
2742
+ // The public vault asset may not be deployed on the private Zone.
2743
+ if (cause instanceof ContractFunctionExecutionError &&
2744
+ cause.walk((error) => error instanceof ContractFunctionZeroDataError))
2745
+ return 0n;
2746
+ const code = await zoneClient.getCode({ address: core.vaultAsset, blockNumber });
2747
+ if (!code || code === '0x')
2748
+ return 0n;
2749
+ throw cause;
2659
2750
  }),
2660
2751
  readZoneBalance(zoneClient, {
2661
2752
  account: options.account,
2662
2753
  blockNumber,
2663
- token: route.shareToken,
2754
+ token: core.shareToken,
2755
+ }).catch(async (cause) => {
2756
+ if (cause instanceof ContractFunctionExecutionError &&
2757
+ cause.walk((error) => error instanceof ContractFunctionZeroDataError))
2758
+ throw new EarnVaults.NotFoundError();
2759
+ const code = await zoneClient.getCode({ address: core.shareToken, blockNumber });
2760
+ if (!code || code === '0x')
2761
+ throw new EarnVaults.NotFoundError();
2762
+ throw cause;
2664
2763
  }),
2665
2764
  readZoneSourceBlock(c, {
2666
2765
  blockNumber,
2667
2766
  historical: block !== undefined,
2668
- portal: route.portal,
2669
- sourceChainId: route.sourceChainId,
2767
+ portal: core.portal,
2768
+ sourceChainId: core.sourceChainId,
2670
2769
  zoneClient,
2671
2770
  }),
2672
2771
  ]);
2673
2772
  const sourceBlock = Value.toNumber(importedParentBlockNumber);
2674
- if (sourceBlock === undefined || sourceBlock < route.deploymentBlock)
2773
+ if (sourceBlock === undefined)
2675
2774
  throw new EarnVaults.NotFoundError();
2676
- const value = await c
2677
- .get('getClient')(route.sourceChainId)
2678
- .earn.getRedeemQuote({
2775
+ const value = await quoteZonePosition(c.get('getClient')(core.sourceChainId), {
2679
2776
  blockNumber: BigInt(sourceBlock),
2680
2777
  shareAmount: shareBalance,
2681
2778
  vault: options.vault,
2682
2779
  });
2683
2780
  return {
2684
- assetAllowance: 0n,
2781
+ blockNumber,
2782
+ discovery: core.discovery,
2783
+ position: {
2784
+ assetAllowance: 0n,
2785
+ assetBalance,
2786
+ assetToken: core.vaultAsset,
2787
+ block,
2788
+ shareAllowance: 0n,
2789
+ shareBalance,
2790
+ shareToken: core.shareToken,
2791
+ value,
2792
+ valueToken: core.vaultAsset,
2793
+ },
2794
+ sourceBlock,
2795
+ };
2796
+ }
2797
+ /** Quotes Zone shares only after the verified parent block contains the vault. */
2798
+ export async function quoteZonePosition(client, options) {
2799
+ const code = await client.getCode({ address: options.vault, blockNumber: options.blockNumber });
2800
+ if (!code || code === '0x')
2801
+ throw new EarnVaults.NotFoundError();
2802
+ return client.earn.getRedeemQuote(options);
2803
+ }
2804
+ /**
2805
+ * Reads a live direct-chain position in two RPC hops by caching the vault's
2806
+ * immutable token bindings, which otherwise cost a hop on every request.
2807
+ */
2808
+ async function readLivePosition(c, options) {
2809
+ const client = c.get('getClient')(options.chainId);
2810
+ const { asset, shareToken } = await resolveVaultBindings(c, options);
2811
+ const [assetAllowance, assetBalance, shareAllowance, shareBalance] = await client.multicall({
2812
+ allowFailure: false,
2813
+ contracts: [
2814
+ {
2815
+ abi: Abis.tip20,
2816
+ address: asset,
2817
+ args: [options.account, options.vault],
2818
+ functionName: 'allowance',
2819
+ },
2820
+ { abi: Abis.tip20, address: asset, args: [options.account], functionName: 'balanceOf' },
2821
+ {
2822
+ abi: Abis.tip20,
2823
+ address: shareToken,
2824
+ args: [options.account, options.vault],
2825
+ functionName: 'allowance',
2826
+ },
2827
+ { abi: Abis.tip20, address: shareToken, args: [options.account], functionName: 'balanceOf' },
2828
+ ],
2829
+ });
2830
+ const value = await client.earn.getRedeemQuote({
2831
+ shareAmount: shareBalance,
2832
+ vault: options.vault,
2833
+ });
2834
+ return {
2835
+ assetAllowance,
2685
2836
  assetBalance,
2686
- assetToken: route.privateAsset,
2687
- block,
2688
- shareAllowance: 0n,
2837
+ assetToken: asset,
2838
+ shareAllowance,
2689
2839
  shareBalance,
2690
- shareToken: route.shareToken,
2840
+ shareToken,
2691
2841
  value,
2692
- valueToken: route.vaultAsset,
2842
+ valueToken: asset,
2693
2843
  };
2694
2844
  }
2845
+ /** Resolves a vault's asset and EarnShare addresses, cached because they never change after deployment. */
2846
+ async function resolveVaultBindings(c, options) {
2847
+ return Store.memoize(async () => {
2848
+ const [asset, shareToken] = await c
2849
+ .get('getClient')(options.chainId)
2850
+ .multicall({
2851
+ allowFailure: false,
2852
+ contracts: [
2853
+ { abi: Abis.earnVault, address: options.vault, functionName: 'asset' },
2854
+ { abi: Abis.earnVault, address: options.vault, functionName: 'earnShare' },
2855
+ ],
2856
+ });
2857
+ return { asset, shareToken };
2858
+ }, {
2859
+ key: `earn-vault-bindings:v1:${options.chainId}:${options.vault.toLowerCase()}`,
2860
+ store: c.get('store'),
2861
+ ttl: Ttl.hours(1),
2862
+ });
2863
+ }
2695
2864
  /** Reads a private Zone token balance with the holder as the authorized RPC caller. */
2696
2865
  async function readZoneBalance(client, options) {
2697
2866
  return client.readContract({
@@ -2739,46 +2908,66 @@ export function alignZoneSourceBlock(options) {
2739
2908
  return options.verified;
2740
2909
  return options.reported;
2741
2910
  }
2742
- /** Resolves the verified parent vault and token pair for one Zone route. */
2743
- async function resolveZonePositionRoute(c, options) {
2911
+ /** Resolves the public parent vault and Zone checkpoint boundary. */
2912
+ async function resolveZonePositionCore(c, options) {
2744
2913
  const zone = c.get('zones').get(options.chainId);
2745
2914
  if (!zone?.sourceId)
2746
2915
  throw new EarnVaults.NotFoundError();
2747
- const db = Db.get(c.get('dbCached'));
2748
- const record = await core_EarnVaults.get(db, {
2749
- chainId: zone.sourceId,
2750
- vaultAddress: options.vault,
2751
- });
2752
- const configured = record?.zones.find((route) => route.chainId === options.chainId);
2753
- if (!record || !configured)
2754
- throw new EarnVaults.NotFoundError();
2755
2916
  const discovery = await resolveVaultDiscovery(c, {
2756
2917
  chainId: zone.sourceId,
2757
2918
  include: [],
2758
2919
  vaultAddress: options.vault,
2920
+ }).catch((cause) => {
2921
+ if (isIncompatible(cause))
2922
+ throw new EarnVaults.NotFoundError();
2923
+ throw cause;
2759
2924
  });
2760
- const [route] = await EarnVaults.resolveZoneRoutes({
2761
- discovery,
2762
- getClient: c.get('getClient'),
2763
- routes: [configured],
2764
- zones: [...c.get('zones').values()],
2765
- });
2766
- const privateAsset = route?.inputTokens[0];
2767
2925
  const portalContract = zone.contracts?.['portal'];
2768
2926
  const portal = Schema.Address.safeParse(portalContract && 'address' in portalContract
2769
2927
  ? portalContract.address
2770
2928
  : portalContract?.[zone.sourceId]?.address);
2771
- if (!route || !privateAsset || !portal.success)
2929
+ if (!portal.success)
2772
2930
  throw new EarnVaults.NotFoundError();
2773
2931
  return {
2774
- deploymentBlock: route.deploymentBlock,
2932
+ discovery,
2775
2933
  portal: portal.data,
2776
- privateAsset,
2777
2934
  shareToken: discovery.shareToken.address,
2778
2935
  sourceChainId: zone.sourceId,
2779
2936
  vaultAsset: discovery.assetToken.address,
2780
2937
  };
2781
2938
  }
2939
+ /** Resolves an optional validated private asset from the Admin Zone route. */
2940
+ async function resolveZonePositionPrivateAsset(c, options) {
2941
+ const record = await core_EarnVaults.get(Db.get(c.get('dbCached')), {
2942
+ chainId: options.discovery.chainId,
2943
+ vaultAddress: options.vault,
2944
+ });
2945
+ const configured = record?.zones.find((route) => route.chainId === options.chainId);
2946
+ if (!configured)
2947
+ return undefined;
2948
+ const [route] = await EarnVaults.resolveZoneRoutes({
2949
+ discovery: options.discovery,
2950
+ getClient: c.get('getClient'),
2951
+ routes: [configured],
2952
+ zones: [...c.get('zones').values()],
2953
+ });
2954
+ const token = route?.inputTokens[0];
2955
+ return token ? { deploymentBlock: route.deploymentBlock, token } : undefined;
2956
+ }
2957
+ /** Records a bounded dependency signal without failing the core Zone position. */
2958
+ function recordZonePositionEnrichmentFailure(c, options) {
2959
+ Cache.setPolicy(c, Cache.policies.noStore);
2960
+ const rpc = Viem.requestFailure(options.cause);
2961
+ const failure = rpc
2962
+ ? { ...rpc, chainId: options.chainId, id: 'rpc', operation: options.operation }
2963
+ : {
2964
+ chainId: options.chainId,
2965
+ failure: 'unknown',
2966
+ id: 'earn-zone-position',
2967
+ operation: options.operation,
2968
+ };
2969
+ c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure]);
2970
+ }
2782
2971
  /** Lists every vault where an account holds earn shares, ordered by vault address. */
2783
2972
  export async function listPositions(c, options) {
2784
2973
  const denomination = options['valuation.currency'];
@@ -2789,11 +2978,7 @@ export async function listPositions(c, options) {
2789
2978
  if (sourceChainId === undefined)
2790
2979
  throw new EarnVaults.NotFoundError();
2791
2980
  const db = Db.get(c.get('dbCached'));
2792
- const recordsPromise = core_EarnVaults
2793
- .list(db, { chainId: sourceChainId })
2794
- .then((records) => zone
2795
- ? records.filter((record) => record.zones.some((route) => route.chainId === options.chainId))
2796
- : records);
2981
+ const recordsPromise = core_EarnVaults.list(db, { chainId: sourceChainId });
2797
2982
  // The verified page needs no index: the registry is the candidate set.
2798
2983
  const heldPromise = options.verified || zone
2799
2984
  ? undefined
@@ -2831,11 +3016,14 @@ export async function listPositions(c, options) {
2831
3016
  const read = await Timing.time(c, 'earn_positions', () => Promise.all(batch.map(async (vault) => {
2832
3017
  const record = registry.get(vault);
2833
3018
  try {
2834
- const position = await getVaultPosition(c, {
3019
+ const input = {
2835
3020
  account: options.address,
2836
3021
  chainId: options.chainId,
2837
3022
  vault: Schema.Address.parse(vault),
2838
- });
3023
+ };
3024
+ const position = zone
3025
+ ? (await getZoneVaultPositionCore(c, input)).position
3026
+ : await getVaultPosition(c, input);
2839
3027
  return { position, record, vaultAddress: vault };
2840
3028
  }
2841
3029
  catch (cause) {
@@ -2858,15 +3046,42 @@ export async function listPositions(c, options) {
2858
3046
  : undefined;
2859
3047
  const [cashFlows, tokens, valueTokens, snapshot] = await Promise.all([
2860
3048
  indexedBlock
2861
- ? getVaultLifetimeCashFlows(c.get('getTidx')(options.chainId), {
2862
- account: options.address,
2863
- blockNumber: indexedBlock.number,
2864
- vaults: page.map(({ vaultAddress }) => Schema.Address.parse(vaultAddress)),
2865
- })
3049
+ ? (async () => {
3050
+ const tidx = c.get('getTidx')(options.chainId);
3051
+ const flows = await getVaultLifetimeCashFlows(tidx, {
3052
+ account: options.address,
3053
+ blockNumber: indexedBlock.number,
3054
+ vaults: page.map(({ vaultAddress }) => Schema.Address.parse(vaultAddress)),
3055
+ });
3056
+ for (const { position, vaultAddress } of page) {
3057
+ const flow = flows.get(vaultAddress);
3058
+ if (flow?.status !== 'complete')
3059
+ continue;
3060
+ const vault = Schema.Address.parse(vaultAddress);
3061
+ const withdrawals = await EarnWithdrawals.read(tidx, {
3062
+ account: options.address,
3063
+ blockNumber: indexedBlock.number,
3064
+ shareToken: position.shareToken,
3065
+ startBlockNumber: beforeFirstBlockNumber,
3066
+ vault,
3067
+ });
3068
+ const withdrawn = await EarnWithdrawals.value(c.get('getClient')(options.chainId), {
3069
+ vault,
3070
+ withdrawals,
3071
+ });
3072
+ flows.set(vaultAddress, withdrawn === undefined
3073
+ ? { status: 'incomplete_history' }
3074
+ : {
3075
+ ...flow,
3076
+ totalWithdrawn: (BigInt(flow.totalWithdrawn) + withdrawn).toString(),
3077
+ });
3078
+ }
3079
+ return flows;
3080
+ })()
2866
3081
  : undefined,
2867
3082
  (async () => {
2868
3083
  const addresses = [
2869
- ...new Set(page.flatMap(({ position }) => [position.assetToken, position.shareToken])),
3084
+ ...new Set(page.flatMap(({ position }) => zone ? [position.shareToken] : [position.assetToken, position.shareToken])),
2870
3085
  ];
2871
3086
  const groups = [];
2872
3087
  for (let index = 0; index < addresses.length; index += tokenReadChunkSize)
@@ -2963,7 +3178,7 @@ async function queryHeldVaults(c, options) {
2963
3178
  /** Serializes one live position into the address-scoped row contract. */
2964
3179
  function serializePosition(options) {
2965
3180
  const { position, tokens } = options;
2966
- const assetToken = getToken(tokens, position.assetToken);
3181
+ const assetToken = getToken(options.valueTokens ?? tokens, position.assetToken);
2967
3182
  const shareToken = getToken(tokens, position.shareToken);
2968
3183
  const valueToken = getToken(options.valueTokens ?? tokens, position.valueToken);
2969
3184
  const vaultAddress = Schema.Address.parse(options.vaultAddress.toLowerCase());
@@ -3226,6 +3441,7 @@ async function resolveVaultDiscovery(c, options) {
3226
3441
  async function readVaultDiscovery(c, options) {
3227
3442
  return Timing.time(c, 'earn_vault_discovery', () => EarnVaults.resolve({
3228
3443
  getClient: c.get('getClient'),
3444
+ hints: c.get('store'),
3229
3445
  include: options.include,
3230
3446
  input: {
3231
3447
  chainId: options.chainId,
@@ -3274,78 +3490,74 @@ async function resolvePositionApy(c, options) {
3274
3490
  c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure]);
3275
3491
  };
3276
3492
  const rateFailures = [];
3277
- const [rates, discovery] = await Promise.all([
3278
- Timing.time(c, 'earn_apy', () => EarnRates.resolve({
3279
- chainId: sourceChainId,
3280
- getClient: c.get('getClient'),
3281
- getTidx: c.get('getTidx'),
3282
- onFailure: (failure) => {
3283
- rateFailures.push({ ...failure, chainId: sourceChainId });
3284
- },
3285
- store: c.get('store'),
3286
- vaults: [options.vault],
3287
- })).catch(() => {
3288
- rateFailures.push({
3289
- chainId: sourceChainId,
3290
- failure: 'unknown',
3291
- id: 'earn-apy',
3292
- operation: 'resolve',
3293
- });
3294
- return undefined;
3295
- }),
3296
- resolveVaultDiscovery(c, {
3493
+ const rates_pending = Timing.time(c, 'earn_apy', () => EarnRates.resolve({
3494
+ chainId: sourceChainId,
3495
+ getClient: c.get('getClient'),
3496
+ getTidx: c.get('getTidx'),
3497
+ onFailure: (failure) => {
3498
+ rateFailures.push({ ...failure, chainId: sourceChainId });
3499
+ },
3500
+ store: c.get('store'),
3501
+ vaults: [options.vault],
3502
+ })).catch(() => {
3503
+ rateFailures.push({
3297
3504
  chainId: sourceChainId,
3298
- include: [],
3505
+ failure: 'unknown',
3506
+ id: 'earn-apy',
3507
+ operation: 'resolve',
3508
+ });
3509
+ return undefined;
3510
+ });
3511
+ // Vault facts and the registry row depend only on the vault, so they load
3512
+ // alongside the rate read rather than after it.
3513
+ const vault_pending = Timing.time(c, 'earn_vault_facts', () => Promise.all([
3514
+ resolveVaultApyFacts(c, { chainId: sourceChainId, vault: options.vault }),
3515
+ core_EarnVaults.get(Db.get(c.get('dbCached')), {
3516
+ chainId: options.chainId,
3299
3517
  vaultAddress: options.vault,
3300
- }).catch((cause) => {
3301
- const failure = Viem.requestFailure(cause);
3302
- recordFailure(failure
3303
- ? { ...failure, chainId: sourceChainId, id: 'rpc', operation: 'eth_call' }
3304
- : {
3305
- chainId: sourceChainId,
3306
- failure: 'unknown',
3307
- id: 'earn-vaults',
3308
- operation: 'getVault',
3309
- });
3310
- return undefined;
3311
3518
  }),
3312
- ]);
3519
+ ])).catch((cause) => {
3520
+ const failure = Viem.requestFailure(cause);
3521
+ recordFailure(failure
3522
+ ? { ...failure, chainId: sourceChainId, id: 'rpc', operation: 'eth_call' }
3523
+ : (sharePriceProviderFailure({ cause, chainId: sourceChainId }) ?? {
3524
+ chainId: options.chainId,
3525
+ failure: 'unknown',
3526
+ id: 'earn-rewards',
3527
+ operation: 'getPositionApy',
3528
+ }));
3529
+ return undefined;
3530
+ });
3531
+ // The handler surfaces a failed position read; here it only ends enrichment.
3532
+ const position = await options.position.catch(() => undefined);
3533
+ const [rates, vault] = await Promise.all([rates_pending, vault_pending]);
3313
3534
  const base = rates?.get(options.vault.toLowerCase());
3314
3535
  const rateFailure = rateFailures[0];
3315
3536
  if (rateFailure)
3316
3537
  recordFailure(rateFailure);
3317
- if (!base || !discovery)
3538
+ if (!base || !vault || !position)
3318
3539
  return null;
3319
- return await Timing.time(c, 'earn_rewards_apy', async () => {
3320
- const [earnFees, record] = await Promise.all([
3321
- c.get('getClient')(sourceChainId).readContract({
3322
- abi: Abis.earnVault,
3323
- address: options.vault,
3324
- functionName: 'earnFees',
3325
- }),
3326
- core_EarnVaults.get(Db.get(c.get('db')), {
3327
- chainId: options.chainId,
3328
- vaultAddress: options.vault,
3329
- }),
3330
- ]);
3540
+ const [facts, record] = vault;
3541
+ return await Timing.time(c, 'earn_rewards_apy', () => {
3331
3542
  // Accounting retains qualified shares for excluded infrastructure, so apply its current exclusions here too.
3332
3543
  const zoneContracts = [...c.get('zones').values()]
3333
3544
  .filter((zone) => zone.sourceId === options.chainId)
3334
3545
  .flatMap((zone) => positionApyContractAddresses(zone.contracts));
3546
+ // Registration must show on the next read, so reward rows stay on the primary.
3335
3547
  return RewardRead.positionApy({
3336
- assetDecimals: discovery.assetToken.decimals,
3548
+ assetDecimals: facts.assetDecimals,
3337
3549
  baseNet: base.net,
3338
3550
  chainId: options.chainId,
3339
3551
  db: c.get('db'),
3340
3552
  excludedAddresses: [
3341
- discovery.engine.address,
3342
- earnFees,
3553
+ facts.engine,
3554
+ facts.earnFees,
3343
3555
  ...(record?.zones.map((zone) => zone.earnRouter) ?? []),
3344
3556
  ...zoneContracts,
3345
3557
  ],
3346
3558
  recipient: options.recipient,
3347
- shareBalance: options.shareBalance.toString(),
3348
- value: options.value.toString(),
3559
+ shareBalance: position.shareBalance.toString(),
3560
+ value: position.value.toString(),
3349
3561
  vaultAddress: options.vault,
3350
3562
  });
3351
3563
  }).catch((cause) => {
@@ -3358,6 +3570,30 @@ async function resolvePositionApy(c, options) {
3358
3570
  return null;
3359
3571
  });
3360
3572
  }
3573
+ /**
3574
+ * Resolves the vault facts wallet APY needs (engine, fee sink, asset decimals)
3575
+ * in one cached hop; full discovery costs several and serves no other field.
3576
+ */
3577
+ async function resolveVaultApyFacts(c, options) {
3578
+ return Store.memoize(async () => {
3579
+ const client = c.get('getClient')(options.chainId);
3580
+ const { asset } = await resolveVaultBindings(c, options);
3581
+ const [assetDecimals, earnFees, engine] = await client.multicall({
3582
+ allowFailure: false,
3583
+ contracts: [
3584
+ { abi: Abis.tip20, address: asset, functionName: 'decimals' },
3585
+ { abi: Abis.earnVault, address: options.vault, functionName: 'earnFees' },
3586
+ { abi: Abis.earnVault, address: options.vault, functionName: 'engine' },
3587
+ ],
3588
+ });
3589
+ return { assetDecimals, earnFees, engine };
3590
+ }, {
3591
+ key: `earn-vault-apy-facts:v1:${options.chainId}:${options.vault.toLowerCase()}`,
3592
+ store: c.get('store'),
3593
+ // Matches the rate bucket so a migrated engine reappears with the reset rate.
3594
+ ttl: Ttl.minutes(15),
3595
+ });
3596
+ }
3361
3597
  function positionApyContractAddresses(contract) {
3362
3598
  if (!contract || typeof contract !== 'object')
3363
3599
  return [];