tapimo 0.12.0 → 0.14.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 (398) hide show
  1. package/dist/App.d.ts +11333 -9563
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +39 -3
  4. package/dist/App.js.map +1 -1
  5. package/dist/Scope.d.ts +2 -0
  6. package/dist/Scope.d.ts.map +1 -1
  7. package/dist/Scope.js +17 -0
  8. package/dist/Scope.js.map +1 -1
  9. package/dist/Webhooks.js +2 -2
  10. package/dist/Webhooks.js.map +1 -1
  11. package/dist/admin/App.d.ts +1064 -924
  12. package/dist/admin/App.d.ts.map +1 -1
  13. package/dist/admin/apps/api-keys.d.ts +80 -0
  14. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  15. package/dist/admin/apps/api-keys.js +54 -0
  16. package/dist/admin/apps/api-keys.js.map +1 -1
  17. package/dist/admin/apps/earn-vaults.d.ts +63 -15
  18. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  19. package/dist/admin/apps/earn-vaults.js +2 -1
  20. package/dist/admin/apps/earn-vaults.js.map +1 -1
  21. package/dist/admin/apps/organizations.d.ts +92 -3
  22. package/dist/admin/apps/organizations.d.ts.map +1 -1
  23. package/dist/admin/apps/organizations.js +69 -7
  24. package/dist/admin/apps/organizations.js.map +1 -1
  25. package/dist/admin/apps/verified-tokens.d.ts +7 -7
  26. package/dist/admin/ui.generated.d.ts +1 -1
  27. package/dist/admin/ui.generated.d.ts.map +1 -1
  28. package/dist/admin/ui.generated.js +151 -151
  29. package/dist/admin/ui.generated.js.map +1 -1
  30. package/dist/apps/Zones.d.ts +28 -28
  31. package/dist/apps/Zones.js +7 -7
  32. package/dist/apps/data/App.d.ts +2909 -2523
  33. package/dist/apps/data/App.d.ts.map +1 -1
  34. package/dist/apps/data/App.js +26 -21
  35. package/dist/apps/data/App.js.map +1 -1
  36. package/dist/apps/data/ZoneSelection.d.ts +8 -8
  37. package/dist/apps/data/ZoneSelection.d.ts.map +1 -1
  38. package/dist/apps/data/ZoneSelection.js +1 -1
  39. package/dist/apps/data/ZoneSelection.js.map +1 -1
  40. package/dist/apps/data/routes/activities.d.ts +588 -584
  41. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  42. package/dist/apps/data/routes/activities.js +1561 -1239
  43. package/dist/apps/data/routes/activities.js.map +1 -1
  44. package/dist/apps/data/routes/addresses.d.ts +22 -22
  45. package/dist/apps/data/routes/balances.d.ts +26 -26
  46. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  47. package/dist/apps/data/routes/balances.js +43 -16
  48. package/dist/apps/data/routes/balances.js.map +1 -1
  49. package/dist/apps/data/routes/blocks.d.ts +44 -44
  50. package/dist/apps/data/routes/blocks.d.ts.map +1 -1
  51. package/dist/apps/data/routes/blocks.js +21 -11
  52. package/dist/apps/data/routes/blocks.js.map +1 -1
  53. package/dist/apps/data/routes/coingecko.d.ts +3 -3
  54. package/dist/apps/data/routes/earn.d.ts +201 -25
  55. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  56. package/dist/apps/data/routes/earn.js +434 -75
  57. package/dist/apps/data/routes/earn.js.map +1 -1
  58. package/dist/apps/data/routes/exchanges.d.ts +160 -145
  59. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  60. package/dist/apps/data/routes/exchanges.js +180 -114
  61. package/dist/apps/data/routes/exchanges.js.map +1 -1
  62. package/dist/apps/data/routes/fee-amm.d.ts +2 -2
  63. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  64. package/dist/apps/data/routes/fee-amm.js +18 -19
  65. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  66. package/dist/apps/data/routes/receipts.d.ts +155 -55
  67. package/dist/apps/data/routes/receipts.d.ts.map +1 -1
  68. package/dist/apps/data/routes/receipts.js +28 -10
  69. package/dist/apps/data/routes/receipts.js.map +1 -1
  70. package/dist/apps/data/routes/tokenlist.d.ts +13 -13
  71. package/dist/apps/data/routes/tokens.d.ts +5 -5
  72. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  73. package/dist/apps/data/routes/tokens.js +51 -20
  74. package/dist/apps/data/routes/tokens.js.map +1 -1
  75. package/dist/apps/data/routes/transactions.d.ts +7 -2
  76. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  77. package/dist/apps/data/routes/transactions.js +37 -17
  78. package/dist/apps/data/routes/transactions.js.map +1 -1
  79. package/dist/apps/data/routes/transfers.d.ts +13 -13
  80. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  81. package/dist/apps/data/routes/transfers.js +18 -12
  82. package/dist/apps/data/routes/transfers.js.map +1 -1
  83. package/dist/apps/data/routes/valuation.d.ts +31 -31
  84. package/dist/apps/data/routes/valuation.d.ts.map +1 -1
  85. package/dist/apps/data/routes/valuation.js +12 -7
  86. package/dist/apps/data/routes/valuation.js.map +1 -1
  87. package/dist/apps/data/routes/verified-tokens.d.ts +8 -8
  88. package/dist/apps/data/routes/webhooks.d.ts +816 -113
  89. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  90. package/dist/apps/data/routes/webhooks.js +47 -5
  91. package/dist/apps/data/routes/webhooks.js.map +1 -1
  92. package/dist/apps/data/routes/zones.d.ts +14 -14
  93. package/dist/apps/data/routes/zones.js +1 -1
  94. package/dist/apps/funding/App.d.ts +466 -44
  95. package/dist/apps/funding/App.d.ts.map +1 -1
  96. package/dist/apps/funding/App.js +1 -1
  97. package/dist/apps/funding/App.js.map +1 -1
  98. package/dist/apps/funding/routes/deposit-addresses.d.ts +17 -17
  99. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  100. package/dist/apps/funding/routes/deposit-addresses.js +17 -12
  101. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  102. package/dist/apps/funding/routes/transfers.d.ts +650 -57
  103. package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
  104. package/dist/apps/funding/routes/transfers.js +238 -24
  105. package/dist/apps/funding/routes/transfers.js.map +1 -1
  106. package/dist/apps/management/App.d.ts +5120 -4152
  107. package/dist/apps/management/App.d.ts.map +1 -1
  108. package/dist/apps/management/Billing.d.ts +1 -1
  109. package/dist/apps/management/Billing.d.ts.map +1 -1
  110. package/dist/apps/management/Billing.js +17 -1
  111. package/dist/apps/management/Billing.js.map +1 -1
  112. package/dist/apps/management/routes/api-keys.d.ts +632 -81
  113. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  114. package/dist/apps/management/routes/api-keys.js +236 -4
  115. package/dist/apps/management/routes/api-keys.js.map +1 -1
  116. package/dist/apps/management/routes/billing.d.ts +76 -76
  117. package/dist/apps/management/routes/faucet.d.ts +6 -6
  118. package/dist/apps/management/routes/invitations.d.ts +24 -24
  119. package/dist/apps/management/routes/invite-links.d.ts +4 -4
  120. package/dist/apps/management/routes/members.d.ts +16 -16
  121. package/dist/apps/management/routes/orgs.d.ts +20 -20
  122. package/dist/apps/management/routes/projects.d.ts +4 -4
  123. package/dist/apps/management/routes/usage.d.ts +8 -8
  124. package/dist/apps/management/routes/verified-token-requests.d.ts +17 -17
  125. package/dist/apps/management/routes/webhooks.d.ts +675 -25
  126. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  127. package/dist/apps/management/routes/webhooks.js +21 -21
  128. package/dist/apps/management/routes/webhooks.js.map +1 -1
  129. package/dist/apps/relay/App.d.ts.map +1 -1
  130. package/dist/apps/relay/App.js +115 -23
  131. package/dist/apps/relay/App.js.map +1 -1
  132. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  133. package/dist/apps/relay/Sponsorships.js +27 -1
  134. package/dist/apps/relay/Sponsorships.js.map +1 -1
  135. package/dist/db/Db.d.ts.map +1 -1
  136. package/dist/db/Db.js +34 -1
  137. package/dist/db/Db.js.map +1 -1
  138. package/dist/db/Schema.d.ts +11 -5
  139. package/dist/db/Schema.d.ts.map +1 -1
  140. package/dist/db/Schema.js +21 -3
  141. package/dist/db/Schema.js.map +1 -1
  142. package/dist/db/tables/fundingCatalog.d.ts +4 -2
  143. package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
  144. package/dist/db/tables/fundingCatalog.js +5 -1
  145. package/dist/db/tables/fundingCatalog.js.map +1 -1
  146. package/dist/db/tables/fundingTransferTransactions.d.ts +38 -0
  147. package/dist/db/tables/fundingTransferTransactions.d.ts.map +1 -1
  148. package/dist/db/tables/fundingTransferTransactions.js +44 -3
  149. package/dist/db/tables/fundingTransferTransactions.js.map +1 -1
  150. package/dist/db/tables/fundingTransfers.d.ts +17 -0
  151. package/dist/db/tables/fundingTransfers.d.ts.map +1 -1
  152. package/dist/db/tables/fundingTransfers.js +21 -0
  153. package/dist/db/tables/fundingTransfers.js.map +1 -1
  154. package/dist/db/tables/organizations.d.ts +24 -0
  155. package/dist/db/tables/organizations.d.ts.map +1 -1
  156. package/dist/db/tables/organizations.js +27 -0
  157. package/dist/db/tables/organizations.js.map +1 -1
  158. package/dist/db/tables/projects.d.ts +25 -1
  159. package/dist/db/tables/projects.d.ts.map +1 -1
  160. package/dist/db/tables/projects.js +26 -0
  161. package/dist/db/tables/projects.js.map +1 -1
  162. package/dist/db/tables/sponsoredTransactions.d.ts +44 -0
  163. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  164. package/dist/db/tables/sponsoredTransactions.js +146 -13
  165. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  166. package/dist/db/tables/webhookSubscriptions.d.ts +10 -6
  167. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  168. package/dist/db/tables/webhookSubscriptions.js +9 -6
  169. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  170. package/dist/handlers/internal/utils.d.ts.map +1 -1
  171. package/dist/handlers/internal/utils.js +9 -0
  172. package/dist/handlers/internal/utils.js.map +1 -1
  173. package/dist/internal/Auth.d.ts +3 -1
  174. package/dist/internal/Auth.d.ts.map +1 -1
  175. package/dist/internal/Auth.js +6 -3
  176. package/dist/internal/Auth.js.map +1 -1
  177. package/dist/internal/EarnVaults.d.ts +3 -3
  178. package/dist/internal/EarnVaults.js +5 -5
  179. package/dist/internal/EarnVaults.js.map +1 -1
  180. package/dist/internal/Fetch.d.ts +23 -0
  181. package/dist/internal/Fetch.d.ts.map +1 -0
  182. package/dist/internal/Fetch.js +26 -0
  183. package/dist/internal/Fetch.js.map +1 -0
  184. package/dist/internal/Log.d.ts +4 -2
  185. package/dist/internal/Log.d.ts.map +1 -1
  186. package/dist/internal/Log.js +16 -3
  187. package/dist/internal/Log.js.map +1 -1
  188. package/dist/internal/OpenApi.d.ts +5 -3
  189. package/dist/internal/OpenApi.d.ts.map +1 -1
  190. package/dist/internal/OpenApi.js +13 -3
  191. package/dist/internal/OpenApi.js.map +1 -1
  192. package/dist/internal/Response.d.ts +1 -1
  193. package/dist/internal/Response.d.ts.map +1 -1
  194. package/dist/internal/Schema.d.ts +6 -3
  195. package/dist/internal/Schema.d.ts.map +1 -1
  196. package/dist/internal/Schema.js +8 -2
  197. package/dist/internal/Schema.js.map +1 -1
  198. package/dist/internal/Store.d.ts +16 -3
  199. package/dist/internal/Store.d.ts.map +1 -1
  200. package/dist/internal/Store.js +82 -16
  201. package/dist/internal/Store.js.map +1 -1
  202. package/dist/internal/Tidx.d.ts.map +1 -1
  203. package/dist/internal/Tidx.js +7 -2
  204. package/dist/internal/Tidx.js.map +1 -1
  205. package/dist/internal/Timeout.d.ts +36 -0
  206. package/dist/internal/Timeout.d.ts.map +1 -0
  207. package/dist/internal/Timeout.js +37 -0
  208. package/dist/internal/Timeout.js.map +1 -0
  209. package/dist/internal/Timing.d.ts +9 -0
  210. package/dist/internal/Timing.d.ts.map +1 -1
  211. package/dist/internal/Timing.js +7 -0
  212. package/dist/internal/Timing.js.map +1 -1
  213. package/dist/internal/Viem.d.ts +16 -1
  214. package/dist/internal/Viem.d.ts.map +1 -1
  215. package/dist/internal/Viem.js +12 -2
  216. package/dist/internal/Viem.js.map +1 -1
  217. package/dist/internal/WebhookDestination.d.ts.map +1 -1
  218. package/dist/internal/WebhookDestination.js +3 -0
  219. package/dist/internal/WebhookDestination.js.map +1 -1
  220. package/dist/internal/funding/Action.d.ts +9 -0
  221. package/dist/internal/funding/Action.d.ts.map +1 -1
  222. package/dist/internal/funding/Action.js +16 -8
  223. package/dist/internal/funding/Action.js.map +1 -1
  224. package/dist/internal/funding/Catalog.d.ts +9 -2
  225. package/dist/internal/funding/Catalog.d.ts.map +1 -1
  226. package/dist/internal/funding/Catalog.js +19 -8
  227. package/dist/internal/funding/Catalog.js.map +1 -1
  228. package/dist/internal/funding/DepositWebhook.d.ts.map +1 -1
  229. package/dist/internal/funding/DepositWebhook.js +2 -1
  230. package/dist/internal/funding/DepositWebhook.js.map +1 -1
  231. package/dist/internal/funding/Evidence.d.ts.map +1 -1
  232. package/dist/internal/funding/Evidence.js +2 -10
  233. package/dist/internal/funding/Evidence.js.map +1 -1
  234. package/dist/internal/funding/Provider.d.ts +108 -13
  235. package/dist/internal/funding/Provider.d.ts.map +1 -1
  236. package/dist/internal/funding/Provider.js +34 -8
  237. package/dist/internal/funding/Provider.js.map +1 -1
  238. package/dist/internal/funding/SourceObservation.d.ts.map +1 -1
  239. package/dist/internal/funding/SourceObservation.js +5 -7
  240. package/dist/internal/funding/SourceObservation.js.map +1 -1
  241. package/dist/internal/funding/Transfer.d.ts +114 -18
  242. package/dist/internal/funding/Transfer.d.ts.map +1 -1
  243. package/dist/internal/funding/Transfer.js +185 -55
  244. package/dist/internal/funding/Transfer.js.map +1 -1
  245. package/dist/internal/funding/TransferReconciliation.d.ts +52 -0
  246. package/dist/internal/funding/TransferReconciliation.d.ts.map +1 -0
  247. package/dist/internal/funding/TransferReconciliation.js +192 -0
  248. package/dist/internal/funding/TransferReconciliation.js.map +1 -0
  249. package/dist/internal/funding/TransferWebhook.d.ts +21 -0
  250. package/dist/internal/funding/TransferWebhook.d.ts.map +1 -0
  251. package/dist/internal/funding/TransferWebhook.js +43 -0
  252. package/dist/internal/funding/TransferWebhook.js.map +1 -0
  253. package/dist/internal/funding/index.d.ts +1 -0
  254. package/dist/internal/funding/index.d.ts.map +1 -1
  255. package/dist/internal/funding/index.js +1 -0
  256. package/dist/internal/funding/index.js.map +1 -1
  257. package/dist/internal/funding/providers/relay.d.ts.map +1 -1
  258. package/dist/internal/funding/providers/relay.js +3 -12
  259. package/dist/internal/funding/providers/relay.js.map +1 -1
  260. package/dist/internal/funding/providers/stargate.d.ts +127 -9
  261. package/dist/internal/funding/providers/stargate.d.ts.map +1 -1
  262. package/dist/internal/funding/providers/stargate.js +548 -112
  263. package/dist/internal/funding/providers/stargate.js.map +1 -1
  264. package/dist/internal/index.d.ts +1 -0
  265. package/dist/internal/index.d.ts.map +1 -1
  266. package/dist/internal/index.js +1 -0
  267. package/dist/internal/index.js.map +1 -1
  268. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
  269. package/dist/internal/webhookDestinations/slack.js +16 -0
  270. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  271. package/package.json +2 -2
  272. package/src/App.test.ts +100 -0
  273. package/src/App.ts +43 -3
  274. package/src/Client.test-d.ts +129 -2
  275. package/src/Scope.test.ts +20 -0
  276. package/src/Scope.ts +16 -0
  277. package/src/Webhooks.ts +2 -2
  278. package/src/admin/apps/api-keys.test.ts +75 -0
  279. package/src/admin/apps/api-keys.ts +64 -0
  280. package/src/admin/apps/earn-vaults.test.ts +1 -1
  281. package/src/admin/apps/earn-vaults.ts +2 -1
  282. package/src/admin/apps/organizations.test.ts +53 -1
  283. package/src/admin/apps/organizations.ts +90 -5
  284. package/src/admin/ui/src/lib/api-keys.ts +19 -0
  285. package/src/admin/ui/src/lib/organizations.test.ts +112 -1
  286. package/src/admin/ui/src/lib/organizations.ts +55 -0
  287. package/src/admin/ui/src/routes/api-keys.tsx +89 -2
  288. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +116 -0
  289. package/src/admin/ui.generated.ts +189 -151
  290. package/src/apps/Zones.test.ts +7 -7
  291. package/src/apps/Zones.ts +7 -7
  292. package/src/apps/composition.test.ts +2 -1
  293. package/src/apps/data/App.test.ts +41 -0
  294. package/src/apps/data/App.ts +30 -21
  295. package/src/apps/data/ZoneSelection.test.ts +2 -2
  296. package/src/apps/data/ZoneSelection.ts +8 -8
  297. package/src/apps/data/routes/activities.test.ts +1526 -12
  298. package/src/apps/data/routes/activities.ts +1774 -1356
  299. package/src/apps/data/routes/balances.ts +133 -97
  300. package/src/apps/data/routes/blocks.test.ts +533 -0
  301. package/src/apps/data/routes/blocks.ts +35 -16
  302. package/src/apps/data/routes/earn.test.ts +373 -16
  303. package/src/apps/data/routes/earn.ts +548 -79
  304. package/src/apps/data/routes/earn.zone-access.test.ts +6 -6
  305. package/src/apps/data/routes/exchanges.test.ts +740 -15
  306. package/src/apps/data/routes/exchanges.ts +954 -753
  307. package/src/apps/data/routes/fee-amm.ts +17 -18
  308. package/src/apps/data/routes/receipts.ts +47 -16
  309. package/src/apps/data/routes/tokens.test.ts +578 -0
  310. package/src/apps/data/routes/tokens.ts +283 -225
  311. package/src/apps/data/routes/transactions.ts +68 -29
  312. package/src/apps/data/routes/transfers.test.ts +421 -0
  313. package/src/apps/data/routes/transfers.ts +45 -27
  314. package/src/apps/data/routes/valuation.ts +94 -78
  315. package/src/apps/data/routes/webhooks.test.ts +21 -5
  316. package/src/apps/data/routes/webhooks.ts +63 -8
  317. package/src/apps/data/routes/zones.test.ts +2 -2
  318. package/src/apps/data/routes/zones.ts +1 -1
  319. package/src/apps/funding/App.ts +12 -2
  320. package/src/apps/funding/routes/deposit-addresses.test.ts +29 -7
  321. package/src/apps/funding/routes/deposit-addresses.ts +19 -14
  322. package/src/apps/funding/routes/quotes.test.ts +5 -9
  323. package/src/apps/funding/routes/transfers.test.ts +901 -23
  324. package/src/apps/funding/routes/transfers.ts +347 -64
  325. package/src/apps/management/Billing.ts +18 -5
  326. package/src/apps/management/routes/api-keys.test.ts +220 -0
  327. package/src/apps/management/routes/api-keys.ts +280 -3
  328. package/src/apps/management/routes/webhooks.test.ts +3 -3
  329. package/src/apps/management/routes/webhooks.ts +24 -25
  330. package/src/apps/relay/App.test.ts +212 -1
  331. package/src/apps/relay/App.ts +158 -29
  332. package/src/apps/relay/Sponsorships.ts +24 -1
  333. package/src/db/Db.ts +48 -1
  334. package/src/db/Schema.ts +22 -4
  335. package/src/db/tables/earnVaults.test.ts +9 -9
  336. package/src/db/tables/fundingCatalog.test.ts +16 -2
  337. package/src/db/tables/fundingCatalog.ts +9 -3
  338. package/src/db/tables/fundingTransferTransactions.test.ts +43 -0
  339. package/src/db/tables/fundingTransferTransactions.ts +79 -3
  340. package/src/db/tables/fundingTransfers.test.ts +26 -0
  341. package/src/db/tables/fundingTransfers.ts +36 -0
  342. package/src/db/tables/organizations.test.ts +41 -0
  343. package/src/db/tables/organizations.ts +49 -0
  344. package/src/db/tables/projects.test.ts +55 -0
  345. package/src/db/tables/projects.ts +46 -1
  346. package/src/db/tables/sponsoredTransactions.test.ts +338 -0
  347. package/src/db/tables/sponsoredTransactions.ts +197 -13
  348. package/src/db/tables/webhookSubscriptions.ts +18 -11
  349. package/src/handlers/internal/utils.test.ts +53 -0
  350. package/src/handlers/internal/utils.ts +15 -0
  351. package/src/internal/Auth.ts +12 -4
  352. package/src/internal/EarnVaults.capabilities.test.ts +2 -2
  353. package/src/internal/EarnVaults.test.ts +1 -1
  354. package/src/internal/EarnVaults.ts +5 -5
  355. package/src/internal/Fetch.test.ts +46 -0
  356. package/src/internal/Fetch.ts +56 -0
  357. package/src/internal/Log.test-d.ts +2 -0
  358. package/src/internal/Log.test.ts +21 -0
  359. package/src/internal/Log.ts +22 -5
  360. package/src/internal/OpenApi.ts +14 -4
  361. package/src/internal/Response.ts +1 -1
  362. package/src/internal/Schema.test.ts +2 -0
  363. package/src/internal/Schema.ts +12 -2
  364. package/src/internal/Store.test.ts +178 -0
  365. package/src/internal/Store.ts +104 -18
  366. package/src/internal/Tidx.test.ts +2 -1
  367. package/src/internal/Tidx.ts +7 -2
  368. package/src/internal/Timeout.test.ts +35 -0
  369. package/src/internal/Timeout.ts +73 -0
  370. package/src/internal/Timing.ts +16 -0
  371. package/src/internal/Viem.ts +39 -3
  372. package/src/internal/WebhookDestination.ts +3 -0
  373. package/src/internal/Webhooks.test.ts +45 -0
  374. package/src/internal/funding/Action.test.ts +41 -1
  375. package/src/internal/funding/Action.ts +69 -41
  376. package/src/internal/funding/Catalog.test.ts +34 -0
  377. package/src/internal/funding/Catalog.ts +28 -11
  378. package/src/internal/funding/DepositWebhook.ts +2 -1
  379. package/src/internal/funding/Evidence.ts +2 -13
  380. package/src/internal/funding/Provider.test.ts +73 -0
  381. package/src/internal/funding/Provider.ts +125 -28
  382. package/src/internal/funding/SourceObservation.ts +5 -9
  383. package/src/internal/funding/Transfer.test.ts +155 -0
  384. package/src/internal/funding/Transfer.ts +387 -147
  385. package/src/internal/funding/TransferReconciliation.test.ts +147 -0
  386. package/src/internal/funding/TransferReconciliation.ts +264 -0
  387. package/src/internal/funding/TransferWebhook.test.ts +128 -0
  388. package/src/internal/funding/TransferWebhook.ts +67 -0
  389. package/src/internal/funding/index.test.ts +1 -0
  390. package/src/internal/funding/index.ts +1 -0
  391. package/src/internal/funding/providers/index.test.ts +4 -167
  392. package/src/internal/funding/providers/relay.test.ts +2 -2
  393. package/src/internal/funding/providers/relay.ts +3 -15
  394. package/src/internal/funding/providers/stargate.test.ts +328 -0
  395. package/src/internal/funding/providers/stargate.ts +807 -135
  396. package/src/internal/index.test.ts +1 -0
  397. package/src/internal/index.ts +1 -0
  398. package/src/internal/webhookDestinations/slack.ts +15 -0
