tapimo 0.19.0 → 0.20.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 (494) hide show
  1. package/README.md +13 -5
  2. package/dist/ApiKey.d.ts +2 -2
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +2 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +85 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +218 -56
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +12543 -13912
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +4 -5
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +12 -20
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +20 -36
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +871 -828
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +14 -26
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +93 -186
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +3 -5
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/audit-logs.d.ts +18 -18
  27. package/dist/admin/apps/audit-logs.js +1 -1
  28. package/dist/admin/apps/audit-logs.js.map +1 -1
  29. package/dist/admin/apps/earn-vaults.d.ts +27 -27
  30. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  31. package/dist/admin/apps/earn-vaults.js +11 -5
  32. package/dist/admin/apps/earn-vaults.js.map +1 -1
  33. package/dist/admin/apps/organizations.d.ts +17 -17
  34. package/dist/admin/apps/prop-amms.d.ts +4 -4
  35. package/dist/admin/apps/routes-support.js +1 -38
  36. package/dist/admin/apps/routes-support.js.map +1 -1
  37. package/dist/admin/apps/routes.d.ts +153 -153
  38. package/dist/admin/apps/sentinel.d.ts +4 -4
  39. package/dist/admin/apps/verified-tokens.d.ts +24 -24
  40. package/dist/admin/apps/zone-delegation-requests.d.ts +332 -0
  41. package/dist/admin/apps/zone-delegation-requests.d.ts.map +1 -0
  42. package/dist/admin/apps/zone-delegation-requests.js +200 -0
  43. package/dist/admin/apps/zone-delegation-requests.js.map +1 -0
  44. package/dist/admin/apps/zone-delegations.d.ts +512 -52
  45. package/dist/admin/apps/zone-delegations.d.ts.map +1 -1
  46. package/dist/admin/apps/zone-delegations.js +134 -44
  47. package/dist/admin/apps/zone-delegations.js.map +1 -1
  48. package/dist/admin/index.d.ts +1 -1
  49. package/dist/admin/index.d.ts.map +1 -1
  50. package/dist/admin/index.js +1 -1
  51. package/dist/admin/index.js.map +1 -1
  52. package/dist/admin/ui.generated.d.ts +1 -1
  53. package/dist/admin/ui.generated.d.ts.map +1 -1
  54. package/dist/admin/ui.generated.js +341 -397
  55. package/dist/admin/ui.generated.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  57. package/dist/analytics/tables/requestEvents.js +4 -2
  58. package/dist/analytics/tables/requestEvents.js.map +1 -1
  59. package/dist/apps/data/App.d.ts +11932 -13214
  60. package/dist/apps/data/App.d.ts.map +1 -1
  61. package/dist/apps/data/App.js +32 -13
  62. package/dist/apps/data/App.js.map +1 -1
  63. package/dist/apps/data/ZoneSelection.d.ts +1 -1
  64. package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
  65. package/dist/apps/data/ZoneSelection.js +2 -2
  66. package/dist/apps/data/ZoneSelection.js.map +1 -1
  67. package/dist/apps/data/routes/activities.d.ts +60 -27
  68. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  69. package/dist/apps/data/routes/activities.js +91 -16
  70. package/dist/apps/data/routes/activities.js.map +1 -1
  71. package/dist/apps/data/routes/addresses.d.ts +893 -875
  72. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  73. package/dist/apps/data/routes/balances.d.ts +36 -36
  74. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  75. package/dist/apps/data/routes/balances.js +3 -1
  76. package/dist/apps/data/routes/balances.js.map +1 -1
  77. package/dist/apps/data/routes/blocks.d.ts +40 -40
  78. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  79. package/dist/apps/data/routes/blocks.js +3 -7
  80. package/dist/apps/data/routes/blocks.js.map +1 -1
  81. package/dist/apps/data/routes/coingecko.d.ts +236 -236
  82. package/dist/apps/data/routes/earn-transactions.d.ts +14 -14
  83. package/dist/apps/data/routes/earn.d.ts +261 -1445
  84. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  85. package/dist/apps/data/routes/earn.js +64 -490
  86. package/dist/apps/data/routes/earn.js.map +1 -1
  87. package/dist/apps/data/routes/exchanges.d.ts +144 -144
  88. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  89. package/dist/apps/data/routes/exchanges.js +5 -15
  90. package/dist/apps/data/routes/exchanges.js.map +1 -1
  91. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  92. package/dist/apps/data/routes/fee-amm.js +3 -9
  93. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  94. package/dist/apps/data/routes/indexer.d.ts +13 -13
  95. package/dist/apps/data/routes/receipts.d.ts +53 -53
  96. package/dist/apps/data/routes/receipts.js +1 -1
  97. package/dist/apps/data/routes/receipts.js.map +1 -1
  98. package/dist/apps/data/routes/rpc.d.ts +52 -0
  99. package/dist/apps/data/routes/rpc.d.ts.map +1 -1
  100. package/dist/apps/data/routes/rpc.js +19 -18
  101. package/dist/apps/data/routes/rpc.js.map +1 -1
  102. package/dist/apps/data/routes/tokenlist.d.ts +14 -14
  103. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  104. package/dist/apps/data/routes/tokenlist.js +1 -3
  105. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  106. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  107. package/dist/apps/data/routes/tokens.js +7 -5
  108. package/dist/apps/data/routes/tokens.js.map +1 -1
  109. package/dist/apps/data/routes/transactions.d.ts +281 -281
  110. package/dist/apps/data/routes/transactions.js +3 -3
  111. package/dist/apps/data/routes/transactions.js.map +1 -1
  112. package/dist/apps/data/routes/transfers.d.ts +12 -12
  113. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  114. package/dist/apps/data/routes/transfers.js +1 -3
  115. package/dist/apps/data/routes/transfers.js.map +1 -1
  116. package/dist/apps/data/routes/valuation.d.ts +30 -30
  117. package/dist/apps/data/routes/valuation.d.ts.map +1 -1
  118. package/dist/apps/data/routes/valuation.js +1 -3
  119. package/dist/apps/data/routes/valuation.js.map +1 -1
  120. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  121. package/dist/apps/data/routes/webhooks.d.ts +102 -102
  122. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  123. package/dist/apps/data/routes/webhooks.js +9 -23
  124. package/dist/apps/data/routes/webhooks.js.map +1 -1
  125. package/dist/apps/data/routes/zone-deposits.d.ts +16 -16
  126. package/dist/apps/data/routes/zone-withdrawals.d.ts +31 -31
  127. package/dist/apps/data/routes/zones.d.ts +28 -28
  128. package/dist/apps/management/App.d.ts +18 -102
  129. package/dist/apps/management/App.d.ts.map +1 -1
  130. package/dist/apps/management/App.js +1 -1
  131. package/dist/apps/management/App.js.map +1 -1
  132. package/dist/apps/management/routes/api-keys.d.ts +253 -339
  133. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  134. package/dist/apps/management/routes/api-keys.js +25 -11
  135. package/dist/apps/management/routes/api-keys.js.map +1 -1
  136. package/dist/apps/management/routes/billing.d.ts +92 -92
  137. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  138. package/dist/apps/management/routes/billing.js +5 -13
  139. package/dist/apps/management/routes/billing.js.map +1 -1
  140. package/dist/apps/management/routes/cli.d.ts.map +1 -1
  141. package/dist/apps/management/routes/cli.js +3 -9
  142. package/dist/apps/management/routes/cli.js.map +1 -1
  143. package/dist/apps/management/routes/faucet.d.ts +16 -16
  144. package/dist/apps/management/routes/fee-payer-usage.d.ts +38 -38
  145. package/dist/apps/management/routes/fee-payer-usage.d.ts.map +1 -1
  146. package/dist/apps/management/routes/fee-payer-usage.js +2 -4
  147. package/dist/apps/management/routes/fee-payer-usage.js.map +1 -1
  148. package/dist/apps/management/routes/invitations.d.ts +52 -52
  149. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  150. package/dist/apps/management/routes/invitations.js +4 -12
  151. package/dist/apps/management/routes/invitations.js.map +1 -1
  152. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  153. package/dist/apps/management/routes/invite-links.js +6 -14
  154. package/dist/apps/management/routes/invite-links.js.map +1 -1
  155. package/dist/apps/management/routes/me.d.ts +6 -6
  156. package/dist/apps/management/routes/me.d.ts.map +1 -1
  157. package/dist/apps/management/routes/me.js +3 -7
  158. package/dist/apps/management/routes/me.js.map +1 -1
  159. package/dist/apps/management/routes/members.d.ts +84 -84
  160. package/dist/apps/management/routes/members.d.ts.map +1 -1
  161. package/dist/apps/management/routes/members.js +2 -4
  162. package/dist/apps/management/routes/members.js.map +1 -1
  163. package/dist/apps/management/routes/orgs.d.ts +44 -44
  164. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  165. package/dist/apps/management/routes/orgs.js +2 -6
  166. package/dist/apps/management/routes/orgs.js.map +1 -1
  167. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  168. package/dist/apps/management/routes/projects.js +2 -6
  169. package/dist/apps/management/routes/projects.js.map +1 -1
  170. package/dist/apps/management/routes/route-usage.d.ts +34 -34
  171. package/dist/apps/management/routes/route-usage.d.ts.map +1 -1
  172. package/dist/apps/management/routes/route-usage.js +2 -4
  173. package/dist/apps/management/routes/route-usage.js.map +1 -1
  174. package/dist/apps/management/routes/routes-access-requests.d.ts +120 -91
  175. package/dist/apps/management/routes/routes-access-requests.d.ts.map +1 -1
  176. package/dist/apps/management/routes/routes-access-requests.js +49 -9
  177. package/dist/apps/management/routes/routes-access-requests.js.map +1 -1
  178. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  179. package/dist/apps/management/routes/usage.js +8 -16
  180. package/dist/apps/management/routes/usage.js.map +1 -1
  181. package/dist/apps/management/routes/verified-token-requests.d.ts +39 -39
  182. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  183. package/dist/apps/management/routes/verified-token-requests.js +3 -7
  184. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  185. package/dist/apps/management/routes/webhooks.d.ts +2089 -2089
  186. package/dist/apps/management/routes/zone-delegations.d.ts +14 -17
  187. package/dist/apps/management/routes/zone-delegations.d.ts.map +1 -1
  188. package/dist/apps/management/routes/zone-delegations.js +1 -6
  189. package/dist/apps/management/routes/zone-delegations.js.map +1 -1
  190. package/dist/apps/mpp/App.d.ts +44 -44
  191. package/dist/apps/mpp/App.js +3 -3
  192. package/dist/apps/mpp/App.js.map +1 -1
  193. package/dist/apps/mpp/internal/Adapter.js +1 -1
  194. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  195. package/dist/apps/mpp/internal/Error.d.ts.map +1 -1
  196. package/dist/apps/mpp/internal/Error.js +1 -0
  197. package/dist/apps/mpp/internal/Error.js.map +1 -1
  198. package/dist/apps/mpp/internal/Policy.d.ts +5 -1
  199. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  200. package/dist/apps/mpp/internal/Policy.js +35 -13
  201. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  202. package/dist/apps/relay/App.d.ts +2 -2
  203. package/dist/apps/relay/App.d.ts.map +1 -1
  204. package/dist/apps/relay/App.js +25 -16
  205. package/dist/apps/relay/App.js.map +1 -1
  206. package/dist/apps/routes/App.d.ts +311 -311
  207. package/dist/apps/routes/routes/deposit-addresses.d.ts +1099 -1099
  208. package/dist/apps/routes/routes/list.d.ts +74 -74
  209. package/dist/apps/routes/routes/transfers.d.ts +94 -94
  210. package/dist/cli/ApiKeys.d.ts +19 -26
  211. package/dist/cli/ApiKeys.d.ts.map +1 -1
  212. package/dist/db/Db.d.ts +3 -3
  213. package/dist/db/Db.d.ts.map +1 -1
  214. package/dist/db/Db.js +27 -0
  215. package/dist/db/Db.js.map +1 -1
  216. package/dist/db/Schema.d.ts +28 -62
  217. package/dist/db/Schema.d.ts.map +1 -1
  218. package/dist/db/Schema.js +18 -18
  219. package/dist/db/Schema.js.map +1 -1
  220. package/dist/db/tables/rewardRuns.d.ts +21 -0
  221. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  222. package/dist/db/tables/rewardRuns.js +19 -0
  223. package/dist/db/tables/rewardRuns.js.map +1 -1
  224. package/dist/db/tables/routesAccessRequests.d.ts +13 -0
  225. package/dist/db/tables/routesAccessRequests.d.ts.map +1 -1
  226. package/dist/db/tables/routesAccessRequests.js +12 -0
  227. package/dist/db/tables/routesAccessRequests.js.map +1 -1
  228. package/dist/db/tables/zoneDelegationRequests.d.ts +165 -0
  229. package/dist/db/tables/zoneDelegationRequests.d.ts.map +1 -0
  230. package/dist/db/tables/{zoneKeyRequests.js → zoneDelegationRequests.js} +43 -42
  231. package/dist/db/tables/zoneDelegationRequests.js.map +1 -0
  232. package/dist/db/tables/zoneDelegations.d.ts +11 -5
  233. package/dist/db/tables/zoneDelegations.d.ts.map +1 -1
  234. package/dist/db/tables/zoneDelegations.js +21 -3
  235. package/dist/db/tables/zoneDelegations.js.map +1 -1
  236. package/dist/handlers/internal/accounts.d.ts +7 -0
  237. package/dist/handlers/internal/accounts.d.ts.map +1 -0
  238. package/dist/handlers/internal/{multisig.js → accounts.js} +10 -10
  239. package/dist/handlers/internal/{multisig.js.map → accounts.js.map} +1 -1
  240. package/dist/handlers/internal/sponsorship.js +17 -17
  241. package/dist/handlers/internal/sponsorship.js.map +1 -1
  242. package/dist/handlers/relay.d.ts +6 -6
  243. package/dist/handlers/relay.d.ts.map +1 -1
  244. package/dist/handlers/relay.js +15 -15
  245. package/dist/handlers/relay.js.map +1 -1
  246. package/dist/internal/Auth.d.ts.map +1 -1
  247. package/dist/internal/Auth.js +4 -8
  248. package/dist/internal/Auth.js.map +1 -1
  249. package/dist/internal/EarnRates.d.ts.map +1 -1
  250. package/dist/internal/EarnRates.js +1 -3
  251. package/dist/internal/EarnRates.js.map +1 -1
  252. package/dist/internal/EarnVaults.js +2 -2
  253. package/dist/internal/Log.d.ts +2 -4
  254. package/dist/internal/Log.d.ts.map +1 -1
  255. package/dist/internal/Log.js +0 -3
  256. package/dist/internal/Log.js.map +1 -1
  257. package/dist/internal/Response.d.ts +1 -1
  258. package/dist/internal/Response.d.ts.map +1 -1
  259. package/dist/internal/Response.js +0 -3
  260. package/dist/internal/Response.js.map +1 -1
  261. package/dist/internal/Schema.d.ts +11 -0
  262. package/dist/internal/Schema.d.ts.map +1 -1
  263. package/dist/internal/Schema.js +24 -1
  264. package/dist/internal/Schema.js.map +1 -1
  265. package/dist/internal/ZoneAccess.d.ts +70 -35
  266. package/dist/internal/ZoneAccess.d.ts.map +1 -1
  267. package/dist/internal/ZoneAccess.js +312 -131
  268. package/dist/internal/ZoneAccess.js.map +1 -1
  269. package/dist/internal/ZoneDelegation.d.ts +7 -19
  270. package/dist/internal/ZoneDelegation.d.ts.map +1 -1
  271. package/dist/internal/ZoneDelegation.js +8 -29
  272. package/dist/internal/ZoneDelegation.js.map +1 -1
  273. package/dist/internal/{ZoneKeyApproval.d.ts → ZoneDelegationApproval.d.ts} +3 -5
  274. package/dist/internal/ZoneDelegationApproval.d.ts.map +1 -0
  275. package/dist/internal/ZoneDelegationApproval.js +16 -0
  276. package/dist/internal/ZoneDelegationApproval.js.map +1 -0
  277. package/dist/internal/ZoneKeyRewrite.d.ts +98 -0
  278. package/dist/internal/ZoneKeyRewrite.d.ts.map +1 -0
  279. package/dist/internal/ZoneKeyRewrite.js +151 -0
  280. package/dist/internal/ZoneKeyRewrite.js.map +1 -0
  281. package/dist/internal/rewards/Campaigns.d.ts +2 -0
  282. package/dist/internal/rewards/Campaigns.d.ts.map +1 -1
  283. package/dist/internal/rewards/Campaigns.js.map +1 -1
  284. package/dist/internal/rewards/Distributions.d.ts.map +1 -1
  285. package/dist/internal/rewards/Distributions.js +2 -6
  286. package/dist/internal/rewards/Distributions.js.map +1 -1
  287. package/dist/internal/rewards/Monitor.d.ts +4 -1
  288. package/dist/internal/rewards/Monitor.d.ts.map +1 -1
  289. package/dist/internal/rewards/Monitor.js +19 -2
  290. package/dist/internal/rewards/Monitor.js.map +1 -1
  291. package/dist/internal/rewards/Runner.d.ts.map +1 -1
  292. package/dist/internal/rewards/Runner.js +9 -1
  293. package/dist/internal/rewards/Runner.js.map +1 -1
  294. package/dist/internal/routes/Action.d.ts.map +1 -1
  295. package/dist/internal/routes/Action.js +2 -3
  296. package/dist/internal/routes/Action.js.map +1 -1
  297. package/dist/internal/routes/Deposit.d.ts.map +1 -1
  298. package/dist/internal/routes/Deposit.js +2 -6
  299. package/dist/internal/routes/Deposit.js.map +1 -1
  300. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  301. package/dist/internal/routes/DepositAddress.js +4 -10
  302. package/dist/internal/routes/DepositAddress.js.map +1 -1
  303. package/dist/internal/routes/Policy.d.ts.map +1 -1
  304. package/dist/internal/routes/Policy.js +2 -1
  305. package/dist/internal/routes/Policy.js.map +1 -1
  306. package/dist/internal/routes/Provider.js +8 -8
  307. package/dist/internal/routes/Provider.js.map +1 -1
  308. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  309. package/dist/internal/routes/Reconciliation.js +3 -2
  310. package/dist/internal/routes/Reconciliation.js.map +1 -1
  311. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  312. package/dist/internal/routes/Transfer.js +4 -12
  313. package/dist/internal/routes/Transfer.js.map +1 -1
  314. package/dist/internal/routes/UniversalDepositAddress.d.ts.map +1 -1
  315. package/dist/internal/routes/UniversalDepositAddress.js +3 -6
  316. package/dist/internal/routes/UniversalDepositAddress.js.map +1 -1
  317. package/dist/internal/routes/providers/SquidOrder.d.ts.map +1 -1
  318. package/dist/internal/routes/providers/SquidOrder.js +3 -2
  319. package/dist/internal/routes/providers/SquidOrder.js.map +1 -1
  320. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  321. package/dist/internal/routes/providers/relay.js +4 -3
  322. package/dist/internal/routes/providers/relay.js.map +1 -1
  323. package/package.json +20 -5
  324. package/src/ApiKey.ts +2 -2
  325. package/src/ApiKeys.test.ts +284 -51
  326. package/src/ApiKeys.ts +297 -64
  327. package/src/App.ts +4 -5
  328. package/src/Client.test-d.ts +33 -126
  329. package/src/Scope.test.ts +26 -45
  330. package/src/Scope.ts +24 -37
  331. package/src/admin/App.test.ts +51 -4
  332. package/src/admin/App.ts +25 -33
  333. package/src/admin/Mcp.test.ts +2 -1
  334. package/src/admin/apps/api-keys.test.ts +90 -20
  335. package/src/admin/apps/api-keys.ts +5 -8
  336. package/src/admin/apps/audit-logs.ts +1 -1
  337. package/src/admin/apps/earn-vaults.test.ts +19 -19
  338. package/src/admin/apps/earn-vaults.ts +11 -5
  339. package/src/admin/apps/routes-support.test.ts +254 -3
  340. package/src/admin/apps/routes-support.ts +1 -44
  341. package/src/admin/apps/scopes.test.ts +3 -3
  342. package/src/admin/apps/zone-delegation-requests.test.ts +246 -0
  343. package/src/admin/apps/zone-delegation-requests.ts +240 -0
  344. package/src/admin/apps/zone-delegations.test.ts +218 -58
  345. package/src/admin/apps/zone-delegations.ts +146 -46
  346. package/src/admin/index.ts +1 -1
  347. package/src/admin/ui/src/components/ApiKeyForm.tsx +4 -3
  348. package/src/admin/ui/src/lib/config.ts +3 -3
  349. package/src/admin/ui/src/lib/query-client.ts +1 -1
  350. package/src/admin/ui/src/lib/review-queues.ts +10 -10
  351. package/src/admin/ui/src/lib/routes-setup.test.ts +1 -2
  352. package/src/admin/ui/src/lib/routes-setup.ts +3 -5
  353. package/src/admin/ui/src/lib/scopes.test.ts +3 -6
  354. package/src/admin/ui/src/lib/scopes.ts +2 -9
  355. package/src/admin/ui/src/lib/{zone-key-requests.ts → zone-delegation-requests.ts} +27 -31
  356. package/src/admin/ui/src/routeTree.gen.ts +17 -17
  357. package/src/admin/ui/src/routes/__root.tsx +1 -1
  358. package/src/admin/ui/src/routes/api-keys.tsx +2 -15
  359. package/src/admin/ui/src/routes/audit-logs.tsx +2 -2
  360. package/src/admin/ui/src/routes/index.tsx +11 -11
  361. package/src/admin/ui/src/routes/organizations.tsx +3 -1
  362. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +3 -1
  363. package/src/admin/ui/src/routes/organizations_.$orgId_.setup.tsx +1 -3
  364. package/src/admin/ui/src/routes/{zone-key-requests.tsx → zone-delegation-requests.tsx} +228 -172
  365. package/src/admin/ui/vite.config.ts +14 -1
  366. package/src/admin/ui.generated.ts +412 -583
  367. package/src/analytics/tables/requestEvents.test.ts +13 -3
  368. package/src/analytics/tables/requestEvents.ts +4 -3
  369. package/src/apps/data/App.test.ts +72 -35
  370. package/src/apps/data/App.ts +29 -13
  371. package/src/apps/data/ZoneSelection.test.ts +53 -70
  372. package/src/apps/data/ZoneSelection.ts +2 -2
  373. package/src/apps/data/routes/activities.test.ts +140 -6
  374. package/src/apps/data/routes/activities.ts +124 -18
  375. package/src/apps/data/routes/balances.ts +5 -1
  376. package/src/apps/data/routes/blocks.ts +9 -13
  377. package/src/apps/data/routes/earn-transactions.local.test.ts +6 -1
  378. package/src/apps/data/routes/earn-transactions.test.ts +7 -3
  379. package/src/apps/data/routes/earn.bench.ts +0 -14
  380. package/src/apps/data/routes/earn.discovery.test.ts +4 -39
  381. package/src/apps/data/routes/earn.local.test.ts +27 -34
  382. package/src/apps/data/routes/earn.test.ts +172 -490
  383. package/src/apps/data/routes/earn.ts +103 -652
  384. package/src/apps/data/routes/exchanges.ts +20 -30
  385. package/src/apps/data/routes/fee-amm.ts +12 -18
  386. package/src/apps/data/routes/indexer.test.ts +14 -12
  387. package/src/apps/data/routes/receipts.ts +1 -1
  388. package/src/apps/data/routes/rpc.test.ts +23 -18
  389. package/src/apps/data/routes/rpc.ts +21 -21
  390. package/src/apps/data/routes/rpc.zone.test.ts +60 -6
  391. package/src/apps/data/routes/tokenlist.ts +4 -6
  392. package/src/apps/data/routes/tokens.test.ts +20 -0
  393. package/src/apps/data/routes/tokens.ts +10 -5
  394. package/src/apps/data/routes/transactions.ts +3 -3
  395. package/src/apps/data/routes/transfers.ts +4 -6
  396. package/src/apps/data/routes/valuation.test.ts +2 -4
  397. package/src/apps/data/routes/valuation.ts +4 -6
  398. package/src/apps/data/routes/webhooks.test.ts +1 -5
  399. package/src/apps/data/routes/webhooks.ts +30 -44
  400. package/src/apps/data/routes/zones.test.ts +35 -19
  401. package/src/apps/management/App.ts +3 -1
  402. package/src/apps/management/routes/api-keys.test.ts +112 -22
  403. package/src/apps/management/routes/api-keys.ts +30 -15
  404. package/src/apps/management/routes/billing.ts +17 -25
  405. package/src/apps/management/routes/cli.ts +12 -18
  406. package/src/apps/management/routes/fee-payer-usage.ts +5 -4
  407. package/src/apps/management/routes/invitations.ts +16 -21
  408. package/src/apps/management/routes/invite-links.ts +18 -26
  409. package/src/apps/management/routes/me.ts +9 -13
  410. package/src/apps/management/routes/members.ts +5 -7
  411. package/src/apps/management/routes/orgs.ts +8 -12
  412. package/src/apps/management/routes/projects.ts +8 -12
  413. package/src/apps/management/routes/route-usage.ts +5 -4
  414. package/src/apps/management/routes/routes-access-requests.test.ts +64 -2
  415. package/src/apps/management/routes/routes-access-requests.ts +99 -15
  416. package/src/apps/management/routes/scopes.test.ts +3 -3
  417. package/src/apps/management/routes/usage.ts +20 -28
  418. package/src/apps/management/routes/verified-token-requests.ts +9 -13
  419. package/src/apps/management/routes/zone-delegations.test.ts +3 -5
  420. package/src/apps/management/routes/zone-delegations.ts +4 -9
  421. package/src/apps/mpp/App.ts +3 -3
  422. package/src/apps/mpp/Mpp.zone.test.ts +49 -18
  423. package/src/apps/mpp/internal/Adapter.ts +1 -1
  424. package/src/apps/mpp/internal/Error.test.ts +3 -0
  425. package/src/apps/mpp/internal/Error.ts +1 -0
  426. package/src/apps/mpp/internal/Policy.test.ts +9 -8
  427. package/src/apps/mpp/internal/Policy.ts +37 -14
  428. package/src/apps/relay/App.sandbox.test.ts +15 -14
  429. package/src/apps/relay/App.test.ts +120 -61
  430. package/src/apps/relay/App.ts +28 -18
  431. package/src/apps/relay/App.zone-billing.test.ts +9 -4
  432. package/src/apps/routes/App.test.ts +21 -22
  433. package/src/db/Db.ts +34 -3
  434. package/src/db/Schema.ts +26 -26
  435. package/src/db/tables/rewardRuns.ts +39 -0
  436. package/src/db/tables/routesAccessRequests.test.ts +65 -0
  437. package/src/db/tables/routesAccessRequests.ts +25 -0
  438. package/src/db/tables/{zoneKeyRequests.test.ts → zoneDelegationRequests.test.ts} +36 -77
  439. package/src/db/tables/{zoneKeyRequests.ts → zoneDelegationRequests.ts} +69 -52
  440. package/src/db/tables/zoneDelegations.test.ts +5 -6
  441. package/src/db/tables/zoneDelegations.ts +25 -8
  442. package/src/handlers/internal/{multisig.store.test.ts → accounts.store.test.ts} +16 -16
  443. package/src/handlers/internal/{multisig.test.ts → accounts.test.ts} +85 -82
  444. package/src/handlers/internal/{multisig.ts → accounts.ts} +9 -9
  445. package/src/handlers/internal/sponsorship.ts +20 -20
  446. package/src/handlers/relay.test.ts +48 -46
  447. package/src/handlers/relay.ts +26 -26
  448. package/src/internal/Auth.test.ts +6 -2
  449. package/src/internal/Auth.ts +4 -10
  450. package/src/internal/EarnRates.ts +4 -6
  451. package/src/internal/EarnVaults.ts +2 -2
  452. package/src/internal/Log.test-d.ts +1 -0
  453. package/src/internal/Log.test.ts +4 -6
  454. package/src/internal/Log.ts +2 -6
  455. package/src/internal/Response.ts +0 -3
  456. package/src/internal/Schema.test.ts +42 -0
  457. package/src/internal/Schema.ts +36 -1
  458. package/src/internal/ZoneAccess.test.ts +515 -312
  459. package/src/internal/ZoneAccess.ts +410 -158
  460. package/src/internal/ZoneDelegation.test.ts +1 -41
  461. package/src/internal/ZoneDelegation.ts +10 -48
  462. package/src/internal/ZoneDelegationApproval.test.ts +22 -0
  463. package/src/internal/{ZoneKeyApproval.ts → ZoneDelegationApproval.ts} +4 -11
  464. package/src/internal/ZoneKeyRewrite.ts +231 -0
  465. package/src/internal/rewards/Campaigns.ts +2 -0
  466. package/src/internal/rewards/Distributions.ts +8 -12
  467. package/src/internal/rewards/Monitor.test.ts +64 -0
  468. package/src/internal/rewards/Monitor.ts +27 -4
  469. package/src/internal/rewards/Runner.ts +9 -1
  470. package/src/internal/routes/Action.ts +5 -6
  471. package/src/internal/routes/Deposit.ts +8 -12
  472. package/src/internal/routes/DepositAddress.ts +13 -19
  473. package/src/internal/routes/Policy.ts +2 -1
  474. package/src/internal/routes/Provider.ts +8 -8
  475. package/src/internal/routes/Reconciliation.ts +3 -2
  476. package/src/internal/routes/Transfer.ts +16 -24
  477. package/src/internal/routes/UniversalDepositAddress.ts +9 -12
  478. package/src/internal/routes/providers/SquidOrder.ts +3 -2
  479. package/src/internal/routes/providers/relay.ts +4 -3
  480. package/dist/admin/apps/zone-key-requests.d.ts +0 -406
  481. package/dist/admin/apps/zone-key-requests.d.ts.map +0 -1
  482. package/dist/admin/apps/zone-key-requests.js +0 -183
  483. package/dist/admin/apps/zone-key-requests.js.map +0 -1
  484. package/dist/db/tables/zoneKeyRequests.d.ts +0 -289
  485. package/dist/db/tables/zoneKeyRequests.d.ts.map +0 -1
  486. package/dist/db/tables/zoneKeyRequests.js.map +0 -1
  487. package/dist/handlers/internal/multisig.d.ts +0 -7
  488. package/dist/handlers/internal/multisig.d.ts.map +0 -1
  489. package/dist/internal/ZoneKeyApproval.d.ts.map +0 -1
  490. package/dist/internal/ZoneKeyApproval.js +0 -21
  491. package/dist/internal/ZoneKeyApproval.js.map +0 -1
  492. package/src/admin/apps/zone-key-requests.test.ts +0 -272
  493. package/src/admin/apps/zone-key-requests.ts +0 -231
  494. package/src/internal/ZoneKeyApproval.test.ts +0 -46
