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
@@ -189,67 +189,75 @@ export namespace schema {
189
189
  * are absent on the base (no-`include`) response and best-effort when
190
190
  * requested (a token whose metadata is unavailable keeps just `address`).
191
191
  */
192
- export const PairToken = Schema.describe(
193
- z.object({
194
- address: Schema.tokenAddress(Tokens.tokenExample.address).check(
195
- z.describe(
196
- 'TIP-20 token contract address — the `0x`-prefixed 20-byte identifier for this token.',
197
- ),
198
- z.meta({ examples: [Tokens.tokenExample.address] }),
199
- ),
200
- currency: z
201
- .optional(z.string())
202
- .check(
203
- z.describe('Human-readable currency code for the token, when known.'),
204
- z.meta({ examples: [Tokens.tokenExample.currency] }),
205
- ),
206
- decimals: z
207
- .optional(z.number().check(z.int(), z.nonnegative()))
208
- .check(
192
+ export const PairToken = OpenApi.component(
193
+ Schema.describe(
194
+ z.object({
195
+ address: Schema.tokenAddress(Tokens.tokenExample.address).check(
209
196
  z.describe(
210
- 'Number of decimal places the token uses; stablecoins on Tempo typically use 6.',
197
+ 'TIP-20 token contract address the `0x`-prefixed 20-byte identifier for this token.',
211
198
  ),
212
- z.meta({ examples: [Tokens.tokenExample.decimals] }),
213
- ),
214
- logoUri: z.optional(z.string()).check(
215
- z.describe('URL for the token logo image, when one is available.'),
216
- z.meta({
217
- examples: [Tokens.tokenExample.logoUri],
218
- }),
219
- ),
220
- name: z
221
- .optional(z.string())
222
- .check(
223
- z.describe('Human-readable token name, such as `USD Coin`.'),
224
- z.meta({ examples: [Tokens.tokenExample.name] }),
225
- ),
226
- symbol: z
227
- .optional(z.string())
228
- .check(
229
- z.describe('Short token ticker symbol, such as `USDC`.'),
230
- z.meta({ examples: [Tokens.tokenExample.symbol] }),
199
+ z.meta({ examples: [Tokens.tokenExample.address] }),
231
200
  ),
232
- verified: z
233
- .optional(z.boolean())
234
- .check(
235
- z.describe('Whether Tempo has verified this token metadata.'),
236
- z.meta({ examples: [true] }),
201
+ currency: z
202
+ .optional(z.string())
203
+ .check(
204
+ z.describe('Human-readable currency code for the token, when known.'),
205
+ z.meta({ examples: [Tokens.tokenExample.currency] }),
206
+ ),
207
+ decimals: z
208
+ .optional(z.number().check(z.int(), z.nonnegative()))
209
+ .check(
210
+ z.describe(
211
+ 'Number of decimal places the token uses; stablecoins on Tempo typically use 6.',
212
+ ),
213
+ z.meta({ examples: [Tokens.tokenExample.decimals] }),
214
+ ),
215
+ logoUri: z.optional(z.string()).check(
216
+ z.describe('URL for the token logo image, when one is available.'),
217
+ z.meta({
218
+ examples: [Tokens.tokenExample.logoUri],
219
+ }),
237
220
  ),
238
- }),
239
- 'One side of a trading pair (with metadata when requested via `include=tokens`).',
221
+ name: z
222
+ .optional(z.string())
223
+ .check(
224
+ z.describe('Human-readable token name, such as `USD Coin`.'),
225
+ z.meta({ examples: [Tokens.tokenExample.name] }),
226
+ ),
227
+ symbol: z
228
+ .optional(z.string())
229
+ .check(
230
+ z.describe('Short token ticker symbol, such as `USDC`.'),
231
+ z.meta({ examples: [Tokens.tokenExample.symbol] }),
232
+ ),
233
+ verified: z
234
+ .optional(z.boolean())
235
+ .check(
236
+ z.describe('Whether Tempo has verified this token metadata.'),
237
+ z.meta({ examples: [true] }),
238
+ ),
239
+ }),
240
+ 'One side of a trading pair (with metadata when requested via `include=tokens`).',
241
+ ),
242
+ 'ExchangePairToken',
240
243
  )
241
244
 
242
- /** A token amount carrying its nominal value in the requested denomination. */
243
- const ValuedAmount = z.extend(Schema.TokenAmount, {
244
- valuation: z
245
- .optional(z.nullable(Valuation.schema.Value))
246
- .check(
247
- z.describe(
248
- 'The amount’s nominal value in the requested `valuation.currency`. `null` when the token is ' +
249
- 'unverified, its display currency has no rate, or rates were unavailable.',
250
- ),
251
- ),
252
- })
245
+ const ValuedAmount = OpenApi.component(
246
+ Schema.describe(
247
+ z.extend(Schema.TokenAmount, {
248
+ valuation: z
249
+ .optional(z.nullable(Valuation.schema.Value))
250
+ .check(
251
+ z.describe(
252
+ 'The amount’s nominal value in the requested `valuation.currency`. `null` when the token is ' +
253
+ 'unverified, its display currency has no rate, or rates were unavailable.',
254
+ ),
255
+ ),
256
+ }),
257
+ 'A token amount carrying its nominal value in the requested denomination.',
258
+ ),
259
+ 'ExchangeValuedAmount',
260
+ )
253
261
 
254
262
  /** Schemas for creating an executable exchange quote. */
255
263
  export namespace createQuote {
@@ -292,63 +300,69 @@ export namespace schema {
292
300
  .check(z.describe('Query parameters for creating an exchange quote.'))
293
301
 
294
302
  /** Quote request with one pinned side and caller-selected slippage. */
295
- export const Request = z
296
- .strictObject({
297
- account: z
298
- .optional(Schema.Address)
299
- .check(
300
- z.describe('Wallet that will sign and execute the swap.'),
301
- z.meta({ examples: ['0x1111111111111111111111111111111111111111'] }),
303
+ export const Request = OpenApi.component(
304
+ z
305
+ .strictObject({
306
+ account: z
307
+ .optional(Schema.Address)
308
+ .check(
309
+ z.describe('Wallet that will sign and execute the swap.'),
310
+ z.meta({ examples: ['0x1111111111111111111111111111111111111111'] }),
311
+ ),
312
+ amount: Amount.check(
313
+ z.describe(
314
+ 'Pinned amount in base units: source amount for `exactSource`, destination amount for `exactDestination`.',
315
+ ),
302
316
  ),
303
- amount: Amount.check(
304
- z.describe(
305
- 'Pinned amount in base units: source amount for `exactSource`, destination amount for `exactDestination`.',
317
+ destinationToken: DestinationTokenAddress.check(
318
+ z.describe('TIP-20 token the swap receives.'),
306
319
  ),
320
+ mode: z
321
+ .enum(['exactSource', 'exactDestination'])
322
+ .check(
323
+ z.describe('Which side of the swap keeps the requested amount exact.'),
324
+ z.meta({ examples: ['exactSource'] }),
325
+ ),
326
+ slippageBps: z
327
+ .number()
328
+ .check(
329
+ z.int(),
330
+ z.gte(0),
331
+ z.lt(10_000),
332
+ z.describe('Allowed execution slippage in basis points, where 100 is 1%.'),
333
+ z.meta({ examples: [50] }),
334
+ ),
335
+ sourceToken: SourceTokenAddress.check(z.describe('TIP-20 token the swap spends.')),
336
+ })
337
+ .check(
338
+ z.refine((request) => request.sourceToken !== request.destinationToken, {
339
+ error: 'Source and destination tokens must differ.',
340
+ }),
341
+ z.describe('Request for an executable quote from the configured exchange providers.'),
307
342
  ),
308
- destinationToken: DestinationTokenAddress.check(
309
- z.describe('TIP-20 token the swap receives.'),
310
- ),
311
- mode: z
312
- .enum(['exactSource', 'exactDestination'])
313
- .check(
314
- z.describe('Which side of the swap keeps the requested amount exact.'),
315
- z.meta({ examples: ['exactSource'] }),
316
- ),
317
- slippageBps: z
318
- .number()
319
- .check(
320
- z.int(),
321
- z.gte(0),
322
- z.lt(10_000),
323
- z.describe('Allowed execution slippage in basis points, where 100 is 1%.'),
324
- z.meta({ examples: [50] }),
325
- ),
326
- sourceToken: SourceTokenAddress.check(z.describe('TIP-20 token the swap spends.')),
327
- })
328
- .check(
329
- z.refine((request) => request.sourceToken !== request.destinationToken, {
330
- error: 'Source and destination tokens must differ.',
331
- }),
332
- z.describe('Request for an executable quote from the configured exchange providers.'),
333
- )
343
+ 'CreateExchangeQuoteRequest',
344
+ )
334
345
 
335
346
  /** One call in the unsigned Tempo transaction plan. */
336
- export const Call = z
337
- .object({
338
- data: Schema.Hex.check(
339
- z.describe('ABI-encoded call data.'),
340
- z.meta({ examples: ['0x095ea7b3'] }),
341
- ),
342
- to: Schema.Address.check(
343
- z.describe('Contract or precompile that receives the call.'),
344
- z.meta({ examples: [Addresses.stablecoinDex] }),
345
- ),
346
- value: Schema.Quantity.check(
347
- z.describe('Native token value sent with the call.'),
348
- z.meta({ examples: ['0x0'] }),
349
- ),
350
- })
351
- .check(z.describe('One unsigned call in the Tempo transaction plan.'))
347
+ export const Call = OpenApi.component(
348
+ z
349
+ .object({
350
+ data: Schema.Hex.check(
351
+ z.describe('ABI-encoded call data.'),
352
+ z.meta({ examples: ['0x095ea7b3'] }),
353
+ ),
354
+ to: Schema.Address.check(
355
+ z.describe('Contract or precompile that receives the call.'),
356
+ z.meta({ examples: [Addresses.stablecoinDex] }),
357
+ ),
358
+ value: Schema.Quantity.check(
359
+ z.describe('Native token value sent with the call.'),
360
+ z.meta({ examples: ['0x0'] }),
361
+ ),
362
+ })
363
+ .check(z.describe('One unsigned call in the Tempo transaction plan.')),
364
+ 'ExchangeQuoteCall',
365
+ )
352
366
 
353
367
  const QuoteToken = Schema.describe(
354
368
  z.partial(z.omit(Tokens.schema.Token, { id: true }), {
@@ -358,117 +372,138 @@ export namespace schema {
358
372
  'A token referenced by an exchange quote, with RPC metadata and optional enrichments.',
359
373
  )
360
374
 
361
- const DestinationToken = z.extend(QuoteToken, {
362
- address: DestinationTokenAddress.check(z.describe('TIP-20 token the swap receives.')),
363
- })
375
+ const DestinationToken = OpenApi.component(
376
+ Schema.describe(
377
+ z.extend(QuoteToken, {
378
+ address: DestinationTokenAddress.check(z.describe('TIP-20 token the swap receives.')),
379
+ }),
380
+ 'The token received by an exchange quote.',
381
+ ),
382
+ 'ExchangeQuoteDestinationToken',
383
+ )
364
384
 
365
- const SourceToken = z.extend(QuoteToken, {
366
- address: SourceTokenAddress.check(z.describe('TIP-20 token the swap spends.')),
367
- })
385
+ const SourceToken = OpenApi.component(
386
+ Schema.describe(
387
+ z.extend(QuoteToken, {
388
+ address: SourceTokenAddress.check(z.describe('TIP-20 token the swap spends.')),
389
+ }),
390
+ 'The token spent by an exchange quote.',
391
+ ),
392
+ 'ExchangeQuoteSourceToken',
393
+ )
368
394
 
369
- export const Transaction = z
370
- .object({
371
- calls: z.array(Call).check(
372
- z.minLength(1),
373
- z.describe('Calls to execute in order.'),
374
- z.meta({
375
- examples: [
376
- [
377
- {
378
- data: exampleApprovalCall.data,
379
- to: exampleApprovalCall.to,
380
- value: '0x0',
381
- },
382
- { data: exampleSwapCall.data, to: exampleSwapCall.to, value: '0x0' },
395
+ export const Transaction = OpenApi.component(
396
+ z
397
+ .object({
398
+ calls: z.array(Call).check(
399
+ z.minLength(1),
400
+ z.describe('Calls to execute in order.'),
401
+ z.meta({
402
+ examples: [
403
+ [
404
+ {
405
+ data: exampleApprovalCall.data,
406
+ to: exampleApprovalCall.to,
407
+ value: '0x0',
408
+ },
409
+ { data: exampleSwapCall.data, to: exampleSwapCall.to, value: '0x0' },
410
+ ],
383
411
  ],
384
- ],
385
- }),
386
- ),
387
- chainId: Schema.ChainId.check(z.describe('Tempo chain where these calls execute.')),
388
- })
389
- .check(z.describe('Unsigned Tempo transaction plan.'))
412
+ }),
413
+ ),
414
+ chainId: Schema.ChainId.check(z.describe('Tempo chain where these calls execute.')),
415
+ })
416
+ .check(z.describe('Unsigned Tempo transaction plan.')),
417
+ 'ExchangeQuoteTransaction',
418
+ )
390
419
 
391
420
  /** Response-level valuation rate provenance. */
392
- export const Meta = z
393
- .object({
394
- valuation: z
395
- .optional(Valuation.schema.Pricing)
396
- .check(
397
- z.describe(
398
- 'Rate provenance for amount valuations. Present when conversion rates were consulted.',
421
+ export const Meta = OpenApi.component(
422
+ z
423
+ .object({
424
+ valuation: z
425
+ .optional(Valuation.schema.Pricing)
426
+ .check(
427
+ z.describe(
428
+ 'Rate provenance for amount valuations. Present when conversion rates were consulted.',
429
+ ),
399
430
  ),
400
- ),
401
- })
402
- .check(z.describe('Response-level resources attached to this quote.'))
431
+ })
432
+ .check(z.describe('Response-level resources attached to this quote.')),
433
+ 'ExchangeQuoteMeta',
434
+ )
403
435
 
404
436
  /** Provider-neutral EIP-712 payload to sign before finalizing a quote. */
405
- export const TypedData = z
406
- .object({
407
- domain: z.record(z.string(), z.unknown()).check(
408
- z.describe('EIP-712 signing domain.'),
409
- z.meta({
410
- examples: [
411
- {
412
- chainId: 4217,
413
- name: 'Permit2',
414
- verifyingContract: '0x000000000022d473030f116ddee9f6b43ac78ba3',
415
- },
416
- ],
417
- }),
418
- ),
419
- message: z.record(z.string(), z.unknown()).check(
420
- z.describe('Values encoded by the primary EIP-712 type.'),
421
- z.meta({
422
- examples: [
423
- {
424
- details: {
425
- amount: '1000000',
426
- expiration: '4102444800',
427
- nonce: '0',
428
- token: exampleSourceToken,
437
+ export const TypedData = OpenApi.component(
438
+ z
439
+ .object({
440
+ domain: z.record(z.string(), z.unknown()).check(
441
+ z.describe('EIP-712 signing domain.'),
442
+ z.meta({
443
+ examples: [
444
+ {
445
+ chainId: 4217,
446
+ name: 'Permit2',
447
+ verifyingContract: '0x000000000022d473030f116ddee9f6b43ac78ba3',
429
448
  },
430
- sigDeadline: '4102444800',
431
- spender: '0x1febb76be10aaf3a1402f04e8e835f2c382f7914',
432
- },
433
- ],
434
- }),
435
- ),
436
- primaryType: z
437
- .string()
438
- .check(z.minLength(1))
439
- .check(z.describe('Root EIP-712 type.'), z.meta({ examples: ['PermitSingle'] })),
440
- types: z
441
- .record(
442
- z.string(),
443
- z.array(
444
- z.strictObject({
445
- name: z.string(),
446
- type: z.string(),
447
- }),
448
- ),
449
- )
450
- .check(
451
- z.describe('EIP-712 type definitions keyed by type name.'),
449
+ ],
450
+ }),
451
+ ),
452
+ message: z.record(z.string(), z.unknown()).check(
453
+ z.describe('Values encoded by the primary EIP-712 type.'),
452
454
  z.meta({
453
455
  examples: [
454
456
  {
455
- PermitDetails: [
456
- { name: 'token', type: 'address' },
457
- { name: 'amount', type: 'uint160' },
458
- { name: 'expiration', type: 'uint48' },
459
- { name: 'nonce', type: 'uint48' },
460
- ],
461
- PermitSingle: [
462
- { name: 'details', type: 'PermitDetails' },
463
- { name: 'spender', type: 'address' },
464
- { name: 'sigDeadline', type: 'uint256' },
465
- ],
457
+ details: {
458
+ amount: '1000000',
459
+ expiration: '4102444800',
460
+ nonce: '0',
461
+ token: exampleSourceToken,
462
+ },
463
+ sigDeadline: '4102444800',
464
+ spender: '0x1febb76be10aaf3a1402f04e8e835f2c382f7914',
466
465
  },
467
466
  ],
468
467
  }),
469
468
  ),
470
- })
471
- .check(z.describe('EIP-712 payload the wallet must sign before execution can continue.'))
469
+ primaryType: z
470
+ .string()
471
+ .check(z.minLength(1))
472
+ .check(z.describe('Root EIP-712 type.'), z.meta({ examples: ['PermitSingle'] })),
473
+ types: z
474
+ .record(
475
+ z.string(),
476
+ z.array(
477
+ z.strictObject({
478
+ name: z.string(),
479
+ type: z.string(),
480
+ }),
481
+ ),
482
+ )
483
+ .check(
484
+ z.describe('EIP-712 type definitions keyed by type name.'),
485
+ z.meta({
486
+ examples: [
487
+ {
488
+ PermitDetails: [
489
+ { name: 'token', type: 'address' },
490
+ { name: 'amount', type: 'uint160' },
491
+ { name: 'expiration', type: 'uint48' },
492
+ { name: 'nonce', type: 'uint48' },
493
+ ],
494
+ PermitSingle: [
495
+ { name: 'details', type: 'PermitDetails' },
496
+ { name: 'spender', type: 'address' },
497
+ { name: 'sigDeadline', type: 'uint256' },
498
+ ],
499
+ },
500
+ ],
501
+ }),
502
+ ),
503
+ })
504
+ .check(z.describe('EIP-712 payload the wallet must sign before execution can continue.')),
505
+ 'ExchangeQuoteTypedData',
506
+ )
472
507
 
473
508
  const Provider = z
474
509
  .string()
@@ -482,24 +517,31 @@ export namespace schema {
482
517
  provider: Provider,
483
518
  }
484
519
 
485
- const ApprovalRequired = {
486
- approval: z.object({
487
- calls: z.array(Call).check(
488
- z.minLength(1),
489
- z.describe('Approval calls to confirm before requesting a fresh quote.'),
490
- z.meta({
491
- examples: [
492
- [
493
- {
494
- data: exampleApprovalCall.data,
495
- to: exampleApprovalCall.to,
496
- value: '0x0',
497
- },
520
+ const Approval = OpenApi.component(
521
+ z
522
+ .object({
523
+ calls: z.array(Call).check(
524
+ z.minLength(1),
525
+ z.describe('Approval calls to confirm before requesting a fresh quote.'),
526
+ z.meta({
527
+ examples: [
528
+ [
529
+ {
530
+ data: exampleApprovalCall.data,
531
+ to: exampleApprovalCall.to,
532
+ value: '0x0',
533
+ },
534
+ ],
498
535
  ],
499
- ],
500
- }),
501
- ),
502
- }),
536
+ }),
537
+ ),
538
+ })
539
+ .check(z.describe('Token approval calls required before requesting a fresh quote.')),
540
+ 'ExchangeQuoteApproval',
541
+ )
542
+
543
+ const ApprovalRequired = {
544
+ approval: Approval,
503
545
  status: z
504
546
  .literal('approvalRequired')
505
547
  .check(
@@ -536,10 +578,8 @@ export namespace schema {
536
578
  }
537
579
 
538
580
  const ExactSource = {
539
- destinationAmount: ValuedAmount.check(z.describe('Quoted destination amount.')),
540
- destinationAmountMin: ValuedAmount.check(
541
- z.describe('Minimum destination amount after slippage.'),
542
- ),
581
+ destinationAmount: ValuedAmount,
582
+ destinationAmountMin: ValuedAmount,
543
583
  destinationToken: DestinationToken,
544
584
  meta: z.optional(Meta).check(z.describe('Valuation rate provenance for this quote.')),
545
585
  mode: z
@@ -548,13 +588,13 @@ export namespace schema {
548
588
  z.describe('The source amount is fixed and the destination has a minimum.'),
549
589
  z.meta({ examples: ['exactSource'] }),
550
590
  ),
551
- sourceAmount: ValuedAmount.check(z.describe('Exact source amount.')),
552
- sourceToken: SourceToken.check(z.describe('Token spent by the swap.')),
591
+ sourceAmount: ValuedAmount,
592
+ sourceToken: SourceToken,
553
593
  }
554
594
 
555
595
  const ExactDestination = {
556
- destinationAmount: ValuedAmount.check(z.describe('Exact destination amount.')),
557
- destinationToken: DestinationToken.check(z.describe('Token received by the swap.')),
596
+ destinationAmount: ValuedAmount,
597
+ destinationToken: DestinationToken,
558
598
  meta: z.optional(Meta).check(z.describe('Valuation rate provenance for this quote.')),
559
599
  mode: z
560
600
  .literal('exactDestination')
@@ -562,64 +602,114 @@ export namespace schema {
562
602
  z.describe('The destination amount is fixed and the source has a maximum.'),
563
603
  z.meta({ examples: ['exactDestination'] }),
564
604
  ),
565
- sourceAmount: ValuedAmount.check(z.describe('Quoted source amount.')),
566
- sourceAmountMax: ValuedAmount.check(z.describe('Maximum source amount after slippage.')),
605
+ sourceAmount: ValuedAmount,
606
+ sourceAmountMax: ValuedAmount,
567
607
  sourceToken: SourceToken,
568
608
  }
569
609
 
610
+ const ExactSourceApprovalRequired = OpenApi.component(
611
+ z
612
+ .object({ ...ApprovalRequired, ...ExactSource, ...Quote })
613
+ .check(z.describe('An exact-source quote that requires token approval.')),
614
+ 'ExchangeQuoteExactSourceApprovalRequired',
615
+ )
616
+ const ExactSourceReady = OpenApi.component(
617
+ z
618
+ .object({ ...ExactSource, ...Quote, ...Ready })
619
+ .check(z.describe('An exact-source quote ready to execute.')),
620
+ 'ExchangeQuoteExactSourceReady',
621
+ )
622
+ const ExactSourceSignatureRequired = OpenApi.component(
623
+ z
624
+ .object({ ...ExactSource, ...Quote, ...SignatureRequired })
625
+ .check(z.describe('An exact-source quote that requires a signature.')),
626
+ 'ExchangeQuoteExactSourceSignatureRequired',
627
+ )
628
+ const ExactDestinationApprovalRequired = OpenApi.component(
629
+ z
630
+ .object({ ...ApprovalRequired, ...ExactDestination, ...Quote })
631
+ .check(z.describe('An exact-destination quote that requires token approval.')),
632
+ 'ExchangeQuoteExactDestinationApprovalRequired',
633
+ )
634
+ const ExactDestinationReady = OpenApi.component(
635
+ z
636
+ .object({ ...ExactDestination, ...Quote, ...Ready })
637
+ .check(z.describe('An exact-destination quote ready to execute.')),
638
+ 'ExchangeQuoteExactDestinationReady',
639
+ )
640
+ const ExactDestinationSignatureRequired = OpenApi.component(
641
+ z
642
+ .object({ ...ExactDestination, ...Quote, ...SignatureRequired })
643
+ .check(z.describe('An exact-destination quote that requires a signature.')),
644
+ 'ExchangeQuoteExactDestinationSignatureRequired',
645
+ )
646
+
570
647
  /** Provider-neutral quote and the action needed to execute it. */
571
- export const Response = z
572
- .union([
573
- z.object({ ...ApprovalRequired, ...ExactSource, ...Quote }),
574
- z.object({ ...ExactSource, ...Quote, ...Ready }),
575
- z.object({ ...ExactSource, ...Quote, ...SignatureRequired }),
576
- z.object({ ...ApprovalRequired, ...ExactDestination, ...Quote }),
577
- z.object({ ...ExactDestination, ...Quote, ...Ready }),
578
- z.object({ ...ExactDestination, ...Quote, ...SignatureRequired }),
579
- ])
580
- .check(z.describe('Provider-neutral exchange quote with its next execution action.'))
648
+ export const Response = OpenApi.component(
649
+ z
650
+ .union([
651
+ ExactSourceApprovalRequired,
652
+ ExactSourceReady,
653
+ ExactSourceSignatureRequired,
654
+ ExactDestinationApprovalRequired,
655
+ ExactDestinationReady,
656
+ ExactDestinationSignatureRequired,
657
+ ])
658
+ .check(z.describe('Provider-neutral exchange quote with its next execution action.')),
659
+ 'ExchangeQuote',
660
+ )
581
661
  }
582
662
 
583
663
  /** Schemas for finishing a quote after a provider-requested signature. */
584
664
  export namespace executeQuote {
585
665
  /** Signed continuation request. */
586
- export const Request = z.strictObject({
587
- account: Schema.Address.check(
588
- z.describe('Wallet that signed and will execute the swap.'),
589
- z.meta({ examples: ['0x1111111111111111111111111111111111111111'] }),
590
- ),
591
- continuation: z
592
- .string()
593
- .check(
594
- z.minLength(1),
595
- z.maxLength(100_000),
596
- z.describe('Opaque state returned by the quote request.'),
597
- z.meta({ examples: ['eyJwcm92aWRlciI6InVuaXN3YXAifQ'] }),
598
- ),
599
- provider: z
600
- .string()
601
- .check(
602
- z.minLength(1),
603
- z.describe('Provider that issued the continuation.'),
604
- z.meta({ examples: ['uniswap'] }),
605
- ),
606
- signature: Schema.Hex.check(
607
- z.refine((value) => value.length === 132, { error: 'Signature must be 65 bytes.' }),
608
- z.describe('65-byte EIP-712 signature requested by the quote.'),
609
- z.meta({ examples: [`0x${'11'.repeat(65)}`] }),
610
- ),
611
- })
666
+ export const Request = OpenApi.component(
667
+ z
668
+ .strictObject({
669
+ account: Schema.Address.check(
670
+ z.describe('Wallet that signed and will execute the swap.'),
671
+ z.meta({ examples: ['0x1111111111111111111111111111111111111111'] }),
672
+ ),
673
+ continuation: z
674
+ .string()
675
+ .check(
676
+ z.minLength(1),
677
+ z.maxLength(100_000),
678
+ z.describe('Opaque state returned by the quote request.'),
679
+ z.meta({ examples: ['eyJwcm92aWRlciI6InVuaXN3YXAifQ'] }),
680
+ ),
681
+ provider: z
682
+ .string()
683
+ .check(
684
+ z.minLength(1),
685
+ z.describe('Provider that issued the continuation.'),
686
+ z.meta({ examples: ['uniswap'] }),
687
+ ),
688
+ signature: Schema.Hex.check(
689
+ z.refine((value) => value.length === 132, { error: 'Signature must be 65 bytes.' }),
690
+ z.describe('65-byte EIP-712 signature requested by the quote.'),
691
+ z.meta({ examples: [`0x${'11'.repeat(65)}`] }),
692
+ ),
693
+ })
694
+ .check(z.describe('Request to finalize a provider quote after signing its typed data.')),
695
+ 'FinalizeExchangeQuoteRequest',
696
+ )
612
697
 
613
698
  /** Final transaction plan. */
614
- export const Response = z.object({
615
- provider: z
616
- .string()
617
- .check(
618
- z.describe('Provider that built the transaction.'),
619
- z.meta({ examples: ['uniswap'] }),
620
- ),
621
- transaction: createQuote.Transaction,
622
- })
699
+ export const Response = OpenApi.component(
700
+ z
701
+ .object({
702
+ provider: z
703
+ .string()
704
+ .check(
705
+ z.describe('Provider that built the transaction.'),
706
+ z.meta({ examples: ['uniswap'] }),
707
+ ),
708
+ transaction: createQuote.Transaction,
709
+ })
710
+ .check(z.describe('Final unsigned transaction plan for a signed provider quote.')),
711
+ 'FinalizedExchangeQuote',
712
+ )
623
713
  }
624
714
 
625
715
  /** Schemas for the getPairs operation. */
@@ -671,69 +761,82 @@ export namespace schema {
671
761
  )
672
762
 
673
763
  /** A single trading pair on the stablecoin DEX. */
674
- export const Pair = z
675
- .object({
676
- base: PairToken.check(
677
- z.describe('Base token — the asset whose price is quoted in the pair.'),
678
- ),
679
- blockNumber: z
680
- .number()
681
- .check(
682
- z.int(),
683
- z.nonnegative(),
684
- z.describe('Block number where the pair was created.'),
685
- z.meta({ examples: [23456789] }),
764
+ export const Pair = OpenApi.component(
765
+ z
766
+ .object({
767
+ base: PairToken,
768
+ blockNumber: z
769
+ .number()
770
+ .check(
771
+ z.int(),
772
+ z.nonnegative(),
773
+ z.describe('Block number where the pair was created.'),
774
+ z.meta({ examples: [23456789] }),
775
+ ),
776
+ id: Schema.Hash.check(
777
+ z.describe(
778
+ 'Stable API id for this pair; it is the same value as the onchain pair key.',
779
+ ),
686
780
  ),
687
- id: Schema.Hash.check(
688
- z.describe('Stable API id for this pair; it is the same value as the onchain pair key.'),
689
- ),
690
- key: Schema.Hash.check(
691
- z.describe('Stable onchain pair identifier returned by the DEX precompile as `pairKey`.'),
692
- ),
693
- liquidity: z
694
- .optional(
695
- z
696
- .string()
697
- .check(
698
- z.regex(/^\d+$/),
699
- z.describe(
700
- 'Liquidity signal for the pair: the base-token balance held by the DEX, returned as a decimal integer string in the token’s smallest units. Present only when `sort=liquidity`.',
701
- ),
702
- ),
703
- )
704
- .check(
781
+ key: Schema.Hash.check(
705
782
  z.describe(
706
- 'Liquidity signal for the pair, present only when you request `sort=liquidity`.',
783
+ 'Stable onchain pair identifier returned by the DEX precompile as `pairKey`.',
707
784
  ),
708
- z.meta({ examples: ['1000000'] }),
709
785
  ),
710
- quote: PairToken.check(z.describe('Quote token — the asset used to price the base token.')),
711
- timestamp: z.iso
712
- .datetime()
713
- .check(
714
- z.describe('Block timestamp when the pair was created.'),
715
- z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
786
+ liquidity: z
787
+ .optional(
788
+ z
789
+ .string()
790
+ .check(
791
+ z.regex(/^\d+$/),
792
+ z.describe(
793
+ 'Liquidity signal for the pair: the base-token balance held by the DEX, returned as a decimal integer string in the token’s smallest units. Present only when `sort=liquidity`.',
794
+ ),
795
+ ),
796
+ )
797
+ .check(
798
+ z.describe(
799
+ 'Liquidity signal for the pair, present only when you request `sort=liquidity`.',
800
+ ),
801
+ z.meta({ examples: ['1000000'] }),
802
+ ),
803
+ quote: PairToken,
804
+ timestamp: z.iso
805
+ .datetime()
806
+ .check(
807
+ z.describe('Block timestamp when the pair was created.'),
808
+ z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
809
+ ),
810
+ transactionHash: Schema.Hash.check(
811
+ z.describe('Transaction hash for the transaction that created the pair.'),
716
812
  ),
717
- transactionHash: Schema.Hash.check(
718
- z.describe('Transaction hash for the transaction that created the pair.'),
719
- ),
720
- })
721
- .check(z.describe('One trading pair on Tempo’s built-in stablecoin exchange.'))
813
+ })
814
+ .check(z.describe('One trading pair on Tempo’s built-in stablecoin exchange.')),
815
+ 'ExchangePair',
816
+ )
817
+
818
+ /** Response metadata requested through `include`, such as capped counts. */
819
+ export const Meta = OpenApi.component(Schema.CountMeta, 'ExchangePairListMeta')
722
820
 
723
821
  /** Page of trading pairs on the stablecoin DEX, ordered by creation. */
724
- export const Response = z
725
- .object({
726
- data: z.array(Pair).check(z.describe('Trading pairs returned on this page.')),
727
- meta: z
728
- .optional(Schema.CountMeta)
729
- .check(
730
- z.describe('Response-level resources requested with `include`, such as `totalCount`.'),
731
- ),
732
- nextCursor: Schema.NextCursor,
733
- })
734
- .check(
735
- z.describe('A paginated list of trading pairs on Tempo’s built-in stablecoin exchange.'),
736
- )
822
+ export const Response = OpenApi.component(
823
+ z
824
+ .object({
825
+ data: z.array(Pair).check(z.describe('Trading pairs returned on this page.')),
826
+ meta: z
827
+ .optional(Meta)
828
+ .check(
829
+ z.describe(
830
+ 'Response-level resources requested with `include`, such as `totalCount`.',
831
+ ),
832
+ ),
833
+ nextCursor: Schema.NextCursor,
834
+ })
835
+ .check(
836
+ z.describe('A paginated list of trading pairs on Tempo’s built-in stablecoin exchange.'),
837
+ ),
838
+ 'ExchangePairList',
839
+ )
737
840
  }
738
841
 
739
842
  /** Schemas for the getPair operation (single trading pair detail). */
@@ -833,51 +936,52 @@ export namespace schema {
833
936
  )
834
937
 
835
938
  /** One swap-side token with RPC metadata and optional curated fields. */
836
- export const SwapSide = Schema.describe(
837
- Tokens.schema.TokenReference,
838
- 'A token referenced by one side of a swap.',
939
+ export const SwapSide = OpenApi.component(
940
+ Schema.describe(Tokens.schema.TokenReference, 'A token referenced by one side of a swap.'),
941
+ 'ExchangeSwapToken',
839
942
  )
840
943
 
841
944
  /** A single maker-order fill within a swap, framed from the taker's perspective. */
842
- export const Fill = z
843
- .object({
844
- destinationAmount: ValuedAmount.check(
845
- z.describe('Amount the taker received in this fill.'),
846
- ),
847
- destinationToken: SwapSide.check(z.describe('Token the taker received in this fill.')),
848
- logIndex: z
849
- .number()
850
- .check(
851
- z.int(),
852
- z.nonnegative(),
853
- z.describe('Log index of this fill within its block.'),
854
- z.meta({ examples: [0] }),
855
- ),
856
- maker: Schema.Address.check(z.describe('Maker address whose resting order was filled.')),
857
- orderId: Schema.DecimalString.check(
858
- z.describe('On-chain maker order id, returned as a decimal string.'),
859
- ),
860
- partialFill: z
861
- .boolean()
862
- .check(
863
- z.describe('Whether this fill used only part of the maker order.'),
864
- z.meta({ examples: [false] }),
865
- ),
866
- price: z
867
- .string()
868
- .check(
869
- z.regex(/^\d+(\.\d+)?$/),
870
- z.describe(
871
- 'Quote-per-base price at fill time, returned as a fixed-decimal string with 5 decimal places. This value is direction-independent and works well for charts.',
945
+ export const Fill = OpenApi.component(
946
+ z
947
+ .object({
948
+ destinationAmount: ValuedAmount,
949
+ destinationToken: SwapSide,
950
+ logIndex: z
951
+ .number()
952
+ .check(
953
+ z.int(),
954
+ z.nonnegative(),
955
+ z.describe('Log index of this fill within its block.'),
956
+ z.meta({ examples: [0] }),
872
957
  ),
873
- z.meta({ examples: ['1.00000'] }),
958
+ maker: Schema.Address.check(z.describe('Maker address whose resting order was filled.')),
959
+ orderId: Schema.DecimalString.check(
960
+ z.describe('On-chain maker order id, returned as a decimal string.'),
874
961
  ),
875
- sourceAmount: ValuedAmount.check(z.describe('Amount the taker sent in this fill.')),
876
- sourceToken: SwapSide.check(z.describe('Token the taker sent in this fill.')),
877
- })
878
- .check(
879
- z.describe('One maker-order fill within a swap, described from the taker’s perspective.'),
880
- )
962
+ partialFill: z
963
+ .boolean()
964
+ .check(
965
+ z.describe('Whether this fill used only part of the maker order.'),
966
+ z.meta({ examples: [false] }),
967
+ ),
968
+ price: z
969
+ .string()
970
+ .check(
971
+ z.regex(/^\d+(\.\d+)?$/),
972
+ z.describe(
973
+ 'Quote-per-base price at fill time, returned as a fixed-decimal string with 5 decimal places. This value is direction-independent and works well for charts.',
974
+ ),
975
+ z.meta({ examples: ['1.00000'] }),
976
+ ),
977
+ sourceAmount: ValuedAmount,
978
+ sourceToken: SwapSide,
979
+ })
980
+ .check(
981
+ z.describe('One maker-order fill within a swap, described from the taker’s perspective.'),
982
+ ),
983
+ 'ExchangeSwapFill',
984
+ )
881
985
 
882
986
  /**
883
987
  * A single logical taker swap on the stablecoin DEX: every maker-order
@@ -886,81 +990,82 @@ export namespace schema {
886
990
  * intermediate token, e.g. pathUSD) are one row; the intermediate hops
887
991
  * are visible via `route` and `fills`.
888
992
  */
889
- export const Swap = z
890
- .object({
891
- blockNumber: z
892
- .number()
893
- .check(
894
- z.int(),
895
- z.nonnegative(),
896
- z.describe('Block number where the swap was included.'),
897
- z.meta({ examples: [23456789] }),
898
- ),
899
- destinationAmount: ValuedAmount.check(
900
- z.describe('Total amount the taker received in this swap.'),
901
- ),
902
- destinationToken: SwapSide.check(z.describe('Destination token for the final hop.')),
903
- filledAt: z.iso
904
- .datetime()
905
- .check(
906
- z.describe('Block timestamp when the swap was filled onchain.'),
907
- z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
908
- ),
909
- fills: z
910
- .array(Fill)
911
- .check(
912
- z.describe(
913
- 'Maker-order fills that make up this swap, ordered by execution `logIndex`. Exact-destination swaps can execute hops in reverse, so use `route` for the source-to-destination path.',
993
+ export const Swap = OpenApi.component(
994
+ z
995
+ .object({
996
+ blockNumber: z
997
+ .number()
998
+ .check(
999
+ z.int(),
1000
+ z.nonnegative(),
1001
+ z.describe('Block number where the swap was included.'),
1002
+ z.meta({ examples: [23456789] }),
914
1003
  ),
915
- ),
916
- id: z.string().check(
917
- z.describe(
918
- 'Stable API id built from the lowercase transaction hash and the first fill log index.',
919
- ),
920
- z.meta({
921
- examples: ['0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-0'],
922
- }),
923
- ),
924
- logIndex: z
925
- .number()
926
- .check(
927
- z.int(),
928
- z.nonnegative(),
929
- z.describe('Block-wide log index for the swap, taken from its first fill.'),
930
- z.meta({ examples: [0] }),
931
- ),
932
- mode: z
933
- .nullable(z.enum(['exactSource', 'exactDestination']))
934
- .check(
935
- z.describe(
936
- 'The amount type fixed by the swap call: `exactSource` for `swapExactAmountIn` or `exactDestination` for `swapExactAmountOut`. This is recovered from transaction calldata and is `null` when the swap did not come from a decodable swap call.',
1004
+ destinationAmount: ValuedAmount,
1005
+ destinationToken: SwapSide,
1006
+ filledAt: z.iso
1007
+ .datetime()
1008
+ .check(
1009
+ z.describe('Block timestamp when the swap was filled onchain.'),
1010
+ z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
937
1011
  ),
938
- z.meta({ examples: ['exactSource'] }),
939
- ),
940
- rate: z
941
- .string()
942
- .check(
943
- z.regex(/^\d+(\.\d+)?$/),
1012
+ fills: z
1013
+ .array(Fill)
1014
+ .check(
1015
+ z.describe(
1016
+ 'Maker-order fills that make up this swap, ordered by execution `logIndex`. Exact-destination swaps can execute hops in reverse, so use `route` for the source-to-destination path.',
1017
+ ),
1018
+ ),
1019
+ id: z.string().check(
944
1020
  z.describe(
945
- 'Swap-level effective rate, calculated as destination amount divided by source amount from the taker’s perspective and returned with 5 decimal places. Compare it with `1` to see distance from peg.',
1021
+ 'Stable API id built from the lowercase transaction hash and the first fill log index.',
946
1022
  ),
947
- z.meta({ examples: ['1.00000'] }),
1023
+ z.meta({
1024
+ examples: ['0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-0'],
1025
+ }),
948
1026
  ),
949
- route: z
950
- .array(Schema.TokenAddress)
951
- .check(
952
- z.describe(
953
- 'Token path for the swap, from source through any intermediate tokens to destination. `route.length - 1` is the hop count; two entries means a direct swap.',
1027
+ logIndex: z
1028
+ .number()
1029
+ .check(
1030
+ z.int(),
1031
+ z.nonnegative(),
1032
+ z.describe('Block-wide log index for the swap, taken from its first fill.'),
1033
+ z.meta({ examples: [0] }),
954
1034
  ),
1035
+ mode: z
1036
+ .nullable(z.enum(['exactSource', 'exactDestination']))
1037
+ .check(
1038
+ z.describe(
1039
+ 'The amount type fixed by the swap call: `exactSource` for `swapExactAmountIn` or `exactDestination` for `swapExactAmountOut`. This is recovered from transaction calldata and is `null` when the swap did not come from a decodable swap call.',
1040
+ ),
1041
+ z.meta({ examples: ['exactSource'] }),
1042
+ ),
1043
+ rate: z
1044
+ .string()
1045
+ .check(
1046
+ z.regex(/^\d+(\.\d+)?$/),
1047
+ z.describe(
1048
+ 'Swap-level effective rate, calculated as destination amount divided by source amount from the taker’s perspective and returned with 5 decimal places. Compare it with `1` to see distance from peg.',
1049
+ ),
1050
+ z.meta({ examples: ['1.00000'] }),
1051
+ ),
1052
+ route: z
1053
+ .array(Schema.TokenAddress)
1054
+ .check(
1055
+ z.describe(
1056
+ 'Token path for the swap, from source through any intermediate tokens to destination. `route.length - 1` is the hop count; two entries means a direct swap.',
1057
+ ),
1058
+ ),
1059
+ sourceAmount: ValuedAmount,
1060
+ sourceToken: SwapSide,
1061
+ taker: Schema.Address.check(z.describe('Taker address that initiated the swap.')),
1062
+ transactionHash: Schema.Hash.check(
1063
+ z.describe('Transaction hash for the transaction containing the swap.'),
955
1064
  ),
956
- sourceAmount: ValuedAmount.check(z.describe('Total amount the taker sent in this swap.')),
957
- sourceToken: SwapSide.check(z.describe('Source token for the first hop.')),
958
- taker: Schema.Address.check(z.describe('Taker address that initiated the swap.')),
959
- transactionHash: Schema.Hash.check(
960
- z.describe('Transaction hash for the transaction containing the swap.'),
961
- ),
962
- })
963
- .check(z.describe('One logical taker swap on Tempo’s built-in stablecoin exchange.'))
1065
+ })
1066
+ .check(z.describe('One logical taker swap on Tempo’s built-in stablecoin exchange.')),
1067
+ 'ExchangeSwap',
1068
+ )
964
1069
 
965
1070
  /**
966
1071
  * Page of swaps. A row is one logical taker swap — the fills of one
@@ -970,28 +1075,34 @@ export namespace schema {
970
1075
  * taker may have its rows split across consecutive pages.
971
1076
  */
972
1077
  /** Page-level resources: valuation rate provenance. */
973
- export const Meta = z
974
- .object({
975
- valuation: z
976
- .optional(Valuation.schema.Pricing)
977
- .check(
978
- z.describe(
979
- 'Rate provenance for amount valuations. Present when conversion rates were ' +
980
- 'consulted; absent when every value was identity-valued or rates were unavailable.',
1078
+ export const Meta = OpenApi.component(
1079
+ z
1080
+ .object({
1081
+ valuation: z
1082
+ .optional(Valuation.schema.Pricing)
1083
+ .check(
1084
+ z.describe(
1085
+ 'Rate provenance for amount valuations. Present when conversion rates were ' +
1086
+ 'consulted; absent when every value was identity-valued or rates were unavailable.',
1087
+ ),
981
1088
  ),
982
- ),
983
- })
984
- .check(z.describe('Page-level resources attached to this response.'))
1089
+ })
1090
+ .check(z.describe('Page-level resources attached to this response.')),
1091
+ 'ExchangeSwapListMeta',
1092
+ )
985
1093
 
986
- export const Response = z
987
- .object({
988
- data: z.array(Swap).check(z.describe('Swaps returned on this page.')),
989
- meta: z
990
- .optional(Meta)
991
- .check(z.describe('Page-level resources, such as valuation rate provenance.')),
992
- nextCursor: Schema.NextCursor,
993
- })
994
- .check(z.describe('A paginated list of swaps on Tempo’s built-in stablecoin exchange.'))
1094
+ export const Response = OpenApi.component(
1095
+ z
1096
+ .object({
1097
+ data: z.array(Swap).check(z.describe('Swaps returned on this page.')),
1098
+ meta: z
1099
+ .optional(Meta)
1100
+ .check(z.describe('Page-level resources, such as valuation rate provenance.')),
1101
+ nextCursor: Schema.NextCursor,
1102
+ })
1103
+ .check(z.describe('A paginated list of swaps on Tempo’s built-in stablecoin exchange.')),
1104
+ 'ExchangeSwapList',
1105
+ )
995
1106
  }
996
1107
 
997
1108
  /** Schemas for the getPairOhlc operation (candlestick aggregations). */
@@ -1061,107 +1172,115 @@ export namespace schema {
1061
1172
  * and low are the extrema across all fills in the bucket. Volumes are
1062
1173
  * the sum of per-fill base- and quote-side amounts in base units.
1063
1174
  */
1064
- export const Bucket = z
1065
- .object({
1066
- close: z
1067
- .string()
1068
- .check(
1069
- z.regex(/^\d+(\.\d+)?$/),
1070
- z.describe(
1071
- 'Close price for the bucket: the latest fill rate, returned with 5 decimal places.',
1072
- ),
1073
- z.meta({ examples: ['1.00000'] }),
1074
- ),
1075
- fillCount: z
1076
- .number()
1077
- .check(
1078
- z.int(),
1079
- z.nonnegative(),
1080
- z.describe('Number of fills included in this bucket.'),
1081
- z.meta({ examples: [5] }),
1082
- ),
1083
- high: z
1084
- .string()
1085
- .check(
1086
- z.regex(/^\d+(\.\d+)?$/),
1087
- z.describe(
1088
- 'High price for the bucket: the highest fill rate, returned with 5 decimal places.',
1089
- ),
1090
- z.meta({ examples: ['1.01000'] }),
1091
- ),
1092
- id: z.string().check(
1093
- z.describe(
1094
- 'Stable API id built from the pair key, candle interval, and bucket start time in Unix seconds.',
1095
- ),
1096
- z.meta({
1097
- examples: [
1098
- '0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-1h-1704067200',
1099
- ],
1100
- }),
1101
- ),
1102
- low: z
1103
- .string()
1104
- .check(
1105
- z.regex(/^\d+(\.\d+)?$/),
1106
- z.describe(
1107
- 'Low price for the bucket: the lowest fill rate, returned with 5 decimal places.',
1175
+ export const Bucket = OpenApi.component(
1176
+ z
1177
+ .object({
1178
+ close: z
1179
+ .string()
1180
+ .check(
1181
+ z.regex(/^\d+(\.\d+)?$/),
1182
+ z.describe(
1183
+ 'Close price for the bucket: the latest fill rate, returned with 5 decimal places.',
1184
+ ),
1185
+ z.meta({ examples: ['1.00000'] }),
1108
1186
  ),
1109
- z.meta({ examples: ['0.99000'] }),
1110
- ),
1111
- open: z
1112
- .string()
1113
- .check(
1114
- z.regex(/^\d+(\.\d+)?$/),
1187
+ fillCount: z
1188
+ .number()
1189
+ .check(
1190
+ z.int(),
1191
+ z.nonnegative(),
1192
+ z.describe('Number of fills included in this bucket.'),
1193
+ z.meta({ examples: [5] }),
1194
+ ),
1195
+ high: z
1196
+ .string()
1197
+ .check(
1198
+ z.regex(/^\d+(\.\d+)?$/),
1199
+ z.describe(
1200
+ 'High price for the bucket: the highest fill rate, returned with 5 decimal places.',
1201
+ ),
1202
+ z.meta({ examples: ['1.01000'] }),
1203
+ ),
1204
+ id: z.string().check(
1115
1205
  z.describe(
1116
- 'Open price for the bucket: the earliest fill rate, returned with 5 decimal places.',
1206
+ 'Stable API id built from the pair key, candle interval, and bucket start time in Unix seconds.',
1117
1207
  ),
1118
- z.meta({ examples: ['1.00000'] }),
1119
- ),
1120
- timestamp: z.iso
1121
- .datetime()
1122
- .check(
1123
- z.describe('ISO 8601 timestamp for the start of this candle bucket.'),
1124
- z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
1208
+ z.meta({
1209
+ examples: [
1210
+ '0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-1h-1704067200',
1211
+ ],
1212
+ }),
1125
1213
  ),
1126
- volume: z
1127
- .object({
1128
- base: Schema.DecimalString.check(
1214
+ low: z
1215
+ .string()
1216
+ .check(
1217
+ z.regex(/^\d+(\.\d+)?$/),
1129
1218
  z.describe(
1130
- 'Total base-side amount filled in this bucket, in the token’s smallest units.',
1219
+ 'Low price for the bucket: the lowest fill rate, returned with 5 decimal places.',
1131
1220
  ),
1221
+ z.meta({ examples: ['0.99000'] }),
1132
1222
  ),
1133
- quote: Schema.DecimalString.check(
1223
+ open: z
1224
+ .string()
1225
+ .check(
1226
+ z.regex(/^\d+(\.\d+)?$/),
1134
1227
  z.describe(
1135
- 'Total quote-side amount filled in this bucket, reconstructed from each fill’s tick and returned in the token’s smallest units.',
1228
+ 'Open price for the bucket: the earliest fill rate, returned with 5 decimal places.',
1136
1229
  ),
1230
+ z.meta({ examples: ['1.00000'] }),
1137
1231
  ),
1138
- })
1139
- .check(z.describe('Total filled volume in this bucket, split by pair side.')),
1140
- })
1141
- .check(z.describe('One OHLC candle bucket for charting a trading pair.'))
1232
+ timestamp: z.iso
1233
+ .datetime()
1234
+ .check(
1235
+ z.describe('ISO 8601 timestamp for the start of this candle bucket.'),
1236
+ z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
1237
+ ),
1238
+ volume: z
1239
+ .object({
1240
+ base: Schema.DecimalString.check(
1241
+ z.describe(
1242
+ 'Total base-side amount filled in this bucket, in the token’s smallest units.',
1243
+ ),
1244
+ ),
1245
+ quote: Schema.DecimalString.check(
1246
+ z.describe(
1247
+ 'Total quote-side amount filled in this bucket, reconstructed from each fill’s tick and returned in the token’s smallest units.',
1248
+ ),
1249
+ ),
1250
+ })
1251
+ .check(z.describe('Total filled volume in this bucket, split by pair side.')),
1252
+ })
1253
+ .check(z.describe('One OHLC candle bucket for charting a trading pair.')),
1254
+ 'ExchangeOhlcBucket',
1255
+ )
1142
1256
 
1143
1257
  /** Page of candlestick buckets for a single trading pair. */
1144
- export const Response = z
1145
- .object({
1146
- base: PairToken.check(z.describe('Base side of the trading pair.')),
1147
- data: z
1148
- .array(Bucket)
1149
- .check(
1150
- z.describe('OHLC candle buckets ordered oldest to newest; empty buckets are omitted.'),
1151
- ),
1152
- interval: Interval,
1153
- quote: PairToken.check(z.describe('Quote side of the trading pair.')),
1154
- truncated: z
1155
- .boolean()
1156
- .check(
1157
- z.describe(
1158
- '`true` when the fill scan hit its hard cap, meaning OHLC values were computed from only the most recent fills.',
1258
+ export const Response = OpenApi.component(
1259
+ z
1260
+ .object({
1261
+ base: PairToken,
1262
+ data: z
1263
+ .array(Bucket)
1264
+ .check(
1265
+ z.describe(
1266
+ 'OHLC candle buckets ordered oldest to newest; empty buckets are omitted.',
1267
+ ),
1159
1268
  ),
1160
- z.meta({ examples: [false] }),
1161
- ),
1162
- window: Window,
1163
- })
1164
- .check(z.describe('OHLC candle data for one trading pair over a rolling time window.'))
1269
+ interval: Interval,
1270
+ quote: PairToken,
1271
+ truncated: z
1272
+ .boolean()
1273
+ .check(
1274
+ z.describe(
1275
+ '`true` when the fill scan hit its hard cap, meaning OHLC values were computed from only the most recent fills.',
1276
+ ),
1277
+ z.meta({ examples: [false] }),
1278
+ ),
1279
+ window: Window,
1280
+ })
1281
+ .check(z.describe('OHLC candle data for one trading pair over a rolling time window.')),
1282
+ 'ExchangePairOhlc',
1283
+ )
1165
1284
  }
1166
1285
 
1167
1286
  /** Schemas shared by the order detail and order fills handlers. */
@@ -1177,13 +1296,16 @@ export namespace schema {
1177
1296
  .check(z.describe('Path parameters for routes that look up one order.'))
1178
1297
 
1179
1298
  /** The pair the order is placed against. */
1180
- export const Pair = Schema.describe(
1181
- z.object({
1182
- base: PairToken.check(z.describe('Base side of the pair; the order trades this token.')),
1183
- key: Schema.Hash.check(z.describe('On-chain key for this `(base, quote)` trading pair.')),
1184
- quote: PairToken.check(z.describe('Quote side of the trading pair.')),
1185
- }),
1186
- 'The trading pair the order belongs to.',
1299
+ export const Pair = OpenApi.component(
1300
+ Schema.describe(
1301
+ z.object({
1302
+ base: PairToken,
1303
+ key: Schema.Hash.check(z.describe('On-chain key for this `(base, quote)` trading pair.')),
1304
+ quote: PairToken,
1305
+ }),
1306
+ 'The trading pair the order belongs to.',
1307
+ ),
1308
+ 'ExchangeOrderPair',
1187
1309
  )
1188
1310
  }
1189
1311
 
@@ -1229,86 +1351,93 @@ export namespace schema {
1229
1351
  * over time and would otherwise force this resource to revalidate on
1230
1352
  * every new fill.
1231
1353
  */
1232
- export const Response = Schema.describe(
1233
- z.object({
1234
- amount: Schema.DecimalString.check(
1235
- z.describe(
1236
- 'Initial order size, returned as a decimal integer string in base-token smallest units.',
1237
- ),
1238
- ),
1239
- flipTick: z
1240
- .number()
1241
- .check(
1242
- z.int(),
1354
+ export const Response = OpenApi.component(
1355
+ Schema.describe(
1356
+ z.object({
1357
+ amount: Schema.DecimalString.check(
1243
1358
  z.describe(
1244
- 'Replacement `tick` used if this order auto-flips into a counter-order after filling.',
1359
+ 'Initial order size, returned as a decimal integer string in base-token smallest units.',
1245
1360
  ),
1246
- z.meta({ examples: [10] }),
1247
1361
  ),
1248
- id: Schema.DecimalString.check(
1249
- z.describe('Stable API id for this order; it is the same value as the onchain order id.'),
1250
- ),
1251
- isBid: z
1252
- .boolean()
1253
- .check(
1254
- z.describe(
1255
- 'Order side as a boolean: `true` means the maker buys base, and `false` means the maker sells base.',
1362
+ flipTick: z
1363
+ .number()
1364
+ .check(
1365
+ z.int(),
1366
+ z.describe(
1367
+ 'Replacement `tick` used if this order auto-flips into a counter-order after filling.',
1368
+ ),
1369
+ z.meta({ examples: [10] }),
1256
1370
  ),
1257
- z.meta({ examples: [true] }),
1258
- ),
1259
- isFlipOrder: z
1260
- .boolean()
1261
- .check(
1262
- z.describe('Whether this order automatically becomes a counter-order after it fills.'),
1263
- z.meta({ examples: [false] }),
1264
- ),
1265
- maker: Schema.Address.check(z.describe('Maker address that owns the order.')),
1266
- mode: z
1267
- .enum(['exactSource', 'exactDestination'])
1268
- .check(
1371
+ id: Schema.DecimalString.check(
1269
1372
  z.describe(
1270
- 'Taker-perspective mode for the order. `exactSource` applies to maker bids where the taker sells base; `exactDestination` applies to maker asks where the taker buys base.',
1373
+ 'Stable API id for this order; it is the same value as the onchain order id.',
1271
1374
  ),
1272
- z.meta({ examples: ['exactSource'] }),
1273
1375
  ),
1274
- orderId: Schema.DecimalString.check(
1275
- z.describe('On-chain order id, returned as a decimal string.'),
1276
- ),
1277
- pair: order.Pair,
1278
- price: z
1279
- .string()
1280
- .check(
1281
- z.regex(/^\d+(\.\d+)?$/),
1282
- z.describe(
1283
- 'Quote-per-base price implied by `tick`, returned as a fixed-decimal string with 5 decimal places.',
1376
+ isBid: z
1377
+ .boolean()
1378
+ .check(
1379
+ z.describe(
1380
+ 'Order side as a boolean: `true` means the maker buys base, and `false` means the maker sells base.',
1381
+ ),
1382
+ z.meta({ examples: [true] }),
1284
1383
  ),
1285
- z.meta({ examples: ['1.00000'] }),
1286
- ),
1287
- rate: z
1288
- .string()
1289
- .check(
1290
- z.regex(/^\d+(\.\d+)?$/),
1291
- z.describe(
1292
- 'Destination-to-source price ratio, returned as a fixed-decimal string with 5 decimal places.',
1384
+ isFlipOrder: z
1385
+ .boolean()
1386
+ .check(
1387
+ z.describe(
1388
+ 'Whether this order automatically becomes a counter-order after it fills.',
1389
+ ),
1390
+ z.meta({ examples: [false] }),
1293
1391
  ),
1294
- z.meta({ examples: ['1.00000'] }),
1295
- ),
1296
- remaining: Schema.DecimalString.check(
1297
- z.describe(
1298
- 'Unfilled base-side amount still resting on the orderbook, returned as a decimal integer string.',
1392
+ maker: Schema.Address.check(z.describe('Maker address that owns the order.')),
1393
+ mode: z
1394
+ .enum(['exactSource', 'exactDestination'])
1395
+ .check(
1396
+ z.describe(
1397
+ 'Taker-perspective mode for the order. `exactSource` applies to maker bids where the taker sells base; `exactDestination` applies to maker asks where the taker buys base.',
1398
+ ),
1399
+ z.meta({ examples: ['exactSource'] }),
1400
+ ),
1401
+ orderId: Schema.DecimalString.check(
1402
+ z.describe('On-chain order id, returned as a decimal string.'),
1299
1403
  ),
1300
- ),
1301
- tick: z
1302
- .number()
1303
- .check(
1304
- z.int(),
1404
+ pair: order.Pair,
1405
+ price: z
1406
+ .string()
1407
+ .check(
1408
+ z.regex(/^\d+(\.\d+)?$/),
1409
+ z.describe(
1410
+ 'Quote-per-base price implied by `tick`, returned as a fixed-decimal string with 5 decimal places.',
1411
+ ),
1412
+ z.meta({ examples: ['1.00000'] }),
1413
+ ),
1414
+ rate: z
1415
+ .string()
1416
+ .check(
1417
+ z.regex(/^\d+(\.\d+)?$/),
1418
+ z.describe(
1419
+ 'Destination-to-source price ratio, returned as a fixed-decimal string with 5 decimal places.',
1420
+ ),
1421
+ z.meta({ examples: ['1.00000'] }),
1422
+ ),
1423
+ remaining: Schema.DecimalString.check(
1305
1424
  z.describe(
1306
- 'On-chain signed tick, scaled by `1/priceScale`; use `price` for the decoded ratio.',
1425
+ 'Unfilled base-side amount still resting on the orderbook, returned as a decimal integer string.',
1307
1426
  ),
1308
- z.meta({ examples: [0] }),
1309
1427
  ),
1310
- }),
1311
- 'A single DEX order with live onchain state.',
1428
+ tick: z
1429
+ .number()
1430
+ .check(
1431
+ z.int(),
1432
+ z.describe(
1433
+ 'On-chain signed tick, scaled by `1/priceScale`; use `price` for the decoded ratio.',
1434
+ ),
1435
+ z.meta({ examples: [0] }),
1436
+ ),
1437
+ }),
1438
+ 'A single DEX order with live onchain state.',
1439
+ ),
1440
+ 'ExchangeOrder',
1312
1441
  )
1313
1442
  }
1314
1443
 
@@ -1384,8 +1513,8 @@ export namespace schema {
1384
1513
  * Orders for which `remaining <= 0` or that have an `OrderCancelled`
1385
1514
  * event are excluded from the response.
1386
1515
  */
1387
- export const RestingOrder = z
1388
- .object({
1516
+ export const RestingOrder = Schema.describe(
1517
+ z.object({
1389
1518
  amount: Schema.DecimalString.check(
1390
1519
  z.describe(
1391
1520
  'Original placed amount, returned as a decimal integer string in base-token smallest units.',
@@ -1461,40 +1590,53 @@ export namespace schema {
1461
1590
  transactionHash: Schema.Hash.check(
1462
1591
  z.describe('Transaction hash for the transaction that placed the order.'),
1463
1592
  ),
1464
- })
1465
- .check(z.describe('One resting maker order on Tempo’s built-in stablecoin exchange.'))
1593
+ }),
1594
+ 'One resting maker order on Tempo’s built-in stablecoin exchange.',
1595
+ )
1466
1596
 
1467
1597
  /** A resting maker order annotated with the trading pair it belongs to. */
1468
- export const Order = z
1469
- .extend(RestingOrder, {
1470
- pair: order.Pair,
1471
- })
1472
- .check(z.describe('A resting maker order plus its trading pair.'))
1598
+ export const Order = OpenApi.component(
1599
+ Schema.describe(
1600
+ z.extend(RestingOrder, {
1601
+ pair: order.Pair,
1602
+ }),
1603
+ 'A resting maker order plus its trading pair.',
1604
+ ),
1605
+ 'ExchangeRestingOrder',
1606
+ )
1607
+
1608
+ /** Response metadata requested through `include`, such as capped counts. */
1609
+ export const Meta = OpenApi.component(Schema.CountMeta, 'ExchangeOrderListMeta')
1473
1610
 
1474
1611
  /** Page of resting maker orders, each annotated with its trading pair. */
1475
- export const Response = z
1476
- .object({
1477
- data: z.array(Order).check(z.describe('Resting orders returned on this page.')),
1478
- meta: z
1479
- .optional(Schema.CountMeta)
1480
- .check(
1481
- z.describe('Response-level resources requested with `include`, such as `totalCount`.'),
1482
- ),
1483
- nextCursor: Schema.NextCursor,
1484
- truncated: z
1485
- .boolean()
1486
- .check(
1487
- z.describe(
1488
- '`true` when the `OrderPlaced` scan hit its hard cap, meaning the resting set was computed from only the most recent placements.',
1612
+ export const Response = OpenApi.component(
1613
+ z
1614
+ .object({
1615
+ data: z.array(Order).check(z.describe('Resting orders returned on this page.')),
1616
+ meta: z
1617
+ .optional(Meta)
1618
+ .check(
1619
+ z.describe(
1620
+ 'Response-level resources requested with `include`, such as `totalCount`.',
1621
+ ),
1622
+ ),
1623
+ nextCursor: Schema.NextCursor,
1624
+ truncated: z
1625
+ .boolean()
1626
+ .check(
1627
+ z.describe(
1628
+ '`true` when the `OrderPlaced` scan hit its hard cap, meaning the resting set was computed from only the most recent placements.',
1629
+ ),
1630
+ z.meta({ examples: [false] }),
1489
1631
  ),
1490
- z.meta({ examples: [false] }),
1632
+ })
1633
+ .check(
1634
+ z.describe(
1635
+ 'A paginated list of resting maker orders on Tempo’s built-in stablecoin exchange.',
1491
1636
  ),
1492
- })
1493
- .check(
1494
- z.describe(
1495
- 'A paginated list of resting maker orders on Tempo’s built-in stablecoin exchange.',
1496
1637
  ),
1497
- )
1638
+ 'ExchangeOrderList',
1639
+ )
1498
1640
  }
1499
1641
 
1500
1642
  /** Schemas for the getOrderFills operation. */
@@ -1522,67 +1664,78 @@ export namespace schema {
1522
1664
  * rate are constant across all fills, so they live on the `Order`
1523
1665
  * resource rather than being repeated per row.
1524
1666
  */
1525
- export const Fill = z
1526
- .object({
1527
- amountFilled: Schema.DecimalString.check(
1528
- z.describe(
1529
- 'Base-side amount filled by this event, returned as a decimal integer string in base-token smallest units.',
1667
+ export const Fill = OpenApi.component(
1668
+ z
1669
+ .object({
1670
+ amountFilled: Schema.DecimalString.check(
1671
+ z.describe(
1672
+ 'Base-side amount filled by this event, returned as a decimal integer string in base-token smallest units.',
1673
+ ),
1530
1674
  ),
1531
- ),
1532
- blockNumber: z
1533
- .number()
1534
- .check(
1535
- z.int(),
1536
- z.nonnegative(),
1537
- z.describe('Block number where the fill was included.'),
1538
- z.meta({ examples: [23456789] }),
1675
+ blockNumber: z
1676
+ .number()
1677
+ .check(
1678
+ z.int(),
1679
+ z.nonnegative(),
1680
+ z.describe('Block number where the fill was included.'),
1681
+ z.meta({ examples: [23456789] }),
1682
+ ),
1683
+ filledAt: z.iso
1684
+ .datetime()
1685
+ .check(
1686
+ z.describe('Block timestamp when the fill landed onchain.'),
1687
+ z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
1688
+ ),
1689
+ id: z.string().check(
1690
+ z.describe('Stable API id built from the lowercase transaction hash and log index.'),
1691
+ z.meta({
1692
+ examples: ['0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-0'],
1693
+ }),
1539
1694
  ),
1540
- filledAt: z.iso
1541
- .datetime()
1542
- .check(
1543
- z.describe('Block timestamp when the fill landed onchain.'),
1544
- z.meta({ examples: ['2024-01-01T00:00:00Z'] }),
1695
+ logIndex: z
1696
+ .number()
1697
+ .check(
1698
+ z.int(),
1699
+ z.nonnegative(),
1700
+ z.describe('Log index of this fill within its block.'),
1701
+ z.meta({ examples: [0] }),
1702
+ ),
1703
+ orderId: Schema.DecimalString.check(
1704
+ z.describe('On-chain order id, returned as a decimal string.'),
1545
1705
  ),
1546
- id: z.string().check(
1547
- z.describe('Stable API id built from the lowercase transaction hash and log index.'),
1548
- z.meta({
1549
- examples: ['0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-0'],
1550
- }),
1551
- ),
1552
- logIndex: z
1553
- .number()
1554
- .check(
1555
- z.int(),
1556
- z.nonnegative(),
1557
- z.describe('Log index of this fill within its block.'),
1558
- z.meta({ examples: [0] }),
1706
+ partialFill: z
1707
+ .boolean()
1708
+ .check(
1709
+ z.describe('Whether this fill used only part of the maker order.'),
1710
+ z.meta({ examples: [false] }),
1711
+ ),
1712
+ taker: Schema.Address.check(
1713
+ z.describe('Taker address that submitted the incoming order.'),
1559
1714
  ),
1560
- orderId: Schema.DecimalString.check(
1561
- z.describe('On-chain order id, returned as a decimal string.'),
1562
- ),
1563
- partialFill: z
1564
- .boolean()
1565
- .check(
1566
- z.describe('Whether this fill used only part of the maker order.'),
1567
- z.meta({ examples: [false] }),
1715
+ transactionHash: Schema.Hash.check(
1716
+ z.describe('Transaction hash for the transaction containing the fill.'),
1568
1717
  ),
1569
- taker: Schema.Address.check(z.describe('Taker address that submitted the incoming order.')),
1570
- transactionHash: Schema.Hash.check(
1571
- z.describe('Transaction hash for the transaction containing the fill.'),
1572
- ),
1573
- })
1574
- .check(z.describe('One `OrderFilled` event against this order.'))
1718
+ })
1719
+ .check(z.describe('One `OrderFilled` event against this order.')),
1720
+ 'ExchangeOrderFill',
1721
+ )
1722
+
1723
+ /** Response metadata requested through `include`, such as capped counts. */
1724
+ export const Meta = OpenApi.component(Schema.CountMeta, 'ExchangeOrderFillListMeta')
1575
1725
 
1576
1726
  /** Paginated page of fills for one order. */
1577
- export const Response = z
1578
- .object({
1579
- data: z.array(Fill).check(z.describe('Fills returned on this page.')),
1580
- meta: z
1581
- .optional(Schema.CountMeta)
1582
- .check(z.describe('Response-level resources requested with `include`.')),
1583
- nextCursor: Schema.NextCursor,
1584
- })
1585
- .check(z.describe('A paginated list of fill events for one DEX order.'))
1727
+ export const Response = OpenApi.component(
1728
+ z
1729
+ .object({
1730
+ data: z.array(Fill).check(z.describe('Fills returned on this page.')),
1731
+ meta: z
1732
+ .optional(Meta)
1733
+ .check(z.describe('Response-level resources requested with `include`.')),
1734
+ nextCursor: Schema.NextCursor,
1735
+ })
1736
+ .check(z.describe('A paginated list of fill events for one DEX order.')),
1737
+ 'ExchangeOrderFillList',
1738
+ )
1586
1739
  }
1587
1740
 
1588
1741
  /** Schemas for the getPairDepth operation (orderbook depth aggregation). */
@@ -1643,60 +1796,70 @@ export namespace schema {
1643
1796
  * side, starting from the best (peg-adjacent) populated tick and walking
1644
1797
  * outward.
1645
1798
  */
1646
- export const Level = z
1647
- .object({
1648
- cumulativeSize: Schema.DecimalString.check(
1649
- z.describe(
1650
- 'Running sum of `size` from the best populated tick outward to this level, in base-token smallest units.',
1799
+ export const Level = OpenApi.component(
1800
+ z
1801
+ .object({
1802
+ cumulativeSize: Schema.DecimalString.check(
1803
+ z.describe(
1804
+ 'Running sum of `size` from the best populated tick outward to this level, in base-token smallest units.',
1805
+ ),
1651
1806
  ),
1652
- ),
1653
- id: z.string().check(
1654
- z.describe('Stable API id built from the pair key, orderbook side, and tick.'),
1655
- z.meta({
1656
- examples: ['0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-bid-0'],
1657
- }),
1658
- ),
1659
- price: z
1660
- .string()
1661
- .check(
1662
- z.regex(/^\d+(\.\d+)?$/),
1663
- z.describe('Tick converted to a price ratio with 5 decimal places.'),
1664
- z.meta({ examples: ['1.00000'] }),
1807
+ id: z.string().check(
1808
+ z.describe('Stable API id built from the pair key, orderbook side, and tick.'),
1809
+ z.meta({
1810
+ examples: [
1811
+ '0x515801d7f9a5ac705e793e85904c9c69b3f1694b465cc8fb6ba3f0298dc82665-bid-0',
1812
+ ],
1813
+ }),
1665
1814
  ),
1666
- size: Schema.DecimalString.check(
1667
- z.describe('Resting liquidity at this tick level, in base-token smallest units.'),
1668
- ),
1669
- tick: z
1670
- .number()
1671
- .check(
1672
- z.int(),
1673
- z.describe('Signed price tick (`int16`), always a multiple of the DEX tick spacing.'),
1674
- z.meta({ examples: [0] }),
1815
+ price: z
1816
+ .string()
1817
+ .check(
1818
+ z.regex(/^\d+(\.\d+)?$/),
1819
+ z.describe('Tick converted to a price ratio with 5 decimal places.'),
1820
+ z.meta({ examples: ['1.00000'] }),
1821
+ ),
1822
+ size: Schema.DecimalString.check(
1823
+ z.describe('Resting liquidity at this tick level, in base-token smallest units.'),
1675
1824
  ),
1676
- })
1677
- .check(z.describe('One price level in the orderbook depth response.'))
1825
+ tick: z
1826
+ .number()
1827
+ .check(
1828
+ z.int(),
1829
+ z.describe('Signed price tick (`int16`), always a multiple of the DEX tick spacing.'),
1830
+ z.meta({ examples: [0] }),
1831
+ ),
1832
+ })
1833
+ .check(z.describe('One price level in the orderbook depth response.')),
1834
+ 'ExchangeDepthLevel',
1835
+ )
1678
1836
 
1679
1837
  /** Orderbook depth (cumulative size per tick) for a single trading pair. */
1680
- export const Response = z
1681
- .object({
1682
- asks: z
1683
- .array(Level)
1684
- .check(
1685
- z.describe(
1686
- 'Ask-side levels, where makers sell base and takers buy it, ordered from best lowest ask outward.',
1838
+ export const Response = OpenApi.component(
1839
+ z
1840
+ .object({
1841
+ asks: z
1842
+ .array(Level)
1843
+ .check(
1844
+ z.describe(
1845
+ 'Ask-side levels, where makers sell base and takers buy it, ordered from best lowest ask outward.',
1846
+ ),
1687
1847
  ),
1688
- ),
1689
- base: PairToken.check(z.describe('Base side of the trading pair.')),
1690
- bids: z
1691
- .array(Level)
1692
- .check(
1693
- z.describe(
1694
- 'Bid-side levels, where makers buy base and takers sell it, ordered from best highest bid outward.',
1848
+ base: PairToken,
1849
+ bids: z
1850
+ .array(Level)
1851
+ .check(
1852
+ z.describe(
1853
+ 'Bid-side levels, where makers buy base and takers sell it, ordered from best highest bid outward.',
1854
+ ),
1695
1855
  ),
1696
- ),
1697
- quote: PairToken.check(z.describe('Quote side of the trading pair.')),
1698
- })
1699
- .check(z.describe('Orderbook depth for one trading pair, with cumulative size at each tick.'))
1856
+ quote: PairToken,
1857
+ })
1858
+ .check(
1859
+ z.describe('Orderbook depth for one trading pair, with cumulative size at each tick.'),
1860
+ ),
1861
+ 'ExchangePairDepth',
1862
+ )
1700
1863
  }
1701
1864
  }
1702
1865
 
@@ -1740,7 +1903,15 @@ export function exchanges(options: exchanges.Options = {}) {
1740
1903
  operationId: 'createExchangeQuote',
1741
1904
  responses: OpenApi.responses({
1742
1905
  errors: {
1743
- 400: { codes: ['body_invalid', 'query_invalid', 'quote_amount_out_of_range'] },
1906
+ 400: {
1907
+ codes: [
1908
+ 'body_invalid',
1909
+ 'chain_id_invalid',
1910
+ 'chain_id_unsupported',
1911
+ 'query_invalid',
1912
+ 'quote_amount_out_of_range',
1913
+ ],
1914
+ },
1744
1915
  404: {
1745
1916
  codes: ['quote_not_available'],
1746
1917
  description:
@@ -2071,6 +2242,8 @@ export function exchanges(options: exchanges.Options = {}) {
2071
2242
  400: {
2072
2243
  codes: [
2073
2244
  'body_invalid',
2245
+ 'chain_id_invalid',
2246
+ 'chain_id_unsupported',
2074
2247
  'query_invalid',
2075
2248
  'swap_continuation_invalid',
2076
2249
  'swap_provider_invalid',
@@ -2166,6 +2339,9 @@ export function exchanges(options: exchanges.Options = {}) {
2166
2339
  operationId: 'getSwaps',
2167
2340
  responses: OpenApi.responses({
2168
2341
  errors: {
2342
+ 400: {
2343
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
2344
+ },
2169
2345
  502: 'The indexer or Tempo RPC could not serve the exchange data right now.',
2170
2346
  },
2171
2347
  success: {
@@ -2324,7 +2500,12 @@ export function exchanges(options: exchanges.Options = {}) {
2324
2500
  description: 'List trading pairs available on Tempo’s built-in stablecoin exchange.',
2325
2501
  operationId: 'getPairs',
2326
2502
  responses: OpenApi.responses({
2327
- errors: { 502: 'The indexer could not serve the exchange data right now.' },
2503
+ errors: {
2504
+ 400: {
2505
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
2506
+ },
2507
+ 502: 'The indexer could not serve the exchange data right now.',
2508
+ },
2328
2509
  success: {
2329
2510
  description: 'A page of exchange trading pairs.',
2330
2511
  schema: schema.getPairs.Response,
@@ -2438,6 +2619,9 @@ export function exchanges(options: exchanges.Options = {}) {
2438
2619
  operationId: 'getPair',
2439
2620
  responses: OpenApi.responses({
2440
2621
  errors: {
2622
+ 400: {
2623
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'pair_invalid', 'query_invalid'],
2624
+ },
2441
2625
  404: {
2442
2626
  description: 'No exchange pair was found for that base token.',
2443
2627
  codes: ['pair_not_found'],
@@ -2528,6 +2712,9 @@ export function exchanges(options: exchanges.Options = {}) {
2528
2712
  operationId: 'getOrders',
2529
2713
  responses: OpenApi.responses({
2530
2714
  errors: {
2715
+ 400: {
2716
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'query_invalid'],
2717
+ },
2531
2718
  404: {
2532
2719
  description: 'No exchange pair was found for the requested `base` filter.',
2533
2720
  codes: ['pair_not_found'],
@@ -2660,6 +2847,9 @@ export function exchanges(options: exchanges.Options = {}) {
2660
2847
  operationId: 'getOrder',
2661
2848
  responses: OpenApi.responses({
2662
2849
  errors: {
2850
+ 400: {
2851
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'order_invalid', 'query_invalid'],
2852
+ },
2663
2853
  404: {
2664
2854
  description: 'No exchange order was found for that id.',
2665
2855
  codes: ['order_not_found'],
@@ -2768,7 +2958,12 @@ export function exchanges(options: exchanges.Options = {}) {
2768
2958
  'List fills for one order. A fill records an execution against the maker order.',
2769
2959
  operationId: 'getOrderFills',
2770
2960
  responses: OpenApi.responses({
2771
- errors: { 502: 'The indexer could not serve the exchange data right now.' },
2961
+ errors: {
2962
+ 400: {
2963
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'order_invalid', 'query_invalid'],
2964
+ },
2965
+ 502: 'The indexer could not serve the exchange data right now.',
2966
+ },
2772
2967
  success: {
2773
2968
  description: 'A page of fills for one order.',
2774
2969
  schema: schema.getOrderFills.Response,
@@ -2858,6 +3053,9 @@ export function exchanges(options: exchanges.Options = {}) {
2858
3053
  operationId: 'getPairOhlc',
2859
3054
  responses: OpenApi.responses({
2860
3055
  errors: {
3056
+ 400: {
3057
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'pair_invalid', 'query_invalid'],
3058
+ },
2861
3059
  404: {
2862
3060
  description: 'No exchange pair was found for that base token.',
2863
3061
  codes: ['pair_not_found'],
@@ -2967,6 +3165,9 @@ export function exchanges(options: exchanges.Options = {}) {
2967
3165
  operationId: 'getPairDepth',
2968
3166
  responses: OpenApi.responses({
2969
3167
  errors: {
3168
+ 400: {
3169
+ codes: ['chain_id_invalid', 'chain_id_unsupported', 'pair_invalid', 'query_invalid'],
3170
+ },
2970
3171
  404: {
2971
3172
  description: 'No exchange pair was found for that base token.',
2972
3173
  codes: ['pair_not_found'],