@@ -1,6 +1,6 @@
1
1
  import { type Context, Hono } from 'hono'
2
2
  import { Value as core_Value } from 'ox'
3
- import type { Actions } from 'viem/tempo'
3
+ import { Abis, type Actions } from 'viem/tempo'
4
4
  import {
5
5
  type Chain,
6
6
  ContractFunctionExecutionError,
@@ -130,7 +130,7 @@ export namespace schema {
130
130
  z.strictObject({
131
131
  address: Schema.Address.check(
132
132
  z.describe('Current vault engine contract address.'),
133
- z.meta({ examples: ['0xd85fc943333a6cd7c0e3391acd54fc4e572f0baf'] }),
133
+ z.meta({ examples: ['0x59d27987bc7cc1521bba5f688a170c65840cbf43'] }),
134
134
  ),
135
135
  type: z
136
136
  .nullable(engineType)
@@ -139,7 +139,7 @@ export namespace schema {
139
139
  .nullable(
140
140
  Schema.Address.check(
141
141
  z.describe('Yield venue contract bound to the engine.'),
142
- z.meta({ examples: ['0xa8b4f0e69cd4b0e56b676343f02acd8c3b355322'] }),
142
+ z.meta({ examples: ['0x9a044ae05e5e6290dcf56afd69548565e957a626'] }),
143
143
  ),
144
144
  )
145
145
  .check(z.describe('Yield venue, or null when the engine does not expose one.')),
@@ -171,22 +171,22 @@ export namespace schema {
171
171
  .strictObject({
172
172
  chainId: Schema.ChainId.check(
173
173
  z.describe('Private Zone chain id.'),
174
- z.meta({ examples: [1424310001] }),
174
+ z.meta({ examples: [421700001] }),
175
175
  ),
176
176
  inputTokens: z
177
177
  .array(Schema.Address)
178
178
  .check(
179
179
  z.describe('Tokens accepted by private deposits.'),
180
- z.meta({ examples: [['0x20c000000000000000000000ff04042ee92fd449']] }),
180
+ z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
181
181
  ),
182
182
  name: z
183
183
  .string()
184
- .check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-moderato-internal'] })),
184
+ .check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-mainnet-internal'] })),
185
185
  outputTokens: z
186
186
  .array(Schema.Address)
187
187
  .check(
188
188
  z.describe('Tokens supported by private redemptions.'),
189
- z.meta({ examples: [['0x20c000000000000000000000ff04042ee92fd449']] }),
189
+ z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
190
190
  ),
191
191
  })
192
192
  .check(z.describe('Private Zone route configured for a verified vault.'))
@@ -195,7 +195,7 @@ export namespace schema {
195
195
  .strictObject({
196
196
  chainId: Schema.ChainId.check(
197
197
  z.describe('Private Zone chain id.'),
198
- z.meta({ examples: [1424310001] }),
198
+ z.meta({ examples: [421700001] }),
199
199
  ),
200
200
  deploymentBlock: z
201
201
  .number()
@@ -203,26 +203,26 @@ export namespace schema {
203
203
  z.int(),
204
204
  z.nonnegative(),
205
205
  z.describe('Parent-chain block that deployed the Earn router.'),
206
- z.meta({ examples: [31039238] }),
206
+ z.meta({ examples: [35816964] }),
207
207
  ),
208
208
  earnRouter: Schema.Address.check(
209
209
  z.describe('Parent-chain router for this Zone and Earn vault.'),
210
- z.meta({ examples: ['0x9144086a79dea966d8bf1b52125ebed8919fc45c'] }),
210
+ z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
211
211
  ),
212
212
  inputTokens: z
213
213
  .array(Schema.Address)
214
214
  .check(
215
215
  z.describe('Tokens accepted by private deposits.'),
216
- z.meta({ examples: [['0x20c000000000000000000000ff04042ee92fd449']] }),
216
+ z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
217
217
  ),
218
218
  name: z
219
219
  .string()
220
- .check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-moderato-internal'] })),
220
+ .check(z.describe('Private Zone name.'), z.meta({ examples: ['zone-mainnet-internal'] })),
221
221
  outputTokens: z
222
222
  .array(Schema.Address)
223
223
  .check(
224
224
  z.describe('Tokens returned by private redemptions.'),
225
- z.meta({ examples: [['0x20c000000000000000000000ff04042ee92fd449']] }),
225
+ z.meta({ examples: [['0x20c0000000000000000000006fd9a167923ba194']] }),
226
226
  ),
227
227
  })
228
228
  .check(z.describe('Verified Earn route through one private Zone.'))
@@ -263,7 +263,22 @@ export namespace schema {
263
263
  'Annualized share-price growth over the selected window, when requested via `include=apy` or by selecting `apy.window`. Null when the rate could not be measured: the vault predates the window, a boundary or historical quote is unavailable, the engine changed inside the window, or the growth is too extreme to annualize as a ratio.',
264
264
  ),
265
265
  ),
266
- assetToken: Tokens.schema.Token.check(z.describe('Asset accepted by the vault.')),
266
+ assetToken: Tokens.schema.Token.check(
267
+ z.describe('Asset accepted by the vault.'),
268
+ z.meta({
269
+ examples: [
270
+ {
271
+ address: '0x20c0000000000000000000000000000000000000',
272
+ currency: 'USD',
273
+ decimals: 6,
274
+ id: '0x20c0000000000000000000000000000000000000',
275
+ name: 'PathUSD',
276
+ symbol: 'pathUSD',
277
+ verified: true,
278
+ },
279
+ ],
280
+ }),
281
+ ),
267
282
  capabilities: z
268
283
  .optional(EarnVaults.schema.Discovery.shape.capabilities)
269
284
  .check(z.describe('Vault capabilities, when requested.')),
@@ -271,21 +286,28 @@ export namespace schema {
271
286
  .nullable(z.string())
272
287
  .check(
273
288
  z.describe('Curated vault description, or null when the vault is not verified.'),
274
- z.meta({ examples: ['Bridge test PATHUSD deposited into Tempo Earn.'] }),
289
+ z.meta({ examples: ['deelUSD deposited into the canonical Tempo Earn deployment.'] }),
275
290
  ),
276
291
  engine,
277
292
  id: Schema.Address.check(
278
293
  z.describe('Stable vault id, equal to the lowercase vault address.'),
279
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
294
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
280
295
  ),
281
296
  instantLiquidity: EarnVaults.schema.Discovery.shape.instantLiquidity.check(
282
297
  z.describe(
283
298
  'Assets the venue would release right now, capped at the vault backing, in asset base units. Null when the engine interface cannot report a reliable number.',
284
299
  ),
285
300
  ),
301
+ instantLiquidityValue: z
302
+ .optional(z.nullable(value))
303
+ .check(
304
+ z.describe(
305
+ 'Instant liquidity valued in USD, when requested via `include=tvl`, or null when liquidity is unavailable or the asset has no priced display currency.',
306
+ ),
307
+ ),
286
308
  label: z
287
309
  .string()
288
- .check(z.describe('Vault display label.'), z.meta({ examples: ['btPATHUSD Earn'] })),
310
+ .check(z.describe('Vault display label.'), z.meta({ examples: ['deelUSD Earn'] })),
289
311
  sharePrice: z
290
312
  .nullable(value)
291
313
  .check(
@@ -293,12 +315,27 @@ export namespace schema {
293
315
  'Assets returned for one whole earn share, in the asset display currency, or null when the engine cannot quote an exit.',
294
316
  ),
295
317
  ),
296
- shareToken: Tokens.schema.Token.check(z.describe('Token representing vault shares.')),
318
+ shareToken: Tokens.schema.Token.check(
319
+ z.describe('Token representing vault shares.'),
320
+ z.meta({
321
+ examples: [
322
+ {
323
+ address: '0x20c000000000000000000000c3268d803b51d448',
324
+ currency: 'USD',
325
+ decimals: 6,
326
+ id: '0x20c000000000000000000000c3268d803b51d448',
327
+ name: 'Sentora pathUSD (Earn)',
328
+ symbol: 'senpathUSDE',
329
+ verified: false,
330
+ },
331
+ ],
332
+ }),
333
+ ),
297
334
  slug: z
298
335
  .nullable(z.string())
299
336
  .check(
300
337
  z.describe('Curated URL slug, or null when the vault is not verified.'),
301
- z.meta({ examples: ['btpathusd-earn-h8k2m4n6'] }),
338
+ z.meta({ examples: ['deelusd-earn'] }),
302
339
  ),
303
340
  state: EarnVaults.schema.Discovery.shape.state,
304
341
  tvl: z
@@ -310,7 +347,7 @@ export namespace schema {
310
347
  ),
311
348
  vaultAddress: Schema.Address.check(
312
349
  z.describe('Earn vault contract address.'),
313
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
350
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
314
351
  ),
315
352
  verified: z
316
353
  .boolean()
@@ -327,12 +364,12 @@ export namespace schema {
327
364
  examples: [
328
365
  [
329
366
  {
330
- chainId: 1424310001,
331
- deploymentBlock: 31039238,
332
- earnRouter: '0x9144086a79dea966d8bf1b52125ebed8919fc45c',
333
- inputTokens: ['0x20c000000000000000000000ff04042ee92fd449'],
334
- name: 'zone-moderato-internal',
335
- outputTokens: ['0x20c000000000000000000000ff04042ee92fd449'],
367
+ chainId: 421700001,
368
+ deploymentBlock: 35816964,
369
+ earnRouter: '0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6',
370
+ inputTokens: ['0x20c0000000000000000000006fd9a167923ba194'],
371
+ name: 'zone-mainnet-internal',
372
+ outputTokens: ['0x20c0000000000000000000006fd9a167923ba194'],
336
373
  },
337
374
  ],
338
375
  ],
@@ -373,7 +410,7 @@ export namespace schema {
373
410
  z.meta({ examples: ['0'] }),
374
411
  ),
375
412
  assetBalance: Schema.DecimalString.check(
376
- z.describe('Assets this account currently holds, in asset base units.'),
413
+ z.describe('Assets held by this account at the observation block, in asset base units.'),
377
414
  z.meta({ examples: ['250000000'] }),
378
415
  ),
379
416
  assetToken: Schema.tokenAddress('0x20c000000000000000000000b9537d11c60e8b50').check(
@@ -388,7 +425,7 @@ export namespace schema {
388
425
  z.meta({ examples: ['0'] }),
389
426
  ),
390
427
  shareBalance: Schema.DecimalString.check(
391
- z.describe('Earn shares this account currently holds, in share base units.'),
428
+ z.describe('Earn shares held by this account at the observation block, in share base units.'),
392
429
  z.meta({ examples: ['99500000'] }),
393
430
  ),
394
431
  shareToken: Schema.tokenAddress('0x20c000000000000000000000300e14ab91a10769').check(
@@ -396,12 +433,37 @@ export namespace schema {
396
433
  ),
397
434
  value: Schema.DecimalString.check(
398
435
  z.describe(
399
- 'Current asset value of this account’s earn shares, including fees, in asset base units.',
436
+ 'Asset value of this account’s earn shares at the observation block, including fees, in asset base units.',
400
437
  ),
401
438
  z.meta({ examples: ['100000000'] }),
402
439
  ),
403
440
  })
404
441
 
442
+ const lifetimeCashFlows = z.union([
443
+ z.strictObject({
444
+ status: z
445
+ .literal('complete')
446
+ .check(
447
+ z.describe('Cash flows are complete through the indexed boundary.'),
448
+ z.meta({ examples: ['complete'] }),
449
+ ),
450
+ totalDeposited: Schema.DecimalString.check(
451
+ z.describe('Assets deposited with this account as receiver over indexed vault history.'),
452
+ ),
453
+ totalWithdrawn: Schema.DecimalString.check(
454
+ z.describe('Assets returned by completed withdrawals over indexed vault history.'),
455
+ ),
456
+ }),
457
+ z.strictObject({
458
+ status: z
459
+ .literal('incomplete_history')
460
+ .check(
461
+ z.describe('Cash flows are omitted because asset deposit history is incomplete.'),
462
+ z.meta({ examples: ['incomplete_history'] }),
463
+ ),
464
+ }),
465
+ ])
466
+
405
467
  const addressPosition = z.strictObject({
406
468
  assetAmount: value.check(
407
469
  z.describe('Current asset value of the held shares, including fees, in `assetToken` units.'),
@@ -409,8 +471,11 @@ export namespace schema {
409
471
  assetToken: Tokens.schema.Token.check(z.describe('Asset accepted by the vault.')),
410
472
  id: Schema.Address.check(
411
473
  z.describe('Stable resource ID for this position, equal to the vault address.'),
412
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
474
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
413
475
  ),
476
+ lifetimeCashFlows: z
477
+ .optional(lifetimeCashFlows)
478
+ .check(z.describe('Lifetime deposits and completed withdrawals, when requested.')),
414
479
  shareAmount: value.check(
415
480
  z.describe('Earn share balance this account holds, in `shareToken` units.'),
416
481
  ),
@@ -425,7 +490,7 @@ export namespace schema {
425
490
  ),
426
491
  vaultAddress: Schema.Address.check(
427
492
  z.describe('Earn vault contract address holding this position.'),
428
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
493
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
429
494
  ),
430
495
  verified: z
431
496
  .boolean()
@@ -476,6 +541,18 @@ export namespace schema {
476
541
  ),
477
542
  z.meta({ examples: ['0'] }),
478
543
  ),
544
+ totalDeposited: Schema.DecimalString.check(
545
+ z.describe(
546
+ 'Assets deposited with this account as receiver over complete indexed vault history.',
547
+ ),
548
+ z.meta({ examples: ['1000000'] }),
549
+ ),
550
+ totalWithdrawn: Schema.DecimalString.check(
551
+ z.describe(
552
+ 'Assets returned by completed redemptions and exact withdrawals initiated by this account over complete indexed vault history.',
553
+ ),
554
+ z.meta({ examples: ['1000000'] }),
555
+ ),
479
556
  period: z
480
557
  .literal('lifetime')
481
558
  .check(
@@ -548,9 +625,23 @@ export namespace schema {
548
625
  }),
549
626
  z.extend(earningsBase, {
550
627
  period: z
551
- .enum(['30d', 'lifetime'])
628
+ .literal('30d')
629
+ .check(
630
+ z.describe('Trailing period with an unresolved async redemption.'),
631
+ z.meta({ examples: ['30d'] }),
632
+ ),
633
+ status: z
634
+ .literal('pending_redemption')
635
+ .check(
636
+ z.describe('Earnings are unavailable while an async redemption remains open.'),
637
+ z.meta({ examples: ['pending_redemption'] }),
638
+ ),
639
+ }),
640
+ z.extend(earningsBase, {
641
+ period: z
642
+ .literal('lifetime')
552
643
  .check(
553
- z.describe('Earnings period with an unresolved async redemption.'),
644
+ z.describe('Lifetime period with an unresolved async redemption.'),
554
645
  z.meta({ examples: ['lifetime'] }),
555
646
  ),
556
647
  status: z
@@ -559,6 +650,12 @@ export namespace schema {
559
650
  z.describe('Earnings are unavailable while an async redemption remains open.'),
560
651
  z.meta({ examples: ['pending_redemption'] }),
561
652
  ),
653
+ totalDeposited: Schema.DecimalString.check(
654
+ z.describe('Assets deposited over complete indexed vault history.'),
655
+ ),
656
+ totalWithdrawn: Schema.DecimalString.check(
657
+ z.describe('Assets withdrawn over complete indexed vault history.'),
658
+ ),
562
659
  }),
563
660
  ])
564
661
 
@@ -654,6 +751,10 @@ export namespace schema {
654
751
  .strictObject({
655
752
  chainId: Schema.ChainIdQuery,
656
753
  cursor: Schema.Cursor,
754
+ include: Schema.includeQuery(
755
+ z.enum(['earnings']),
756
+ 'Comma-separated position fields to include, such as `earnings`.',
757
+ ),
657
758
  limit: Schema.Limit,
658
759
  'valuation.currency': Schema.Denomination.check(
659
760
  z.describe(
@@ -727,11 +828,13 @@ export namespace schema {
727
828
 
728
829
  /** Schemas for the getEarnVaultPosition operation. */
729
830
  export namespace getEarnVaultPosition {
831
+ const asOf = z.iso.datetime({ offset: true })
832
+
730
833
  /** Path parameters identifying the Earn vault and account. */
731
834
  export const Params = z
732
835
  .strictObject({
733
836
  address: Schema.Address.check(z.describe('Account whose earn position to read.')),
734
- vaultId: Schema.address('0xdb48b00fb28d9a8db881fcd671c3fb1bf8c486b6').check(
837
+ vaultId: Schema.address('0x4f94590b636f5878bce585e82379de81e1ec174f').check(
735
838
  z.describe('Earn vault contract address.'),
736
839
  ),
737
840
  })
@@ -739,13 +842,56 @@ export namespace schema {
739
842
 
740
843
  /** Query parameters selecting the chain containing the vault. */
741
844
  export const Query = z
742
- .strictObject({ chainId: Schema.ChainIdQuery })
845
+ .strictObject({
846
+ asOf: z
847
+ .optional(asOf)
848
+ .check(
849
+ z.describe(
850
+ 'ISO 8601 timestamp at which to read the position. Resolves the latest indexed block at or before this time.',
851
+ ),
852
+ z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
853
+ ),
854
+ chainId: Schema.ChainIdQuery,
855
+ })
743
856
  .check(z.describe('Query parameters selecting an earn vault position.'))
744
857
 
745
- /** Current asset and Earn-share state for one account in one vault. */
858
+ const Block = z
859
+ .strictObject({
860
+ number: z
861
+ .number()
862
+ .check(
863
+ z.int(),
864
+ z.nonnegative(),
865
+ z.describe('Indexed observation block.'),
866
+ z.meta({ examples: [31039238] }),
867
+ ),
868
+ timestamp: z.iso
869
+ .datetime()
870
+ .check(
871
+ z.describe('Timestamp of the indexed observation block.'),
872
+ z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
873
+ ),
874
+ })
875
+ .check(z.describe('Indexed block used for a historical Earn position observation.'))
876
+
877
+ /** Current or historical asset and Earn-share state for one account in one vault. */
746
878
  export const Response = Schema.describe(
747
- position,
748
- 'Current asset and earn-share balances, allowances, and asset value for an account in one earn vault.',
879
+ z.extend(position, {
880
+ asOf: z
881
+ .optional(asOf)
882
+ .check(
883
+ z.describe('Requested historical observation time, when supplied.'),
884
+ z.meta({ examples: ['2026-07-21T09:00:00.000Z'] }),
885
+ ),
886
+ block: z
887
+ .optional(Block)
888
+ .check(
889
+ z.describe(
890
+ 'Indexed block used for a historical Earn position observation, when requested.',
891
+ ),
892
+ ),
893
+ }),
894
+ 'Current or historical asset and earn-share balances, allowances, and asset value for an account in one earn vault.',
749
895
  )
750
896
  }
751
897
 
@@ -807,7 +953,7 @@ export function earn(options: earn.Options = {}) {
807
953
  Cache.response<App.Environment>({
808
954
  cacheControl: Cache.policies.state,
809
955
  key: (c) => vaultCacheKey(c, schema.getEarnVaults.Query),
810
- name: 'tempo-api:earn-vaults:v3',
956
+ name: 'tempo-api:earn-vaults:v4',
811
957
  }),
812
958
  async (c) => {
813
959
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -851,7 +997,7 @@ export function earn(options: earn.Options = {}) {
851
997
  Cache.response<App.Environment>({
852
998
  cacheControl: Cache.policies.state,
853
999
  key: (c) => vaultCacheKey(c, schema.getVerifiedEarnVaults.Query),
854
- name: 'tempo-api:earn-vaults:v3',
1000
+ name: 'tempo-api:earn-vaults:v4',
855
1001
  }),
856
1002
  async (c) => {
857
1003
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -884,7 +1030,7 @@ export function earn(options: earn.Options = {}) {
884
1030
  }),
885
1031
  OpenApi.describeRoute({
886
1032
  description:
887
- 'Lists every earn vault where an account currently holds shares, with the current balance and value of each position.',
1033
+ 'Lists every earn vault where an account currently holds shares, with current balances and optional lifetime cash flows.',
888
1034
  operationId: 'getEarnAddressPositions',
889
1035
  responses: OpenApi.responses({
890
1036
  errors: {
@@ -911,7 +1057,7 @@ export function earn(options: earn.Options = {}) {
911
1057
  Cache.response<App.Environment>({
912
1058
  cacheControl: Cache.policies.noStore,
913
1059
  key: (c) => Cache.urlKey(c, schema.getEarnAddressPositions.Query),
914
- name: 'tempo-api:earn-address-positions:v1',
1060
+ name: 'tempo-api:earn-address-positions:v2',
915
1061
  }),
916
1062
  async (c) => {
917
1063
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -964,7 +1110,7 @@ export function earn(options: earn.Options = {}) {
964
1110
  }),
965
1111
  OpenApi.describeRoute({
966
1112
  description:
967
- 'Gets an account’s asset and earn-share balances, allowances, and current asset value for one earn vault.',
1113
+ 'Gets an account’s asset and earn-share balances, allowances, and asset value for one earn vault, optionally at an ISO 8601 timestamp.',
968
1114
  operationId: 'getEarnVaultPosition',
969
1115
  responses: OpenApi.responses({
970
1116
  errors: {
@@ -983,17 +1129,18 @@ export function earn(options: earn.Options = {}) {
983
1129
  502: 'Could not read the earn vault position.',
984
1130
  },
985
1131
  success: {
986
- description: 'Current earn position for one account in one vault.',
1132
+ description: 'Current or historical earn position for one account in one vault.',
987
1133
  schema: schema.getEarnVaultPosition.Response,
988
1134
  },
989
1135
  }),
990
1136
  summary: 'Get account position',
991
1137
  tags: ['Earn'],
992
1138
  }),
1139
+ // Account holdings must read fresh immediately after a deposit or redemption.
993
1140
  Cache.response<App.Environment>({
994
- cacheControl: Cache.policies.state,
1141
+ cacheControl: Cache.policies.noStore,
995
1142
  key: (c) => Cache.urlKey(c, schema.getEarnVaultPosition.Query),
996
- name: 'tempo-api:earn-vault-positions:v1',
1143
+ name: 'tempo-api:earn-vault-positions:v2',
997
1144
  }),
998
1145
  async (c) => {
999
1146
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -1023,35 +1170,85 @@ export function earn(options: earn.Options = {}) {
1023
1170
  const { address, vaultId } = c.req.valid('param')
1024
1171
  const query = c.req.valid('query')
1025
1172
  const chainId = query.chainId ?? c.get('chainId')
1173
+ const client = c.get('getClient')(chainId)
1026
1174
  try {
1027
- const position = await c
1028
- .get('getClient')(chainId)
1029
- .earn.getPosition({ account: address, vault: vaultId })
1030
- return c.json(
1031
- Response.validated(schema.getEarnVaultPosition.Response, {
1032
- account: address,
1033
- assetAllowance: position.assetAllowance.toString(),
1034
- assetBalance: position.assetBalance.toString(),
1035
- assetToken: position.assetToken,
1036
- id: address,
1037
- shareAllowance: position.shareAllowance.toString(),
1038
- shareBalance: position.shareBalance.toString(),
1039
- shareToken: position.shareToken,
1040
- value: position.value.toString(),
1041
- }),
1042
- 200,
1043
- )
1044
- } catch (cause) {
1175
+ const block =
1176
+ query.asOf === undefined
1177
+ ? undefined
1178
+ : await getIndexedBlockAtOrBefore(c.get('getTidx')(chainId), query.asOf)
1045
1179
  try {
1046
- await resolveVaultDiscovery(c, { chainId, include: [], vaultAddress: vaultId })
1047
- } catch (vaultCause) {
1048
- if (isIncompatible(vaultCause))
1049
- return Response.error(c, {
1050
- code: 'earn_vault_not_found',
1051
- message: 'Earn vault not found',
1052
- status: 404,
1053
- })
1180
+ const position = await client.earn.getPosition({
1181
+ account: address,
1182
+ ...(block ? { blockNumber: BigInt(block.number) } : {}),
1183
+ vault: vaultId,
1184
+ })
1185
+ return c.json(
1186
+ Response.validated(schema.getEarnVaultPosition.Response, {
1187
+ account: address,
1188
+ assetAllowance: position.assetAllowance.toString(),
1189
+ assetBalance: position.assetBalance.toString(),
1190
+ assetToken: position.assetToken,
1191
+ asOf: query.asOf,
1192
+ block,
1193
+ id: address,
1194
+ shareAllowance: position.shareAllowance.toString(),
1195
+ shareBalance: position.shareBalance.toString(),
1196
+ shareToken: position.shareToken,
1197
+ value: position.value.toString(),
1198
+ }),
1199
+ 200,
1200
+ )
1201
+ } catch (cause) {
1202
+ if (block) {
1203
+ try {
1204
+ // These immutable bindings establish historical vault identity
1205
+ // without repeating fallible token or redemption subreads.
1206
+ const [asset, shareToken] = await Promise.all([
1207
+ client.readContract({
1208
+ abi: Abis.earnVault,
1209
+ address: vaultId,
1210
+ blockNumber: BigInt(block.number),
1211
+ functionName: 'asset',
1212
+ }),
1213
+ client.readContract({
1214
+ abi: Abis.earnVault,
1215
+ address: vaultId,
1216
+ blockNumber: BigInt(block.number),
1217
+ functionName: 'earnShare',
1218
+ }),
1219
+ ])
1220
+ if (asset === zeroAddress || shareToken === zeroAddress)
1221
+ return Response.error(c, {
1222
+ code: 'earn_vault_not_found',
1223
+ message: 'Earn vault not found',
1224
+ status: 404,
1225
+ })
1226
+ } catch (identityCause) {
1227
+ if (isIncompatible(identityCause))
1228
+ return Response.error(c, {
1229
+ code: 'earn_vault_not_found',
1230
+ message: 'Earn vault not found',
1231
+ status: 404,
1232
+ })
1233
+ return Response.upstream(c, identityCause)
1234
+ }
1235
+ return Response.upstream(c, cause)
1236
+ }
1237
+ try {
1238
+ await resolveVaultDiscovery(c, { chainId, include: [], vaultAddress: vaultId })
1239
+ } catch (vaultCause) {
1240
+ if (isIncompatible(vaultCause))
1241
+ return Response.error(c, {
1242
+ code: 'earn_vault_not_found',
1243
+ message: 'Earn vault not found',
1244
+ status: 404,
1245
+ })
1246
+ }
1247
+ return Response.upstream(c, cause)
1054
1248
  }
1249
+ } catch (cause) {
1250
+ if (cause instanceof IndexedBlockNotFoundError || cause instanceof IndexedCoverageError)
1251
+ return Response.error(c, { code: 'query_invalid', message: cause.message, status: 400 })
1055
1252
  return Response.upstream(c, cause)
1056
1253
  }
1057
1254
  },
@@ -1098,7 +1295,7 @@ export function earn(options: earn.Options = {}) {
1098
1295
  Cache.response<App.Environment>({
1099
1296
  cacheControl: Cache.policies.state,
1100
1297
  key: (c) => Cache.urlKey(c, schema.getEarnVaultEarnings.Query),
1101
- name: 'tempo-api:earn-vault-earnings:v3',
1298
+ name: 'tempo-api:earn-vault-earnings:v4',
1102
1299
  }),
1103
1300
  async (c) => {
1104
1301
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -1185,7 +1382,7 @@ export function earn(options: earn.Options = {}) {
1185
1382
  Cache.response<App.Environment>({
1186
1383
  cacheControl: Cache.policies.state,
1187
1384
  key: (c) => vaultCacheKey(c, schema.getEarnVault.Query),
1188
- name: 'tempo-api:earn-vaults:v3',
1385
+ name: 'tempo-api:earn-vaults:v4',
1189
1386
  }),
1190
1387
  async (c) => {
1191
1388
  if (Auth.narrowAccess) return Auth.paidAccessError(c)
@@ -1304,10 +1501,20 @@ export async function getVaultEarnings(
1304
1501
  }
1305
1502
  if (history.incompleteCostBasis || externalShareTransfer)
1306
1503
  return { ...base, status: 'incomplete_cost_basis' as const }
1307
- if (history.pendingRedemption) return { ...base, status: 'pending_redemption' as const }
1308
- const lifetimeEarnings =
1309
- current.value + history.redeemed + history.withdrewExact + history.finalized - history.deposited
1310
- return { ...base, lifetimeEarnings: lifetimeEarnings.toString(), status: 'complete' as const }
1504
+ const totalWithdrawn = history.redeemed + history.withdrewExact + history.finalized
1505
+ const cashFlows = {
1506
+ totalDeposited: history.deposited.toString(),
1507
+ totalWithdrawn: totalWithdrawn.toString(),
1508
+ }
1509
+ if (history.pendingRedemption)
1510
+ return { ...base, ...cashFlows, status: 'pending_redemption' as const }
1511
+ const lifetimeEarnings = current.value + totalWithdrawn - history.deposited
1512
+ return {
1513
+ ...base,
1514
+ ...cashFlows,
1515
+ lifetimeEarnings: lifetimeEarnings.toString(),
1516
+ status: 'complete' as const,
1517
+ }
1311
1518
  }
1312
1519
 
1313
1520
  /** Reads cash-flow-adjusted earnings over a trailing indexed window. */
@@ -1453,6 +1660,62 @@ async function getLatestIndexedBlock(tidx: Tidx.Client) {
1453
1660
  return { number, timestamp }
1454
1661
  }
1455
1662
 
1663
+ /** Resolves the latest indexed block at or before a historical position timestamp. */
1664
+ async function getIndexedBlockAtOrBefore(tidx: Tidx.Client, asOf: string) {
1665
+ const timestamp = new Date(asOf).toISOString().replace('T', ' ').replace(/Z$/, '')
1666
+ const result = await tidx.fetch({
1667
+ engine: 'clickhouse',
1668
+ // SAFETY: Zod restricts `asOf` to ISO 8601, so the formatted timestamp cannot alter SQL.
1669
+ query: `
1670
+ SELECT 'boundary' AS kind, num, timestamp
1671
+ FROM (
1672
+ SELECT num, timestamp
1673
+ FROM blocks
1674
+ WHERE timestamp <= '${timestamp}'
1675
+ ORDER BY timestamp DESC, num DESC
1676
+ LIMIT 1
1677
+ )
1678
+ UNION ALL
1679
+ SELECT 'head' AS kind, num, timestamp
1680
+ FROM (
1681
+ SELECT num, timestamp
1682
+ FROM blocks
1683
+ ORDER BY num DESC
1684
+ LIMIT 1
1685
+ )
1686
+ ` as string,
1687
+ })
1688
+ return parseIndexedBlockAtOrBefore({ asOf, rows: result.rows })
1689
+ }
1690
+
1691
+ /** Decodes the indexed head and historical position boundary from TIDX rows. */
1692
+ export function parseIndexedBlockAtOrBefore(options: parseIndexedBlockAtOrBefore.Options) {
1693
+ const head = options.rows.find((row) => row['kind'] === 'head')
1694
+ if (!head) throw new Error('TIDX returned no indexed head for a historical Earn position.')
1695
+ const headNumber = Value.toNumber(head['num'])
1696
+ const headAt = Value.toIsoDateTime(head['timestamp'])
1697
+ if (headNumber === undefined || headAt === undefined)
1698
+ throw new Error('TIDX returned a malformed indexed head for a historical Earn position.')
1699
+ const boundary = options.rows.find((row) => row['kind'] === 'boundary')
1700
+ if (!boundary) throw new IndexedBlockNotFoundError(options.asOf)
1701
+ const number = Value.toNumber(boundary['num'])
1702
+ const indexedAt = Value.toIsoDateTime(boundary['timestamp'])
1703
+ if (number === undefined || indexedAt === undefined)
1704
+ throw new Error('TIDX returned a malformed historical Earn position boundary.')
1705
+ if (Date.parse(headAt) < Date.parse(options.asOf)) throw new IndexedCoverageError(options.asOf)
1706
+ return { number, timestamp: indexedAt }
1707
+ }
1708
+
1709
+ export declare namespace parseIndexedBlockAtOrBefore {
1710
+ /** Inputs returned by the historical boundary query. */
1711
+ type Options = {
1712
+ /** Requested historical observation timestamp. */
1713
+ asOf: string
1714
+ /** Indexed head and optional boundary rows. */
1715
+ rows: readonly Record<string, unknown>[]
1716
+ }
1717
+ }
1718
+
1456
1719
  /** Resolves the last indexed block at or before a trailing-day boundary. */
1457
1720
  async function getWindowStartBlockNumber(
1458
1721
  tidx: Tidx.Client,
@@ -1596,6 +1859,7 @@ async function getVaultEarningsHistory(
1596
1859
  return {
1597
1860
  deposited: BigInt(deposited),
1598
1861
  finalized: BigInt(finalized),
1862
+ incompleteCashFlows: venueDeposits > 0,
1599
1863
  incompleteCostBasis: transferredCancellations > 0 || venueDeposits > 0,
1600
1864
  pendingRedemption: pendingRedemptions > 0,
1601
1865
  redeemed: BigInt(redeemed),
@@ -2403,7 +2667,18 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
2403
2667
  }
2404
2668
 
2405
2669
  const page = matches.slice(0, options.limit)
2406
- const [tokens, snapshot] = await Promise.all([
2670
+ const indexedBlock =
2671
+ page.length > 0 && options.include.includes('earnings')
2672
+ ? await getLatestIndexedBlock(c.get('getTidx')(options.chainId))
2673
+ : undefined
2674
+ const [cashFlows, tokens, snapshot] = await Promise.all([
2675
+ indexedBlock
2676
+ ? getVaultLifetimeCashFlows(c.get('getTidx')(options.chainId), {
2677
+ account: options.address,
2678
+ blockNumber: indexedBlock.number,
2679
+ vaults: page.map(({ vaultAddress }) => Schema.Address.parse(vaultAddress)),
2680
+ })
2681
+ : undefined,
2407
2682
  (async () => {
2408
2683
  const addresses = [
2409
2684
  ...new Set(page.flatMap(({ position }) => [position.assetToken, position.shareToken])),
@@ -2444,6 +2719,7 @@ export async function listPositions(c: Context<App.Environment>, options: listPo
2444
2719
  return {
2445
2720
  data: page.map((match) =>
2446
2721
  serializePosition({
2722
+ cashFlows: cashFlows?.get(match.vaultAddress),
2447
2723
  denomination,
2448
2724
  position: match.position,
2449
2725
  rates,
@@ -2557,6 +2833,7 @@ function serializePosition(options: serializePosition.Options) {
2557
2833
  assetAmount: valueFor(position.value, assetToken),
2558
2834
  assetToken,
2559
2835
  id: vaultAddress,
2836
+ ...(options.cashFlows ? { lifetimeCashFlows: options.cashFlows } : {}),
2560
2837
  shareAmount: valueFor(position.shareBalance, shareToken),
2561
2838
  shareToken,
2562
2839
  ...(options.denomination
@@ -2577,6 +2854,10 @@ function serializePosition(options: serializePosition.Options) {
2577
2854
  declare namespace serializePosition {
2578
2855
  /** Values used to serialize one account position row. */
2579
2856
  type Options = {
2857
+ /** Indexed lifetime cash flows, when requested. */
2858
+ cashFlows?: z.output<
2859
+ typeof schema.getEarnAddressPositions.Response
2860
+ >['data'][number]['lifetimeCashFlows']
2580
2861
  /** Currency the row valuation is denominated in (uppercase). */
2581
2862
  denomination?: string | undefined
2582
2863
  position: Actions.earn.getPosition.ReturnValue
@@ -2590,6 +2871,155 @@ declare namespace serializePosition {
2590
2871
  }
2591
2872
  }
2592
2873
 
2874
+ /** Reads complete protocol cash flows for one account and a set of vaults. */
2875
+ export async function getVaultLifetimeCashFlows(
2876
+ tidx: Tidx.Client,
2877
+ options: getVaultLifetimeCashFlows.Options,
2878
+ ) {
2879
+ const vaults = [...new Set(options.vaults.map((vault) => vault.toLowerCase()))]
2880
+ const cashFlows = new Map<string, getVaultLifetimeCashFlows.CashFlows>()
2881
+ if (vaults.length === 0) return cashFlows
2882
+ const addresses = vaults.map((vault) => `'${vault}'`).join(', ')
2883
+ const seeds = vaults
2884
+ .map(
2885
+ (vault) => `
2886
+ SELECT '${vault}' AS vault,
2887
+ toUInt256(0) AS deposited_assets,
2888
+ toUInt256(0) AS finalized_assets,
2889
+ toUInt256(0) AS redeemed_assets,
2890
+ toUInt64(0) AS venue_deposits,
2891
+ toUInt256(0) AS withdrew_exact`,
2892
+ )
2893
+ .join('\n UNION ALL')
2894
+ const result = await tidx.fetch({
2895
+ engine: 'clickhouse',
2896
+ query: `
2897
+ SELECT vault,
2898
+ toString(sum(deposited_assets)) AS deposited_assets,
2899
+ toString(sum(finalized_assets)) AS finalized_assets,
2900
+ toString(sum(redeemed_assets)) AS redeemed_assets,
2901
+ sum(venue_deposits) AS venue_deposits,
2902
+ toString(sum(withdrew_exact)) AS withdrew_exact
2903
+ FROM (
2904
+ ${seeds}
2905
+ UNION ALL
2906
+ SELECT address AS vault, sum(toUInt256(assets)) AS deposited_assets,
2907
+ toUInt256(0) AS finalized_assets, toUInt256(0) AS redeemed_assets,
2908
+ toUInt64(0) AS venue_deposits, toUInt256(0) AS withdrew_exact
2909
+ FROM Deposited
2910
+ WHERE address IN (${addresses})
2911
+ AND receiver = '${options.account}'
2912
+ AND block_num > ${beforeFirstBlockNumber}
2913
+ AND block_num <= ${options.blockNumber}
2914
+ GROUP BY address
2915
+ UNION ALL
2916
+ SELECT finalized.address AS vault, toUInt256(0) AS deposited_assets,
2917
+ sum(toUInt256(finalized.assets)) AS finalized_assets,
2918
+ toUInt256(0) AS redeemed_assets, toUInt64(0) AS venue_deposits,
2919
+ toUInt256(0) AS withdrew_exact
2920
+ FROM RedeemFinalized AS finalized
2921
+ INNER JOIN RedeemRequested AS requested
2922
+ ON requested.address = finalized.address
2923
+ AND requested."requestId" = finalized."requestId"
2924
+ WHERE finalized.address IN (${addresses})
2925
+ AND requested.requester = '${options.account}'
2926
+ AND finalized.block_num > ${beforeFirstBlockNumber}
2927
+ AND finalized.block_num <= ${options.blockNumber}
2928
+ AND requested.block_num <= ${options.blockNumber}
2929
+ GROUP BY finalized.address
2930
+ UNION ALL
2931
+ SELECT address AS vault, toUInt256(0) AS deposited_assets,
2932
+ toUInt256(0) AS finalized_assets, sum(toUInt256(assets)) AS redeemed_assets,
2933
+ toUInt64(0) AS venue_deposits,
2934
+ toUInt256(0) AS withdrew_exact
2935
+ FROM Redeemed
2936
+ WHERE address IN (${addresses})
2937
+ AND caller = '${options.account}'
2938
+ AND block_num > ${beforeFirstBlockNumber}
2939
+ AND block_num <= ${options.blockNumber}
2940
+ GROUP BY address
2941
+ UNION ALL
2942
+ SELECT address AS vault, toUInt256(0) AS deposited_assets,
2943
+ toUInt256(0) AS finalized_assets, toUInt256(0) AS redeemed_assets,
2944
+ count() AS venue_deposits, toUInt256(0) AS withdrew_exact
2945
+ FROM VenueSharesDeposited
2946
+ WHERE address IN (${addresses})
2947
+ AND receiver = '${options.account}'
2948
+ AND block_num > ${beforeFirstBlockNumber}
2949
+ AND block_num <= ${options.blockNumber}
2950
+ GROUP BY address
2951
+ UNION ALL
2952
+ SELECT address AS vault, toUInt256(0) AS deposited_assets,
2953
+ toUInt256(0) AS finalized_assets, toUInt256(0) AS redeemed_assets,
2954
+ toUInt64(0) AS venue_deposits, sum(toUInt256(assets)) AS withdrew_exact
2955
+ FROM WithdrewExact
2956
+ WHERE address IN (${addresses})
2957
+ AND caller = '${options.account}'
2958
+ AND block_num > ${beforeFirstBlockNumber}
2959
+ AND block_num <= ${options.blockNumber}
2960
+ GROUP BY address
2961
+ ) AS histories
2962
+ GROUP BY vault
2963
+ ` as string,
2964
+ signatures: [
2965
+ depositedSignature,
2966
+ redeemFinalizedSignature,
2967
+ redeemRequestedSignature,
2968
+ redeemedSignature,
2969
+ venueSharesDepositedSignature,
2970
+ withdrewExactSignature,
2971
+ ],
2972
+ })
2973
+ for (const row of result.rows) {
2974
+ const vault = Schema.Address.safeParse(Value.toText(row['vault']))
2975
+ const deposited = Value.toIntegerString(row['deposited_assets'])
2976
+ const finalized = Value.toIntegerString(row['finalized_assets'])
2977
+ const redeemed = Value.toIntegerString(row['redeemed_assets'])
2978
+ const venueDeposits = Value.toNumber(row['venue_deposits'])
2979
+ const withdrewExact = Value.toIntegerString(row['withdrew_exact'])
2980
+ if (
2981
+ !vault.success ||
2982
+ deposited === undefined ||
2983
+ finalized === undefined ||
2984
+ redeemed === undefined ||
2985
+ venueDeposits === undefined ||
2986
+ withdrewExact === undefined
2987
+ )
2988
+ throw new Error('TIDX returned invalid Earn lifetime cash flows.')
2989
+ cashFlows.set(
2990
+ vault.data.toLowerCase(),
2991
+ venueDeposits > 0
2992
+ ? { status: 'incomplete_history' }
2993
+ : {
2994
+ status: 'complete',
2995
+ totalDeposited: deposited,
2996
+ totalWithdrawn: (
2997
+ BigInt(finalized) +
2998
+ BigInt(redeemed) +
2999
+ BigInt(withdrewExact)
3000
+ ).toString(),
3001
+ },
3002
+ )
3003
+ }
3004
+ if (cashFlows.size !== vaults.length)
3005
+ throw new Error('TIDX returned incomplete Earn lifetime cash flows.')
3006
+ return cashFlows
3007
+ }
3008
+
3009
+ export declare namespace getVaultLifetimeCashFlows {
3010
+ /** Lifetime cash-flow state for one vault. */
3011
+ type CashFlows = NonNullable<
3012
+ z.output<typeof schema.getEarnAddressPositions.Response>['data'][number]['lifetimeCashFlows']
3013
+ >
3014
+
3015
+ /** Indexed boundary and account whose protocol cash flows are read. */
3016
+ type Options = {
3017
+ account: z.output<typeof Schema.Address>
3018
+ blockNumber: number
3019
+ vaults: readonly z.output<typeof Schema.Address>[]
3020
+ }
3021
+ }
3022
+
2593
3023
  /** Renders a base-unit amount in the token's display currency and precision. */
2594
3024
  function valueFor(amount: bigint, token: z.output<typeof Tokens.schema.Token>) {
2595
3025
  return {
@@ -2898,11 +3328,28 @@ async function resolveVault(c: Context<App.Environment>, options: resolveVault.O
2898
3328
  token: options.snapshot.byAddress.get(discovery.assetToken.address),
2899
3329
  })
2900
3330
  : undefined
3331
+ const liquidityValue =
3332
+ options.include.includes('tvl') && discovery.instantLiquidity !== null
3333
+ ? Valuation.valuationFor({
3334
+ amount: BigInt(discovery.instantLiquidity),
3335
+ denomination: tvlDenomination,
3336
+ rates: options.rates,
3337
+ token: options.snapshot.byAddress.get(discovery.assetToken.address),
3338
+ })
3339
+ : undefined
2901
3340
  return serializeVault({
2902
3341
  apy: options.apy?.get(discovery.vaultAddress) ?? null,
2903
3342
  assetToken: getToken(options.tokens, discovery.assetToken.address),
2904
3343
  discovery,
2905
3344
  include: options.include,
3345
+ instantLiquidityValue: liquidityValue
3346
+ ? {
3347
+ amount: core_Value.from(liquidityValue.amount, tvlDecimals).toString(),
3348
+ currency: liquidityValue.currency,
3349
+ decimals: tvlDecimals,
3350
+ formatted: liquidityValue.amount,
3351
+ }
3352
+ : null,
2906
3353
  record,
2907
3354
  shareToken: getToken(options.tokens, discovery.shareToken.address),
2908
3355
  tvl: valued
@@ -2952,6 +3399,9 @@ export function serializeVault(options: serializeVault.Options): z.output<typeof
2952
3399
  },
2953
3400
  id: vaultAddress,
2954
3401
  instantLiquidity: discovery.instantLiquidity,
3402
+ ...(options.include.includes('tvl')
3403
+ ? { instantLiquidityValue: options.instantLiquidityValue }
3404
+ : {}),
2955
3405
  label: record?.label ?? options.shareToken.name,
2956
3406
  sharePrice:
2957
3407
  discovery.sharePrice === null
@@ -2995,6 +3445,8 @@ export declare namespace serializeVault {
2995
3445
  discovery: EarnVaults.Discovery
2996
3446
  /** Optional vault fields selected by the request. */
2997
3447
  include: z.output<typeof schema.getEarnVault.Query>['include']
3448
+ /** USD value of instant liquidity, or null when unavailable; omitted unless `include` carries `tvl`. */
3449
+ instantLiquidityValue: z.output<typeof schema.Vault>['instantLiquidityValue']
2998
3450
  /** Curated registry row, when verified. */
2999
3451
  record?: core_EarnVaults.Record | undefined
3000
3452
  /** Resolved share token. */
@@ -3195,3 +3647,20 @@ type RegistryRecord = Awaited<ReturnType<typeof core_EarnVaults.list>>[number]
3195
3647
  export class NotFoundError extends Error {
3196
3648
  override name = 'Earn.NotFoundError'
3197
3649
  }
3650
+
3651
+ /** Thrown when a historical position boundary is not indexed. */
3652
+ class IndexedBlockNotFoundError extends Error {
3653
+ override name = 'Earn.IndexedBlockNotFoundError'
3654
+
3655
+ constructor(asOf: string) {
3656
+ super(`No indexed block exists at or before ${asOf}.`)
3657
+ }
3658
+ }
3659
+
3660
+ class IndexedCoverageError extends Error {
3661
+ override name = 'Earn.IndexedCoverageError'
3662
+
3663
+ constructor(asOf: string) {
3664
+ super(`Indexed history does not yet cover ${asOf}.`)
3665
+ }
3666
+ }