@@ -1,4 +1,5 @@
1
1
  import { type Context, Hono } from 'hono'
2
+ import { HTTPException } from 'hono/http-exception'
2
3
  import { Value as core_Value } from 'ox'
3
4
  import { Abis, type Actions } from 'viem/tempo'
4
5
  import {
@@ -101,6 +102,8 @@ const scanLimit = 50
101
102
  // Concurrent metadata reads in one macrotask collapse into one deployless
102
103
  // multicall; an await between small chunks keeps each call under the RPC limit.
103
104
  const tokenReadChunkSize = 20
105
+ // Bumped when the public vault shape changes, so no older cached body is served.
106
+ const vaultCacheName = 'tempo-api:earn-vaults:v7'
104
107
  const tempoStateAddress = '0x1c00000000000000000000000000000000000000'
105
108
  const tempoStateAbi = parseAbi(['function tempoBlockNumber() view returns (uint64)'])
106
109
  const zonePortalAbi = parseAbi(['function lastSyncedTempoBlockNumber() view returns (uint64)'])
@@ -168,12 +171,10 @@ export namespace schema {
168
171
  export const Association = z
169
172
  .strictObject({
170
173
  chainId: Schema.ChainId,
171
- firstRegisteredAt: z.iso
172
- .datetime()
173
- .check(
174
- z.describe('When the association was first registered.'),
175
- z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
176
- ),
174
+ firstRegisteredAt: Schema.dateTime().check(
175
+ z.describe('When the association was first registered.'),
176
+ z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
177
+ ),
177
178
  id: z.string().check(
178
179
  z.describe('Stable reward eligibility association identifier.'),
179
180
  z.meta({
@@ -182,12 +183,10 @@ export namespace schema {
182
183
  ],
183
184
  }),
184
185
  ),
185
- latestRegisteredAt: z.iso
186
- .datetime()
187
- .check(
188
- z.describe('When the association was most recently registered.'),
189
- z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
190
- ),
186
+ latestRegisteredAt: Schema.dateTime().check(
187
+ z.describe('When the association was most recently registered.'),
188
+ z.meta({ examples: ['2026-08-25T20:00:00.000Z'] }),
189
+ ),
191
190
  registrationOrder: z
192
191
  .string()
193
192
  .check(
@@ -516,16 +515,10 @@ export namespace schema {
516
515
  capabilities: z
517
516
  .optional(EarnVaults.schema.Discovery.shape.capabilities)
518
517
  .check(z.describe('Vault capabilities, when requested.')),
519
- description: z
520
- .nullable(z.string())
521
- .check(
522
- z.describe('Curated vault description, or null when the vault is not verified.'),
523
- z.meta({ examples: ['deelUSD deposited into the canonical Tempo Earn deployment.'] }),
524
- ),
525
518
  engine,
526
519
  id: Schema.Address.check(
527
520
  z.describe('Stable vault id, equal to the lowercase vault address.'),
528
- z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
521
+ z.meta({ examples: ['0xb20ba39ccf522d69b7a21e3f369be5de73a2c694'] }),
529
522
  ),
530
523
  instantLiquidity: EarnVaults.schema.Discovery.shape.instantLiquidity.check(
531
524
  z.describe(
@@ -539,9 +532,14 @@ export namespace schema {
539
532
  'Instant liquidity valued in USD, when requested via `include=tvl`, or null when liquidity is unavailable or the asset has no priced display currency.',
540
533
  ),
541
534
  ),
535
+ // Kept as an empty string for clients that require the field; registry labels name
536
+ // customers, so only the admin app serves them.
542
537
  label: z
543
538
  .string()
544
- .check(z.describe('Vault display label.'), z.meta({ examples: ['deelUSD Earn'] })),
539
+ .check(
540
+ z.describe('Always empty; curated labels are not public.'),
541
+ z.meta({ examples: [''] }),
542
+ ),
545
543
  sharePrice: z
546
544
  .nullable(value)
547
545
  .check(
@@ -565,12 +563,6 @@ export namespace schema {
565
563
  ],
566
564
  }),
567
565
  ),
568
- slug: z
569
- .nullable(z.string())
570
- .check(
571
- z.describe('Curated URL slug, or null when the vault is not verified.'),
572
- z.meta({ examples: ['deelusd-earn'] }),
573
- ),
574
566
  state: EarnVaults.schema.Discovery.shape.state,
575
567
  tvl: z
576
568
  .optional(z.nullable(value))
@@ -581,7 +573,7 @@ export namespace schema {
581
573
  ),
582
574
  vaultAddress: Schema.Address.check(
583
575
  z.describe('Earn vault contract address.'),
584
- z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
576
+ z.meta({ examples: ['0xb20ba39ccf522d69b7a21e3f369be5de73a2c694'] }),
585
577
  ),
586
578
  verified: z
587
579
  .boolean()
@@ -617,10 +609,35 @@ export namespace schema {
617
609
  'EarnVault',
618
610
  )
619
611
 
612
+ // Registry labels name customers, so only the admin app serves them.
613
+ const curatedVault = z.extend(vault, {
614
+ description: z
615
+ .nullable(z.string())
616
+ .check(
617
+ z.describe('Curated vault description, or null when the vault is not verified.'),
618
+ z.meta({ examples: ['pathUSD deposited into the canonical Tempo Earn deployment.'] }),
619
+ ),
620
+ label: z
621
+ .string()
622
+ .check(z.describe('Vault display label.'), z.meta({ examples: ['Sentora pathUSD (Earn)'] })),
623
+ slug: z
624
+ .nullable(z.string())
625
+ .check(
626
+ z.describe('Curated URL slug, or null when the vault is not verified.'),
627
+ z.meta({ examples: ['sentora-pathusd-earn'] }),
628
+ ),
629
+ })
630
+
631
+ /** One Earn vault with its curated registry label, slug, and description. */
632
+ export const CuratedVault = Schema.describe(
633
+ curatedVault,
634
+ 'A compatible earn vault with its curated registry fields.',
635
+ )
636
+
620
637
  /** One registry-curated Earn vault. */
621
638
  export const VerifiedVault = OpenApi.component(
622
639
  Schema.describe(
623
- z.extend(vault, {
640
+ z.extend(curatedVault, {
624
641
  engine: z.extend(engine, { type: engineType }),
625
642
  slug: z
626
643
  .string()
@@ -825,7 +842,7 @@ export namespace schema {
825
842
  ),
826
843
  id: Schema.Address.check(
827
844
  z.describe('Stable resource ID for this position, equal to the vault address.'),
828
- z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
845
+ z.meta({ examples: ['0xb20ba39ccf522d69b7a21e3f369be5de73a2c694'] }),
829
846
  ),
830
847
  lifetimeCashFlows: z
831
848
  .optional(lifetimeCashFlows)
@@ -847,7 +864,7 @@ export namespace schema {
847
864
  ),
848
865
  vaultAddress: Schema.Address.check(
849
866
  z.describe('Earn vault contract address holding this position.'),
850
- z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
867
+ z.meta({ examples: ['0xb20ba39ccf522d69b7a21e3f369be5de73a2c694'] }),
851
868
  ),
852
869
  verified: z
853
870
  .boolean()
@@ -891,28 +908,24 @@ export namespace schema {
891
908
  )
892
909
 
893
910
  const earningsWindow = z.extend(earningsBase, {
894
- end: z.iso
895
- .datetime()
896
- .check(
897
- z.describe(
898
- 'UTC ending boundary. Includes activity through the latest indexed block at or before this timestamp.',
899
- ),
900
- z.meta({ examples: ['2026-09-18T00:00:00.000Z'] }),
911
+ end: Schema.dateTime().check(
912
+ z.describe(
913
+ 'UTC ending boundary. Includes activity through the latest indexed block at or before this timestamp.',
901
914
  ),
915
+ z.meta({ examples: ['2026-09-18T00:00:00.000Z'] }),
916
+ ),
902
917
  period: z
903
918
  .enum(['7d', '30d', 'custom'])
904
919
  .check(
905
920
  z.describe('Rolling or explicitly bounded earnings window.'),
906
921
  z.meta({ examples: ['7d'] }),
907
922
  ),
908
- start: z.iso
909
- .datetime()
910
- .check(
911
- z.describe(
912
- 'UTC opening boundary. Excludes activity through the latest indexed block at or before this timestamp.',
913
- ),
914
- z.meta({ examples: ['2026-09-11T00:00:00.000Z'] }),
923
+ start: Schema.dateTime().check(
924
+ z.describe(
925
+ 'UTC opening boundary. Excludes activity through the latest indexed block at or before this timestamp.',
915
926
  ),
927
+ z.meta({ examples: ['2026-09-11T00:00:00.000Z'] }),
928
+ ),
916
929
  })
917
930
 
918
931
  const earnings = z.union([
@@ -1076,60 +1089,16 @@ export namespace schema {
1076
1089
  limit: Schema.Limit,
1077
1090
  })
1078
1091
 
1079
- const collectionQuery = z
1080
- .extend(collectionFilters, { 'apy.window': EarnRates.schema.Window })
1081
- .check(z.describe('Query parameters for listing earn vaults.'))
1082
-
1083
1092
  const vaultSelector = z.strictObject({
1084
1093
  chainId: Schema.ChainIdQuery,
1085
1094
  include: includeQuery,
1086
1095
  })
1087
1096
 
1088
- /** Schemas for the getEarnVaults operation. */
1089
- export namespace getEarnVaults {
1090
- /** Query parameters for all compatible deployed Earn vaults. */
1091
- export const Query = collectionQuery
1092
-
1093
- /** Paginated list of compatible deployed Earn vaults. */
1094
- export const Response = OpenApi.component(
1095
- z
1096
- .strictObject({
1097
- data: z
1098
- .array(Vault)
1099
- .check(z.describe('Compatible deployed earn vaults in deployment order.')),
1100
- meta: z.optional(meta),
1101
- nextCursor: Schema.NextCursor,
1102
- })
1103
- .check(z.describe('A page of compatible deployed earn vaults.')),
1104
- 'EarnVaultList',
1105
- )
1106
- }
1107
-
1108
- /** Schemas for the getVerifiedEarnVaults operation. */
1109
- export namespace getVerifiedEarnVaults {
1110
- /** Collection query without rates or valuation, for surfaces that cannot measure them. */
1111
- export const BaseQuery = Schema.describe(
1112
- z.extend(collectionFilters, { include: baseIncludeQuery }),
1113
- 'Query parameters for listing earn vaults.',
1114
- )
1115
-
1116
- /** Query parameters for registry-curated Earn vaults. */
1117
- export const Query = collectionQuery
1118
-
1119
- /** Paginated list of registry-curated Earn vaults. */
1120
- export const Response = OpenApi.component(
1121
- z
1122
- .strictObject({
1123
- data: z
1124
- .array(VerifiedVault)
1125
- .check(z.describe('Registry-curated earn vaults ordered by vault address.')),
1126
- meta: z.optional(meta),
1127
- nextCursor: Schema.NextCursor,
1128
- })
1129
- .check(z.describe('A page of registry-curated earn vaults.')),
1130
- 'VerifiedEarnVaultList',
1131
- )
1132
- }
1097
+ /** Collection filters without rates or valuation, for surfaces that cannot measure them. */
1098
+ export const VaultCollectionQuery = Schema.describe(
1099
+ z.extend(collectionFilters, { include: baseIncludeQuery }),
1100
+ 'Query parameters for listing earn vaults.',
1101
+ )
1133
1102
 
1134
1103
  /** Schemas for the getEarnAddressPositions operation. */
1135
1104
  export namespace getEarnAddressPositions {
@@ -1228,7 +1197,7 @@ export namespace schema {
1228
1197
 
1229
1198
  /** Schemas for the getEarnVaultSharePrices operation. */
1230
1199
  export namespace getEarnVaultSharePrices {
1231
- const timestamp = z.iso.datetime({ offset: true })
1200
+ const timestamp = Schema.dateTime({ offset: true })
1232
1201
 
1233
1202
  /** Path parameters identifying one Earn vault. */
1234
1203
  export const Params = z
@@ -1280,12 +1249,10 @@ export namespace schema {
1280
1249
  sharePrice: value.check(
1281
1250
  z.describe('Assets returned for one whole Earn share at the observation block.'),
1282
1251
  ),
1283
- timestamp: z.iso
1284
- .datetime()
1285
- .check(
1286
- z.describe('Requested daily observation timestamp.'),
1287
- z.meta({ examples: ['2026-07-01T00:00:00.000Z'] }),
1288
- ),
1252
+ timestamp: Schema.dateTime().check(
1253
+ z.describe('Requested daily observation timestamp.'),
1254
+ z.meta({ examples: ['2026-07-01T00:00:00.000Z'] }),
1255
+ ),
1289
1256
  })
1290
1257
  .check(z.describe('One historical Earn vault share price.'))
1291
1258
 
@@ -1319,13 +1286,13 @@ export namespace schema {
1319
1286
 
1320
1287
  /** Schemas for the getEarnVaultPosition operation. */
1321
1288
  export namespace getEarnVaultPosition {
1322
- const asOf = z.iso.datetime({ offset: true })
1289
+ const asOf = Schema.dateTime({ offset: true })
1323
1290
 
1324
1291
  /** Path parameters identifying the Earn vault and account. */
1325
1292
  export const Params = z
1326
1293
  .strictObject({
1327
1294
  address: Schema.Address.check(z.describe('Account whose earn position to read.')),
1328
- vaultId: Schema.address('0x4f94590b636f5878bce585e82379de81e1ec174f').check(
1295
+ vaultId: Schema.address('0xb20ba39ccf522d69b7a21e3f369be5de73a2c694').check(
1329
1296
  z.describe('Earn vault contract address.'),
1330
1297
  ),
1331
1298
  })
@@ -1360,12 +1327,10 @@ export namespace schema {
1360
1327
  z.describe('Indexed observation block.'),
1361
1328
  z.meta({ examples: [31039238] }),
1362
1329
  ),
1363
- timestamp: z.iso
1364
- .datetime()
1365
- .check(
1366
- z.describe('Timestamp of the indexed observation block.'),
1367
- z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
1368
- ),
1330
+ timestamp: Schema.dateTime().check(
1331
+ z.describe('Timestamp of the indexed observation block.'),
1332
+ z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
1333
+ ),
1369
1334
  })
1370
1335
  .check(z.describe('Indexed block used for a historical Earn position observation.'))
1371
1336
 
@@ -1463,7 +1428,7 @@ export namespace schema {
1463
1428
  .strictObject({
1464
1429
  chainId: Schema.ChainIdQuery,
1465
1430
  end: z
1466
- .optional(z.iso.datetime({ offset: true }))
1431
+ .optional(Schema.dateTime({ offset: true }))
1467
1432
  .check(
1468
1433
  z.describe(
1469
1434
  'Required with period=custom. Inclusive ISO 8601 ending timestamp; indexed history must cover this time.',
@@ -1472,7 +1437,7 @@ export namespace schema {
1472
1437
  ),
1473
1438
  period: z._default(earningsPeriod, 'lifetime'),
1474
1439
  start: z
1475
- .optional(z.iso.datetime({ offset: true }))
1440
+ .optional(Schema.dateTime({ offset: true }))
1476
1441
  .check(
1477
1442
  z.describe(
1478
1443
  'Required with period=custom. Exclusive ISO 8601 opening timestamp, earlier than end.',
@@ -1646,134 +1611,6 @@ export function earn(options: earn.Options = {}) {
1646
1611
  )
1647
1612
  },
1648
1613
  )
1649
- .get(
1650
- '/v1/earn/vaults',
1651
- Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
1652
- OpenApi.validate('query', schema.getEarnVaults.Query, {
1653
- code: 'query_invalid',
1654
- message: 'Invalid query parameters',
1655
- }),
1656
- OpenApi.describeRoute({
1657
- description:
1658
- 'Lists compatible earn vaults discovered from deployment events and resolved from current chain state.',
1659
- operationId: 'getEarnVaults',
1660
- responses: OpenApi.responses({
1661
- errors: {
1662
- 400: {
1663
- codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
1664
- },
1665
- 502: 'Could not read earn deployment or vault data.',
1666
- },
1667
- success: {
1668
- description: 'A page of compatible deployed earn vaults.',
1669
- schema: schema.getEarnVaults.Response,
1670
- },
1671
- }),
1672
- summary: 'List vaults',
1673
- tags: ['Earn'],
1674
- }),
1675
- // Live state and rate enrichment are embedded, so every vault read caches
1676
- // as current-state rather than slow-changing metadata.
1677
- Cache.response<App.Environment>({
1678
- cacheControl: Cache.policies.state,
1679
- key: (c) => vaultCacheKey(c, schema.getEarnVaults.Query),
1680
- name: 'tempo-api:earn-vaults:v5',
1681
- }),
1682
- async (c) => {
1683
- if (Auth.narrowAccess) return Auth.paidAccessError(c)
1684
- if (OpenApi.narrowValidation)
1685
- return Response.error(c, {
1686
- code: 'chain_id_invalid',
1687
- message: 'Invalid chain id',
1688
- status: 400,
1689
- })
1690
- if (OpenApi.narrowValidation)
1691
- return Response.error(c, {
1692
- code: 'chain_id_unsupported',
1693
- message: 'Unsupported chain id',
1694
- status: 400,
1695
- })
1696
- if (OpenApi.narrowValidation)
1697
- return OpenApi.validationError(c, {
1698
- code: 'query_invalid',
1699
- message: 'Invalid query parameters',
1700
- })
1701
-
1702
- const query = c.req.valid('query')
1703
- try {
1704
- const chainId = query.chainId ?? c.get('chainId')
1705
- const data = await listVaults(c, { ...query, chainId, oracle })
1706
- return c.json(Response.validated(schema.getEarnVaults.Response, data), 200)
1707
- } catch (cause) {
1708
- return Response.upstream(c, cause)
1709
- }
1710
- },
1711
- )
1712
- .get(
1713
- '/v1/earn/vaults/verified',
1714
- Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
1715
- OpenApi.validate('query', schema.getVerifiedEarnVaults.Query, {
1716
- code: 'query_invalid',
1717
- message: 'Invalid query parameters',
1718
- }),
1719
- OpenApi.describeRoute({
1720
- description:
1721
- 'Lists registry-curated earn vaults after resolving their current onchain configuration.',
1722
- operationId: 'getVerifiedEarnVaults',
1723
- responses: OpenApi.responses({
1724
- errors: {
1725
- 400: {
1726
- codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
1727
- },
1728
- 502: 'Could not read curated earn registry or vault data.',
1729
- },
1730
- success: {
1731
- description: 'A page of registry-curated earn vaults.',
1732
- schema: schema.getVerifiedEarnVaults.Response,
1733
- },
1734
- }),
1735
- summary: 'List verified vaults',
1736
- tags: ['Earn'],
1737
- }),
1738
- Cache.response<App.Environment>({
1739
- cacheControl: Cache.policies.state,
1740
- key: (c) => vaultCacheKey(c, schema.getVerifiedEarnVaults.Query),
1741
- name: 'tempo-api:earn-vaults:v4',
1742
- }),
1743
- async (c) => {
1744
- if (Auth.narrowAccess) return Auth.paidAccessError(c)
1745
- if (OpenApi.narrowValidation)
1746
- return Response.error(c, {
1747
- code: 'chain_id_invalid',
1748
- message: 'Invalid chain id',
1749
- status: 400,
1750
- })
1751
- if (OpenApi.narrowValidation)
1752
- return Response.error(c, {
1753
- code: 'chain_id_unsupported',
1754
- message: 'Unsupported chain id',
1755
- status: 400,
1756
- })
1757
- if (OpenApi.narrowValidation)
1758
- return OpenApi.validationError(c, {
1759
- code: 'query_invalid',
1760
- message: 'Invalid query parameters',
1761
- })
1762
-
1763
- const query = c.req.valid('query')
1764
- try {
1765
- const chainId = query.chainId ?? c.get('chainId')
1766
- const data = await listVerifiedVaults(c, {
1767
- ...query,
1768
- chainId,
1769
- oracle,
1770
- })
1771
- return c.json(Response.validated(schema.getVerifiedEarnVaults.Response, data), 200)
1772
- } catch (cause) {
1773
- return Response.upstream(c, cause)
1774
- }
1775
- },
1776
- )
1777
1614
  .get(
1778
1615
  '/v1/earn/addresses/:address/positions',
1779
1616
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
@@ -2310,8 +2147,13 @@ export function earn(options: earn.Options = {}) {
2310
2147
  }),
2311
2148
  Cache.response<App.Environment>({
2312
2149
  cacheControl: Cache.policies.state,
2313
- key: (c) => vaultCacheKey(c, schema.getEarnVault.Query),
2314
- name: 'tempo-api:earn-vaults:v4',
2150
+ key: (c) => {
2151
+ const url = new URL(vaultCacheKey(c, schema.getEarnVault.Query))
2152
+ // The outer edge cache uses this URL, not the inner cache namespace.
2153
+ url.searchParams.set('cache', vaultCacheName)
2154
+ return url.toString()
2155
+ },
2156
+ name: vaultCacheName,
2315
2157
  }),
2316
2158
  async (c) => {
2317
2159
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -2357,6 +2199,8 @@ export function earn(options: earn.Options = {}) {
2357
2199
  message: 'Earn vault not found',
2358
2200
  status: 404,
2359
2201
  })
2202
+ // A Zone access refusal (`ZoneAccess.visible`) is no upstream failure; it keeps its own status and code.
2203
+ if (cause instanceof HTTPException) throw cause
2360
2204
  return Response.upstream(c, cause)
2361
2205
  }
2362
2206
  },
@@ -3367,273 +3211,6 @@ declare namespace getActiveCostBasis {
3367
3211
  }
3368
3212
  }
3369
3213
 
3370
- /** Lists compatible deployed Earn vaults. */
3371
- export async function listVaults(c: Context<App.Environment>, options: listVaults.Options) {
3372
- const db = Db.get(c.get('dbCached'))
3373
- const [records, snapshot] = await Promise.all([
3374
- core_EarnVaults.list(db, { chainId: options.chainId }),
3375
- VerifiedTokens.snapshot(c, options.chainId),
3376
- ])
3377
- const include = vaultInclude(options)
3378
- const apyByVault = new Map<string, EarnRates.Apy | null>()
3379
- const registry = new Map(records.map((record) => [record.vaultAddress.toLowerCase(), record]))
3380
- const decoded = options.cursor ? Cursor.decode(options.cursor, ['int', 'int']) : undefined
3381
- let position = decoded
3382
- ? ([Number(decoded[0]), Number(decoded[1])] as listVaults.Position)
3383
- : undefined
3384
- let hasMore = false
3385
- let scanned = 0
3386
- const matches: listVaults.Match[] = []
3387
-
3388
- while (matches.length <= options.limit && scanned < maxScannedDeployments) {
3389
- const page = await queryDeployments(c, {
3390
- asset: options.asset,
3391
- chainId: options.chainId,
3392
- cursor: position,
3393
- limit: discoveryBatchLimit({
3394
- filtered: options.capability.length > 0 || options['engine.type'] !== undefined,
3395
- limit: options.limit,
3396
- matches: matches.length,
3397
- remaining: maxScannedDeployments - scanned,
3398
- }),
3399
- })
3400
- hasMore = page.hasMore
3401
- if (page.items.length === 0) {
3402
- hasMore = false
3403
- break
3404
- }
3405
- scanned += page.items.length
3406
-
3407
- const apyVaults =
3408
- apyByVault.size === 0 &&
3409
- include.includes('apy') &&
3410
- options.capability.length === 0 &&
3411
- options['engine.type'] === undefined
3412
- ? page.items
3413
- .slice(0, options.limit - matches.length)
3414
- .map(({ vaultAddress }) => vaultAddress)
3415
- : []
3416
- // Rate boundaries and historical quotes depend only on candidate addresses,
3417
- // so the unfiltered page can resolve them alongside live vault discovery.
3418
- const [discovered, prefetchedApy] = await Promise.all([
3419
- Promise.all(
3420
- page.items.map(async (item) => {
3421
- const record = registry.get(item.vaultAddress.toLowerCase())
3422
- try {
3423
- const discovered = await resolveVaultDiscovery(c, {
3424
- chainId: options.chainId,
3425
- include: discoveryInclude(options),
3426
- vaultAddress: item.vaultAddress,
3427
- })
3428
- const { discovery, zoneRoutes } = await resolveVaultRoutes(c, {
3429
- capability: options.capability,
3430
- discovery: discovered,
3431
- include,
3432
- record,
3433
- })
3434
- return { discovery, position: item.position, record, zoneRoutes }
3435
- } catch (cause) {
3436
- if (!record && isIncompatible(cause)) return undefined
3437
- throw cause
3438
- }
3439
- }),
3440
- ),
3441
- apyVaults.length > 0
3442
- ? resolvePageApy(c, {
3443
- chainId: options.chainId,
3444
- include,
3445
- vaults: apyVaults,
3446
- window: options['apy.window'],
3447
- })
3448
- : undefined,
3449
- ])
3450
- for (const [vault, apy] of prefetchedApy ?? []) apyByVault.set(vault, apy)
3451
- for (const match of discovered) {
3452
- if (!match || !matchesVaultFilters(match.discovery, options)) continue
3453
- matches.push(match)
3454
- }
3455
-
3456
- position = page.items.at(-1)!.position
3457
- if (!hasMore) break
3458
- }
3459
-
3460
- const page = matches.slice(0, options.limit)
3461
- const discoveries = page.map(({ discovery }) => discovery)
3462
- const missingApyVaults = include.includes('apy')
3463
- ? discoveries.flatMap(({ vaultAddress }) =>
3464
- apyByVault.has(vaultAddress.toLowerCase()) ? [] : [vaultAddress],
3465
- )
3466
- : []
3467
- const [missingApy, rates, rewards, tokens] = await Promise.all([
3468
- missingApyVaults.length > 0
3469
- ? resolvePageApy(c, {
3470
- chainId: options.chainId,
3471
- include,
3472
- vaults: missingApyVaults,
3473
- window: options['apy.window'],
3474
- })
3475
- : undefined,
3476
- resolvePageRates(c, { discoveries, include, oracle: options.oracle, snapshot }),
3477
- resolvePageRewards(c, {
3478
- chainId: options.chainId,
3479
- include,
3480
- vaults: discoveries.map(({ vaultAddress }) => vaultAddress),
3481
- }),
3482
- resolvePageTokens(c, { chainId: options.chainId, discoveries, include, snapshot }),
3483
- ])
3484
- for (const [vault, apy] of missingApy ?? []) apyByVault.set(vault, apy)
3485
- const apy = include.includes('apy') ? apyByVault : undefined
3486
- const data = await Promise.all(
3487
- page.map((match) =>
3488
- resolveVault(c, {
3489
- ...match,
3490
- apy,
3491
- include,
3492
- rates,
3493
- rewards: rewards?.get(match.discovery.vaultAddress),
3494
- snapshot,
3495
- tokens,
3496
- }),
3497
- ),
3498
- )
3499
- const last = matches[options.limit - 1]
3500
- const nextPosition =
3501
- matches.length > options.limit ? last?.position : hasMore ? position : undefined
3502
- return {
3503
- data,
3504
- ...(rates ? { meta: { valuation: Valuation.pricing(rates, options.oracle) } } : {}),
3505
- nextCursor: nextPosition ? Cursor.encode(nextPosition) : null,
3506
- }
3507
- }
3508
-
3509
- export declare namespace listVaults {
3510
- /** One compatible deployment found while scanning TIDX. */
3511
- type Match = {
3512
- discovery: EarnVaults.Discovery
3513
- position: Position
3514
- record?: RegistryRecord | undefined
3515
- zoneRoutes: readonly EarnVaults.ResolvedZoneRoute[]
3516
- }
3517
-
3518
- /** Options for listing compatible Earn vaults. */
3519
- type Options = z.output<typeof schema.getEarnVaults.Query> & {
3520
- chainId: z.output<typeof Schema.ChainId>
3521
- /** FX rate oracle backing TVL valuation. */
3522
- oracle: FxOracle.Oracle
3523
- }
3524
-
3525
- /** TIDX deployment cursor position. */
3526
- type Position = [number, number]
3527
- }
3528
-
3529
- /** Lists registry-curated Earn vaults. */
3530
- export async function listVerifiedVaults(
3531
- c: Context<App.Environment>,
3532
- options: listVerifiedVaults.Options,
3533
- ) {
3534
- const db = Db.get(c.get('dbCached'))
3535
- const [records, snapshot] = await Promise.all([
3536
- core_EarnVaults.list(db, { chainId: options.chainId }),
3537
- VerifiedTokens.snapshot(c, options.chainId),
3538
- ])
3539
- const decoded = options.cursor ? Cursor.decode(options.cursor, ['address']) : undefined
3540
- const cursor = decoded?.[0]?.toString().toLowerCase()
3541
- const candidates = records.filter(
3542
- (record) => !cursor || record.vaultAddress.toLowerCase() > cursor,
3543
- )
3544
- const include = vaultInclude(options)
3545
- const matches: listVerifiedVaults.Match[] = []
3546
-
3547
- let offset = 0
3548
- while (offset < candidates.length && matches.length <= options.limit) {
3549
- const batchSize = discoveryBatchLimit({
3550
- filtered: options.capability.length > 0 || options['engine.type'] !== undefined,
3551
- limit: options.limit,
3552
- matches: matches.length,
3553
- remaining: candidates.length - offset,
3554
- })
3555
- const batch = candidates.slice(offset, offset + batchSize)
3556
- offset += batch.length
3557
- const discovered = await Promise.all(
3558
- batch.map(async (record) => {
3559
- const discovered = await resolveVaultDiscovery(c, {
3560
- chainId: options.chainId,
3561
- include: discoveryInclude(options),
3562
- vaultAddress: Schema.Address.parse(record.vaultAddress.toLowerCase()),
3563
- })
3564
- const { discovery, zoneRoutes } = await resolveVaultRoutes(c, {
3565
- capability: options.capability,
3566
- discovery: discovered,
3567
- include,
3568
- record,
3569
- })
3570
- return { discovery, record, zoneRoutes }
3571
- }),
3572
- )
3573
- for (const match of discovered) {
3574
- if (!matchesVaultFilters(match.discovery, options)) continue
3575
- matches.push(match)
3576
- }
3577
- }
3578
-
3579
- const page = matches.slice(0, options.limit)
3580
- const discoveries = page.map(({ discovery }) => discovery)
3581
- const [apy, rates, rewards, tokens] = await Promise.all([
3582
- resolvePageApy(c, {
3583
- chainId: options.chainId,
3584
- include,
3585
- vaults: discoveries.map(({ vaultAddress }) => vaultAddress),
3586
- window: options['apy.window'],
3587
- }),
3588
- resolvePageRates(c, { discoveries, include, oracle: options.oracle, snapshot }),
3589
- resolvePageRewards(c, {
3590
- chainId: options.chainId,
3591
- include,
3592
- vaults: discoveries.map(({ vaultAddress }) => vaultAddress),
3593
- }),
3594
- resolvePageTokens(c, { chainId: options.chainId, discoveries, include, snapshot }),
3595
- ])
3596
- const data = await Promise.all(
3597
- page.map(async (match) =>
3598
- Response.validated(
3599
- schema.VerifiedVault,
3600
- await resolveVault(c, {
3601
- ...match,
3602
- apy,
3603
- include,
3604
- rates,
3605
- rewards: rewards?.get(match.discovery.vaultAddress),
3606
- snapshot,
3607
- tokens,
3608
- }),
3609
- ),
3610
- ),
3611
- )
3612
- const last = matches[options.limit - 1]
3613
- return {
3614
- data,
3615
- ...(rates ? { meta: { valuation: Valuation.pricing(rates, options.oracle) } } : {}),
3616
- nextCursor:
3617
- matches.length > options.limit && last ? Cursor.encode([last.record.vaultAddress]) : null,
3618
- }
3619
- }
3620
-
3621
- export declare namespace listVerifiedVaults {
3622
- /** One verified vault and its current onchain state. */
3623
- type Match = {
3624
- discovery: EarnVaults.Discovery
3625
- record: RegistryRecord
3626
- zoneRoutes: readonly EarnVaults.ResolvedZoneRoute[]
3627
- }
3628
-
3629
- /** Options for listing verified Earn vaults. */
3630
- type Options = z.output<typeof schema.getVerifiedEarnVaults.Query> & {
3631
- chainId: z.output<typeof Schema.ChainId>
3632
- /** FX rate oracle backing TVL valuation. */
3633
- oracle: FxOracle.Oracle
3634
- }
3635
- }
3636
-
3637
3214
  /** Reads daily historical share prices for one Earn vault. */
3638
3215
  export async function getVaultSharePrices(
3639
3216
  c: Context<App.Environment>,
@@ -4914,7 +4491,7 @@ export async function getVault(c: Context<App.Environment>, options: getVault.Op
4914
4491
  try {
4915
4492
  const discovered = await resolveVaultDiscovery(c, {
4916
4493
  chainId: options.chainId,
4917
- include: discoveryInclude({ capability: [], include: options.include }),
4494
+ include: discoveryInclude({ include: options.include }),
4918
4495
  vaultAddress: options.vaultAddress,
4919
4496
  })
4920
4497
  const include = vaultInclude(options)
@@ -5008,9 +4585,7 @@ function discoveryInclude(
5008
4585
  options: discoveryInclude.Options,
5009
4586
  ): readonly EarnVaults.resolve.Include[] {
5010
4587
  const includeCapabilities =
5011
- options.include.includes('capabilities') ||
5012
- options.include.includes('zone') ||
5013
- options.capability.length > 0
4588
+ options.include.includes('capabilities') || options.include.includes('zone')
5014
4589
  return [
5015
4590
  ...(options.include.includes('access') ? (['access'] as const) : []),
5016
4591
  ...(includeCapabilities ? (['capabilities'] as const) : []),
@@ -5018,7 +4593,7 @@ function discoveryInclude(
5018
4593
  }
5019
4594
 
5020
4595
  declare namespace discoveryInclude {
5021
- type Options = Pick<z.output<typeof schema.getEarnVaults.Query>, 'capability' | 'include'>
4596
+ type Options = Pick<z.output<typeof schema.getEarnVault.Query>, 'include'>
5022
4597
  }
5023
4598
 
5024
4599
  async function resolveVaultDiscovery(
@@ -5076,11 +4651,13 @@ async function resolveVaultRoutes(
5076
4651
  options.include.includes('capabilities') ||
5077
4652
  options.capability.includes('privateRouting') ||
5078
4653
  options.capability.includes('routerSwaps')
5079
- const visibleRoutes = record.zones.filter(
5080
- (route) => ZoneAccess.check(c, { chainId: route.chainId, verb: 'read' }).allowed,
5081
- )
5082
- // Capabilities describe the vault; API-key scopes limit only the route metadata.
5083
- const routes = needsCapabilities ? record.zones : includesRoutes ? visibleRoutes : []
4654
+ await ZoneAccess.ensure(c)
4655
+ // Capabilities describe the vault; API-key scopes limit only the route metadata, checked only when requested.
4656
+ const routes = needsCapabilities
4657
+ ? record.zones
4658
+ : includesRoutes
4659
+ ? record.zones.filter((route) => ZoneAccess.visible(c, { chainId: route.chainId }))
4660
+ : []
5084
4661
  if (routes.length === 0) return { discovery, zoneRoutes: [] }
5085
4662
 
5086
4663
  const resolved = await EarnVaults.resolveZoneRoutes({
@@ -5097,16 +4674,14 @@ async function resolveVaultRoutes(
5097
4674
  ? { ...discovery, capabilities: EarnVaults.addZoneRouteCapabilities(capabilities) }
5098
4675
  : discovery,
5099
4676
  zoneRoutes: includesRoutes
5100
- ? resolved.filter(
5101
- (route) => ZoneAccess.check(c, { chainId: route.chainId, verb: 'read' }).allowed,
5102
- )
4677
+ ? resolved.filter((route) => ZoneAccess.visible(c, { chainId: route.chainId }))
5103
4678
  : [],
5104
4679
  }
5105
4680
  }
5106
4681
 
5107
4682
  declare namespace resolveVaultRoutes {
5108
4683
  type Options = {
5109
- capability: z.output<typeof schema.getEarnVaults.Query>['capability']
4684
+ capability: z.output<typeof schema.VaultCollectionQuery>['capability']
5110
4685
  discovery: EarnVaults.Discovery
5111
4686
  include: z.output<typeof schema.getEarnVault.Query>['include']
5112
4687
  record?: RegistryRecord | undefined
@@ -5289,27 +4864,6 @@ function resolvePageApy(c: Context<App.Environment>, options: resolvePageApy.Opt
5289
4864
  )
5290
4865
  }
5291
4866
 
5292
- function resolvePageRewards(c: Context<App.Environment>, options: resolvePageRewards.Options) {
5293
- if (!options.include.includes('apy')) return undefined
5294
- return Timing.time(c, 'earn_rewards_apy', () =>
5295
- RewardRead.resolveCollection({
5296
- chainId: options.chainId,
5297
- db: c.get('dbCached'),
5298
- vaults: options.vaults,
5299
- }).catch(() => {
5300
- Cache.setPolicy(c, Cache.policies.noStore)
5301
- const failure = {
5302
- chainId: options.chainId,
5303
- failure: 'unknown',
5304
- id: 'earn-rewards',
5305
- operation: 'listVaultRewards',
5306
- } satisfies Log.ProviderFailure
5307
- c.set('providerFailures', [...(c.get('providerFailures') ?? []), failure])
5308
- return new Map<string, readonly RewardRead.Reward[]>()
5309
- }),
5310
- )
5311
- }
5312
-
5313
4867
  function resolveVaultRewards(c: Context<App.Environment>, options: resolveVaultRewards.Options) {
5314
4868
  if (!options.include.includes('apy')) return undefined
5315
4869
  return Timing.time(c, 'earn_rewards_apy', () =>
@@ -5339,14 +4893,6 @@ declare namespace resolveVaultRewards {
5339
4893
  }
5340
4894
  }
5341
4895
 
5342
- declare namespace resolvePageRewards {
5343
- type Options = {
5344
- chainId: z.output<typeof Schema.ChainId>
5345
- include: z.output<typeof schema.getEarnVault.Query>['include']
5346
- vaults: readonly z.output<typeof Schema.Address>[]
5347
- }
5348
- }
5349
-
5350
4896
  declare namespace resolvePageApy {
5351
4897
  type Options = {
5352
4898
  chainId: z.output<typeof Schema.ChainId>
@@ -5413,9 +4959,11 @@ declare namespace resolvePageTokens {
5413
4959
 
5414
4960
  async function resolveVault(c: Context<App.Environment>, options: resolveVault.Options) {
5415
4961
  const { discovery, record } = options
5416
- const zones = [...c.get('zones').values()].filter(
5417
- (zone) => ZoneAccess.check(c, { chainId: zone.id, verb: 'read' }).allowed,
5418
- )
4962
+ await ZoneAccess.ensure(c)
4963
+ // Only `include=zone` reads Zones, so other reads never fail on an unreadable delegation.
4964
+ const zones = options.include.includes('zone')
4965
+ ? [...c.get('zones').values()].filter((zone) => ZoneAccess.visible(c, { chainId: zone.id }))
4966
+ : []
5419
4967
  const valued = options.include.includes('tvl')
5420
4968
  ? Valuation.valuationFor({
5421
4969
  amount: BigInt(discovery.state.totalAssets),
@@ -5521,7 +5069,6 @@ export function serializeVault(options: serializeVault.Options): z.output<typeof
5521
5069
  ...(options.include.includes('apy') ? { apy } : {}),
5522
5070
  assetToken: options.assetToken,
5523
5071
  ...(options.include.includes('capabilities') ? { capabilities: discovery.capabilities } : {}),
5524
- description: record?.description ?? null,
5525
5072
  engine: {
5526
5073
  address: discovery.engine.address.toLowerCase(),
5527
5074
  type: discovery.engine.type,
@@ -5532,7 +5079,7 @@ export function serializeVault(options: serializeVault.Options): z.output<typeof
5532
5079
  ...(options.include.includes('tvl')
5533
5080
  ? { instantLiquidityValue: options.instantLiquidityValue }
5534
5081
  : {}),
5535
- label: record?.label ?? options.shareToken.name,
5082
+ label: '',
5536
5083
  sharePrice:
5537
5084
  discovery.sharePrice === null
5538
5085
  ? null
@@ -5543,7 +5090,6 @@ export function serializeVault(options: serializeVault.Options): z.output<typeof
5543
5090
  formatted: core_Value.format(BigInt(discovery.sharePrice), options.assetToken.decimals),
5544
5091
  },
5545
5092
  shareToken: options.shareToken,
5546
- slug: record?.slug ?? null,
5547
5093
  state: discovery.state,
5548
5094
  ...(options.include.includes('tvl') ? { tvl: options.tvl } : {}),
5549
5095
  vaultAddress,
@@ -5645,101 +5191,6 @@ function getToken(
5645
5191
  return Response.validated(Tokens.schema.Token, token)
5646
5192
  }
5647
5193
 
5648
- async function queryDeployments(
5649
- c: Context<App.Environment>,
5650
- options: queryDeployments.Options,
5651
- ): Promise<queryDeployments.Result> {
5652
- const factories = deploymentFactories[options.chainId] ?? []
5653
- if (factories.length === 0) return { hasMore: false, items: [] }
5654
- const filters: string[] = []
5655
- if (options.asset) filters.push(`lower(asset) = '${options.asset.toLowerCase()}'`)
5656
- if (options.cursor)
5657
- filters.push(
5658
- Cursor.keyset([
5659
- {
5660
- literal: Cursor.literal(options.cursor[0], 'int'),
5661
- name: 'block_num',
5662
- order: 'desc',
5663
- },
5664
- {
5665
- literal: Cursor.literal(options.cursor[1], 'int'),
5666
- name: 'log_idx',
5667
- order: 'desc',
5668
- },
5669
- ]),
5670
- )
5671
-
5672
- // Authenticate emitters before deduplication so a forged newer event cannot
5673
- // replace a factory deployment or suppress it through outer filters.
5674
- const result = await c
5675
- .get('getTidx')(options.chainId)
5676
- .fetch({
5677
- chainId: options.chainId,
5678
- engine: 'clickhouse',
5679
- query: `
5680
- SELECT "earnVault", asset, block_num, log_idx
5681
- FROM (
5682
- SELECT
5683
- "earnVault",
5684
- asset,
5685
- block_num,
5686
- log_idx
5687
- FROM EarnStackDeployed
5688
- WHERE address IN (${factories.map((address) => `'${address}'`).join(', ')})
5689
- ORDER BY block_num DESC, log_idx DESC
5690
- LIMIT 1 BY lower("earnVault")
5691
- )
5692
- ${filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : ''}
5693
- ORDER BY block_num DESC, log_idx DESC
5694
- LIMIT ${options.limit + 1}
5695
- ` as string,
5696
- signatures: [deployedSignature],
5697
- })
5698
-
5699
- const rows: readonly Record<string, unknown>[] = result.rows
5700
- const items = rows.slice(0, options.limit).map((row) => {
5701
- const vaultAddress = Schema.Address.safeParse(Value.toText(row['earnVault']))
5702
- const asset = Schema.Address.safeParse(Value.toText(row['asset']))
5703
- const blockNumber = Value.toNumber(row['block_num'])
5704
- const logIndex = Value.toNumber(row['log_idx'])
5705
- if (
5706
- !vaultAddress.success ||
5707
- !asset.success ||
5708
- blockNumber === undefined ||
5709
- logIndex === undefined
5710
- )
5711
- throw new Error('TIDX returned an invalid Earn deployment row.')
5712
- return {
5713
- asset: asset.data,
5714
- position: [blockNumber, logIndex] as queryDeployments.Position,
5715
- vaultAddress: vaultAddress.data,
5716
- }
5717
- })
5718
- return { hasMore: rows.length > options.limit, items }
5719
- }
5720
-
5721
- declare namespace queryDeployments {
5722
- type Item = {
5723
- asset: z.output<typeof Schema.Address>
5724
- position: Position
5725
- vaultAddress: z.output<typeof Schema.Address>
5726
- }
5727
-
5728
- type Options = {
5729
- asset?: z.output<typeof Schema.Address> | undefined
5730
- chainId: z.output<typeof Schema.ChainId>
5731
- cursor?: Position | undefined
5732
- limit: number
5733
- }
5734
-
5735
- type Position = [number, number]
5736
-
5737
- type Result = {
5738
- hasMore: boolean
5739
- items: readonly Item[]
5740
- }
5741
- }
5742
-
5743
5194
  /** Tests live vault state against the shared collection filters. */
5744
5195
  export function matchesVaultFilters(
5745
5196
  discovery: EarnVaults.Discovery,
@@ -5758,7 +5209,7 @@ export function matchesVaultFilters(
5758
5209
  export declare namespace matchesVaultFilters {
5759
5210
  /** Filters shared by the all-vault and verified-vault collections. */
5760
5211
  type Options = Pick<
5761
- z.output<typeof schema.getEarnVaults.Query>,
5212
+ z.output<typeof schema.VaultCollectionQuery>,
5762
5213
  'asset' | 'capability' | 'engine.type'
5763
5214
  >
5764
5215
  }