tapimo 0.11.0 → 0.12.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 (339) hide show
  1. package/dist/App.d.ts +2296 -1010
  2. package/dist/App.d.ts.map +1 -1
  3. package/dist/App.js +2 -2
  4. package/dist/App.js.map +1 -1
  5. package/dist/Assets.d.ts +15 -0
  6. package/dist/Assets.d.ts.map +1 -1
  7. package/dist/Assets.js +7 -0
  8. package/dist/Assets.js.map +1 -1
  9. package/dist/admin/App.d.ts +53 -4
  10. package/dist/admin/App.d.ts.map +1 -1
  11. package/dist/admin/apps/api-keys.d.ts +4 -4
  12. package/dist/admin/apps/earn-vaults.d.ts +114 -0
  13. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  14. package/dist/admin/apps/earn-vaults.js +59 -6
  15. package/dist/admin/apps/earn-vaults.js.map +1 -1
  16. package/dist/admin/apps/organizations.d.ts.map +1 -1
  17. package/dist/admin/apps/organizations.js +4 -2
  18. package/dist/admin/apps/organizations.js.map +1 -1
  19. package/dist/admin/apps/verified-tokens.d.ts +9 -9
  20. package/dist/admin/ui.generated.d.ts +1 -1
  21. package/dist/admin/ui.generated.d.ts.map +1 -1
  22. package/dist/admin/ui.generated.js +151 -151
  23. package/dist/admin/ui.generated.js.map +1 -1
  24. package/dist/apps/data/App.d.ts +1699 -749
  25. package/dist/apps/data/App.d.ts.map +1 -1
  26. package/dist/apps/data/App.js +56 -7
  27. package/dist/apps/data/App.js.map +1 -1
  28. package/dist/apps/data/ZoneSelection.d.ts +62 -0
  29. package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
  30. package/dist/apps/data/ZoneSelection.js +44 -0
  31. package/dist/apps/data/ZoneSelection.js.map +1 -0
  32. package/dist/apps/data/routes/activities.d.ts +2367 -4
  33. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  34. package/dist/apps/data/routes/activities.js +368 -87
  35. package/dist/apps/data/routes/activities.js.map +1 -1
  36. package/dist/apps/data/routes/addresses.d.ts +471 -340
  37. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  38. package/dist/apps/data/routes/balances.d.ts +28 -28
  39. package/dist/apps/data/routes/balances.js +1 -1
  40. package/dist/apps/data/routes/balances.js.map +1 -1
  41. package/dist/apps/data/routes/blocks.d.ts +4 -4
  42. package/dist/apps/data/routes/blocks.js +1 -1
  43. package/dist/apps/data/routes/blocks.js.map +1 -1
  44. package/dist/apps/data/routes/coingecko.d.ts +176 -176
  45. package/dist/apps/data/routes/earn.d.ts +131 -6
  46. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  47. package/dist/apps/data/routes/earn.js +157 -25
  48. package/dist/apps/data/routes/earn.js.map +1 -1
  49. package/dist/apps/data/routes/exchanges.d.ts +825 -119
  50. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  51. package/dist/apps/data/routes/exchanges.js +16 -13
  52. package/dist/apps/data/routes/exchanges.js.map +1 -1
  53. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  54. package/dist/apps/data/routes/fee-amm.js +9 -11
  55. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  56. package/dist/apps/data/routes/indexer.d.ts +34 -34
  57. package/dist/apps/data/routes/receipts.d.ts +230 -230
  58. package/dist/apps/data/routes/receipts.js +1 -1
  59. package/dist/apps/data/routes/receipts.js.map +1 -1
  60. package/dist/apps/data/routes/rpc.js +24 -10
  61. package/dist/apps/data/routes/rpc.js.map +1 -1
  62. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  63. package/dist/apps/data/routes/tokenlist.js +16 -15
  64. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  65. package/dist/apps/data/routes/tokens.d.ts +14 -0
  66. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  67. package/dist/apps/data/routes/tokens.js +34 -15
  68. package/dist/apps/data/routes/tokens.js.map +1 -1
  69. package/dist/apps/data/routes/transactions.js +1 -1
  70. package/dist/apps/data/routes/transactions.js.map +1 -1
  71. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  72. package/dist/apps/data/routes/transfers.js +7 -9
  73. package/dist/apps/data/routes/transfers.js.map +1 -1
  74. package/dist/apps/data/routes/webhooks.d.ts +4 -4
  75. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  76. package/dist/apps/data/routes/webhooks.js +2 -2
  77. package/dist/apps/data/routes/webhooks.js.map +1 -1
  78. package/dist/apps/data/routes/zones.d.ts +30 -30
  79. package/dist/apps/funding/App.d.ts +27 -27
  80. package/dist/apps/funding/routes/chains.d.ts.map +1 -1
  81. package/dist/apps/funding/routes/chains.js +5 -4
  82. package/dist/apps/funding/routes/chains.js.map +1 -1
  83. package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
  84. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  85. package/dist/apps/funding/routes/deposit-addresses.js +8 -8
  86. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  87. package/dist/apps/funding/routes/providers.d.ts +13 -13
  88. package/dist/apps/funding/routes/providers.d.ts.map +1 -1
  89. package/dist/apps/funding/routes/providers.js +3 -2
  90. package/dist/apps/funding/routes/providers.js.map +1 -1
  91. package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
  92. package/dist/apps/funding/routes/quotes.js +2 -2
  93. package/dist/apps/funding/routes/quotes.js.map +1 -1
  94. package/dist/apps/management/App.d.ts +627 -293
  95. package/dist/apps/management/App.d.ts.map +1 -1
  96. package/dist/apps/management/Billing.d.ts.map +1 -1
  97. package/dist/apps/management/Billing.js +19 -6
  98. package/dist/apps/management/Billing.js.map +1 -1
  99. package/dist/apps/management/routes/api-keys.d.ts +114 -54
  100. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  101. package/dist/apps/management/routes/api-keys.js +76 -30
  102. package/dist/apps/management/routes/api-keys.js.map +1 -1
  103. package/dist/apps/management/routes/billing.d.ts +103 -30
  104. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  105. package/dist/apps/management/routes/billing.js +91 -32
  106. package/dist/apps/management/routes/billing.js.map +1 -1
  107. package/dist/apps/management/routes/faucet.d.ts +33 -33
  108. package/dist/apps/management/routes/faucet.d.ts.map +1 -1
  109. package/dist/apps/management/routes/faucet.js +23 -12
  110. package/dist/apps/management/routes/faucet.js.map +1 -1
  111. package/dist/apps/management/routes/invitations.d.ts +46 -13
  112. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  113. package/dist/apps/management/routes/invitations.js +79 -29
  114. package/dist/apps/management/routes/invitations.js.map +1 -1
  115. package/dist/apps/management/routes/invite-links.d.ts +86 -41
  116. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  117. package/dist/apps/management/routes/invite-links.js +100 -41
  118. package/dist/apps/management/routes/invite-links.js.map +1 -1
  119. package/dist/apps/management/routes/me.d.ts +5 -5
  120. package/dist/apps/management/routes/me.d.ts.map +1 -1
  121. package/dist/apps/management/routes/me.js +14 -10
  122. package/dist/apps/management/routes/me.js.map +1 -1
  123. package/dist/apps/management/routes/members.d.ts +93 -72
  124. package/dist/apps/management/routes/members.d.ts.map +1 -1
  125. package/dist/apps/management/routes/members.js +37 -18
  126. package/dist/apps/management/routes/members.js.map +1 -1
  127. package/dist/apps/management/routes/orgs.d.ts +48 -8
  128. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  129. package/dist/apps/management/routes/orgs.js +48 -19
  130. package/dist/apps/management/routes/orgs.js.map +1 -1
  131. package/dist/apps/management/routes/projects.d.ts +90 -28
  132. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  133. package/dist/apps/management/routes/projects.js +72 -21
  134. package/dist/apps/management/routes/projects.js.map +1 -1
  135. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  136. package/dist/apps/management/routes/scopes.js +8 -5
  137. package/dist/apps/management/routes/scopes.js.map +1 -1
  138. package/dist/apps/management/routes/usage.d.ts +78 -78
  139. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  140. package/dist/apps/management/routes/usage.js +41 -31
  141. package/dist/apps/management/routes/usage.js.map +1 -1
  142. package/dist/apps/management/routes/verified-token-requests.d.ts +34 -6
  143. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  144. package/dist/apps/management/routes/verified-token-requests.js +36 -17
  145. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  146. package/dist/apps/management/routes/webhooks.d.ts +147 -130
  147. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  148. package/dist/apps/management/routes/webhooks.js +80 -35
  149. package/dist/apps/management/routes/webhooks.js.map +1 -1
  150. package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
  151. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  152. package/dist/apps/mpp/internal/Adapter.js +12 -0
  153. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  154. package/dist/db/Db.d.ts +2 -0
  155. package/dist/db/Db.d.ts.map +1 -1
  156. package/dist/db/Db.js +40 -0
  157. package/dist/db/Db.js.map +1 -1
  158. package/dist/db/Schema.d.ts +23 -1
  159. package/dist/db/Schema.d.ts.map +1 -1
  160. package/dist/db/Schema.js +19 -3
  161. package/dist/db/Schema.js.map +1 -1
  162. package/dist/db/tables/earnVaults.d.ts +5 -1
  163. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  164. package/dist/db/tables/earnVaults.js +5 -0
  165. package/dist/db/tables/earnVaults.js.map +1 -1
  166. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
  167. package/dist/db/tables/webhookDeliveries.js +10 -0
  168. package/dist/db/tables/webhookDeliveries.js.map +1 -1
  169. package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
  170. package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
  171. package/dist/db/tables/webhookQueueCompletions.js +32 -0
  172. package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
  173. package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
  174. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  175. package/dist/db/tables/webhookQueueEvents.js +68 -47
  176. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  177. package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
  178. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  179. package/dist/db/tables/webhookSubscriptions.js +29 -5
  180. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  181. package/dist/internal/Auth.d.ts +8 -1
  182. package/dist/internal/Auth.d.ts.map +1 -1
  183. package/dist/internal/Auth.js +13 -3
  184. package/dist/internal/Auth.js.map +1 -1
  185. package/dist/internal/Cache.d.ts.map +1 -1
  186. package/dist/internal/Cache.js +11 -7
  187. package/dist/internal/Cache.js.map +1 -1
  188. package/dist/internal/EarnVaults.d.ts +41 -2
  189. package/dist/internal/EarnVaults.d.ts.map +1 -1
  190. package/dist/internal/EarnVaults.js +167 -0
  191. package/dist/internal/EarnVaults.js.map +1 -1
  192. package/dist/internal/OpenApi.d.ts +26 -22
  193. package/dist/internal/OpenApi.d.ts.map +1 -1
  194. package/dist/internal/OpenApi.js +128 -39
  195. package/dist/internal/OpenApi.js.map +1 -1
  196. package/dist/internal/Response.d.ts +13 -8
  197. package/dist/internal/Response.d.ts.map +1 -1
  198. package/dist/internal/Response.js +16 -5
  199. package/dist/internal/Response.js.map +1 -1
  200. package/dist/internal/Schema.d.ts +5 -7
  201. package/dist/internal/Schema.d.ts.map +1 -1
  202. package/dist/internal/Schema.js +6 -7
  203. package/dist/internal/Schema.js.map +1 -1
  204. package/dist/internal/Store.d.ts +15 -6
  205. package/dist/internal/Store.d.ts.map +1 -1
  206. package/dist/internal/Store.js +45 -15
  207. package/dist/internal/Store.js.map +1 -1
  208. package/dist/internal/Tidx.d.ts +2 -0
  209. package/dist/internal/Tidx.d.ts.map +1 -1
  210. package/dist/internal/Tidx.js +16 -4
  211. package/dist/internal/Tidx.js.map +1 -1
  212. package/dist/internal/Webhooks.d.ts +29 -12
  213. package/dist/internal/Webhooks.d.ts.map +1 -1
  214. package/dist/internal/Webhooks.js +37 -20
  215. package/dist/internal/Webhooks.js.map +1 -1
  216. package/dist/internal/funding/Deposit.d.ts +2 -2
  217. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  218. package/dist/internal/funding/Deposit.js +9 -8
  219. package/dist/internal/funding/Deposit.js.map +1 -1
  220. package/dist/internal/funding/DepositAddress.d.ts +4 -4
  221. package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
  222. package/dist/internal/funding/DepositAddress.js +9 -8
  223. package/dist/internal/funding/DepositAddress.js.map +1 -1
  224. package/dist/internal/funding/Provider.d.ts.map +1 -1
  225. package/dist/internal/funding/Provider.js +13 -12
  226. package/dist/internal/funding/Provider.js.map +1 -1
  227. package/dist/internal/funding/providers/stargate.d.ts +19 -0
  228. package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
  229. package/dist/internal/funding/providers/stargate.js +143 -0
  230. package/dist/internal/funding/providers/stargate.js.map +1 -0
  231. package/dist/providers/index.d.ts +7 -0
  232. package/dist/providers/index.d.ts.map +1 -1
  233. package/dist/providers/index.js +3 -0
  234. package/dist/providers/index.js.map +1 -1
  235. package/package.json +2 -2
  236. package/src/App.test.ts +48 -0
  237. package/src/App.ts +4 -2
  238. package/src/Assets.test.ts +18 -0
  239. package/src/Assets.ts +22 -0
  240. package/src/Client.test-d.ts +265 -16
  241. package/src/admin/apps/earn-vaults.test.ts +143 -0
  242. package/src/admin/apps/earn-vaults.ts +83 -6
  243. package/src/admin/apps/organizations.ts +6 -2
  244. package/src/admin/ui/src/routes/api-keys.tsx +36 -0
  245. package/src/admin/ui.generated.ts +151 -189
  246. package/src/apps/data/App.test.ts +31 -0
  247. package/src/apps/data/App.ts +56 -8
  248. package/src/apps/data/ZoneSelection.test.ts +196 -0
  249. package/src/apps/data/ZoneSelection.ts +108 -0
  250. package/src/apps/data/routes/activities.test.ts +328 -1
  251. package/src/apps/data/routes/activities.ts +498 -93
  252. package/src/apps/data/routes/balances.ts +1 -1
  253. package/src/apps/data/routes/blocks.ts +1 -1
  254. package/src/apps/data/routes/earn.test.ts +183 -23
  255. package/src/apps/data/routes/earn.ts +225 -29
  256. package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
  257. package/src/apps/data/routes/exchanges.test.ts +31 -1
  258. package/src/apps/data/routes/exchanges.ts +19 -15
  259. package/src/apps/data/routes/fee-amm.ts +18 -11
  260. package/src/apps/data/routes/receipts.ts +1 -1
  261. package/src/apps/data/routes/rpc.test.ts +75 -0
  262. package/src/apps/data/routes/rpc.ts +23 -9
  263. package/src/apps/data/routes/tokenlist.ts +21 -18
  264. package/src/apps/data/routes/tokens.test.ts +29 -0
  265. package/src/apps/data/routes/tokens.ts +38 -15
  266. package/src/apps/data/routes/transactions.ts +1 -1
  267. package/src/apps/data/routes/transfers.test.ts +3 -3
  268. package/src/apps/data/routes/transfers.ts +12 -9
  269. package/src/apps/data/routes/webhooks.ts +6 -2
  270. package/src/apps/data/routes/zones.test.ts +19 -13
  271. package/src/apps/funding/routes/chains.test.ts +211 -7
  272. package/src/apps/funding/routes/chains.ts +19 -12
  273. package/src/apps/funding/routes/deposit-addresses.test.ts +394 -0
  274. package/src/apps/funding/routes/deposit-addresses.ts +84 -72
  275. package/src/apps/funding/routes/providers.ts +9 -5
  276. package/src/apps/funding/routes/quotes.test.ts +46 -0
  277. package/src/apps/funding/routes/quotes.ts +8 -5
  278. package/src/apps/funding/routes/transfers.test.ts +35 -32
  279. package/src/apps/management/Billing.test.ts +26 -0
  280. package/src/apps/management/Billing.ts +24 -7
  281. package/src/apps/management/routes/api-keys.test.ts +178 -0
  282. package/src/apps/management/routes/api-keys.ts +203 -144
  283. package/src/apps/management/routes/billing.test.ts +209 -0
  284. package/src/apps/management/routes/billing.ts +254 -177
  285. package/src/apps/management/routes/faucet.test.ts +39 -0
  286. package/src/apps/management/routes/faucet.ts +75 -41
  287. package/src/apps/management/routes/invitations.test.ts +216 -0
  288. package/src/apps/management/routes/invitations.ts +186 -109
  289. package/src/apps/management/routes/invite-links.test.ts +263 -1
  290. package/src/apps/management/routes/invite-links.ts +295 -214
  291. package/src/apps/management/routes/me.test.ts +49 -0
  292. package/src/apps/management/routes/me.ts +42 -32
  293. package/src/apps/management/routes/members.test.ts +124 -1
  294. package/src/apps/management/routes/members.ts +81 -51
  295. package/src/apps/management/routes/orgs.test.ts +176 -0
  296. package/src/apps/management/routes/orgs.ts +101 -59
  297. package/src/apps/management/routes/projects.test.ts +183 -0
  298. package/src/apps/management/routes/projects.ts +124 -60
  299. package/src/apps/management/routes/scopes.test.ts +44 -0
  300. package/src/apps/management/routes/scopes.ts +37 -28
  301. package/src/apps/management/routes/usage.test.ts +92 -0
  302. package/src/apps/management/routes/usage.ts +186 -151
  303. package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
  304. package/src/apps/management/routes/verified-token-requests.ts +166 -133
  305. package/src/apps/management/routes/webhooks.test.ts +234 -0
  306. package/src/apps/management/routes/webhooks.ts +191 -78
  307. package/src/apps/mpp/internal/Adapter.ts +13 -1
  308. package/src/db/Db.test.ts +41 -0
  309. package/src/db/Db.ts +62 -0
  310. package/src/db/Schema.ts +28 -3
  311. package/src/db/tables/earnVaults.test.ts +22 -0
  312. package/src/db/tables/earnVaults.ts +11 -1
  313. package/src/db/tables/webhookDeliveries.ts +13 -0
  314. package/src/db/tables/webhookQueueCompletions.ts +55 -0
  315. package/src/db/tables/webhookQueueEvents.ts +95 -61
  316. package/src/db/tables/webhookSubscriptions.ts +45 -6
  317. package/src/internal/Auth.ts +23 -5
  318. package/src/internal/Cache.ts +14 -7
  319. package/src/internal/EarnVaults.capabilities.test.ts +33 -0
  320. package/src/internal/EarnVaults.test.ts +79 -0
  321. package/src/internal/EarnVaults.ts +277 -0
  322. package/src/internal/OpenApi.ts +165 -49
  323. package/src/internal/Response.test.ts +95 -0
  324. package/src/internal/Response.ts +40 -2
  325. package/src/internal/Schema.test.ts +16 -0
  326. package/src/internal/Schema.ts +7 -7
  327. package/src/internal/Store.test.ts +186 -0
  328. package/src/internal/Store.ts +57 -17
  329. package/src/internal/Tidx.test.ts +19 -0
  330. package/src/internal/Tidx.ts +16 -4
  331. package/src/internal/Webhooks.test.ts +122 -8
  332. package/src/internal/Webhooks.ts +59 -29
  333. package/src/internal/funding/Deposit.ts +71 -64
  334. package/src/internal/funding/DepositAddress.ts +50 -43
  335. package/src/internal/funding/Provider.ts +164 -142
  336. package/src/internal/funding/providers/index.test.ts +185 -0
  337. package/src/internal/funding/providers/stargate.ts +184 -0
  338. package/src/providers/index.test.ts +1 -0
  339. package/src/providers/index.ts +9 -0
@@ -1,3 +1,4 @@
1
+ import { ZoneId } from 'ox/tempo'
1
2
  import {
2
3
  ContractFunctionExecutionError,
3
4
  ContractFunctionRevertedError,
@@ -161,6 +162,28 @@ export namespace schema {
161
162
  })
162
163
  .check(z.describe('Onchain identity of an Earn vault.'))
163
164
 
165
+ /** Schema for one curated Earn route through a private Zone. */
166
+ export const ZoneRoute = z
167
+ .strictObject({
168
+ chainId: Schema.ChainId.check(
169
+ z.describe('Private Zone chain id.'),
170
+ z.meta({ examples: [1424310001] }),
171
+ ),
172
+ deploymentBlock: z
173
+ .number()
174
+ .check(
175
+ z.int(),
176
+ z.nonnegative(),
177
+ z.describe('Parent-chain block that deployed the Earn router.'),
178
+ z.meta({ examples: [31039238] }),
179
+ ),
180
+ earnRouter: Schema.Address.check(
181
+ z.describe('Parent-chain router for this Zone and Earn vault.'),
182
+ z.meta({ examples: ['0x9144086a79dea966d8bf1b52125ebed8919fc45c'] }),
183
+ ),
184
+ })
185
+ .check(z.describe('Curated Earn route through one private Zone.'))
186
+
164
187
  /** Schema for live state resolved from one Earn vault. */
165
188
  export const Discovery = z
166
189
  .strictObject({
@@ -228,12 +251,48 @@ export type Discovery = z.output<typeof schema.Discovery>
228
251
  /** Onchain identity of an Earn vault. */
229
252
  export type ResolveInput = z.output<typeof schema.ResolveInput>
230
253
 
254
+ /** Curated Earn route through one private Zone. */
255
+ export type ZoneRoute = z.output<typeof schema.ZoneRoute>
256
+
257
+ /** Curated Zone route with immutable router bindings resolved onchain. */
258
+ export type ResolvedZoneRoute = ZoneRoute & {
259
+ /** Tokens accepted by private deposits. */
260
+ inputTokens: readonly Address[]
261
+ /** Configured private Zone name. */
262
+ name: string
263
+ /** Tokens returned by private redemptions. */
264
+ outputTokens: readonly Address[]
265
+ }
266
+
267
+ /** Adds capabilities proven by a verified private Zone route. */
268
+ export function addZoneRouteCapabilities(
269
+ capabilities: NonNullable<Discovery['capabilities']>,
270
+ ): NonNullable<Discovery['capabilities']> {
271
+ return { ...capabilities, privateRouting: true, routerSwaps: true }
272
+ }
273
+
274
+ /** Derives a Zone ID from any supported Zone chain-ID scheme. */
275
+ export function deriveZoneId(chainId: number): number {
276
+ for (const sourceId of [4_217, 42_431] satisfies readonly ZoneId.SourceId[]) {
277
+ const zoneId = ZoneId.fromChainId(chainId, sourceId)
278
+ if (zoneId >= 0 && ZoneId.toChainId(zoneId, sourceId) === chainId) return zoneId
279
+ }
280
+ throw new InvalidRegistryError(`Chain ${chainId} does not use a supported Zone chain-ID scheme.`)
281
+ }
282
+
231
283
  /** Stable code describing an onchain verification issue. */
232
284
  export type VerificationIssueCode =
233
285
  | 'chain-mismatch'
234
286
  | 'engine-asset-mismatch'
235
287
  | 'policy-unsupported'
236
288
  | 'read-failed'
289
+ | 'zone-deployment-block-mismatch'
290
+ | 'zone-flow-unsupported'
291
+ | 'zone-id-mismatch'
292
+ | 'zone-router-invalid'
293
+ | 'zone-share-mismatch'
294
+ | 'zone-vault-asset-mismatch'
295
+ | 'zone-vault-mismatch'
237
296
 
238
297
  /** One onchain verification issue. */
239
298
  export type VerificationIssue = {
@@ -303,6 +362,16 @@ type RouterCapabilities = {
303
362
  redeem: boolean
304
363
  }
305
364
 
365
+ type ZoneRouteBindings = {
366
+ allowedZoneId: number
367
+ deposit: boolean
368
+ earnShare: Address
369
+ earnVault: Address
370
+ privateAsset: Address
371
+ redeem: boolean
372
+ vaultAsset: Address
373
+ }
374
+
306
375
  type TokenMetadata = Omit<Discovery['assetToken'], 'address'>
307
376
 
308
377
  const engineBindingsAbi = parseAbi(['function vault() view returns (address)'])
@@ -363,6 +432,139 @@ export declare namespace resolve {
363
432
  }
364
433
  }
365
434
 
435
+ /** Resolves and verifies every curated Zone route for one Earn vault. */
436
+ export async function resolveZoneRoutes(
437
+ options: resolveZoneRoutes.Options,
438
+ ): Promise<ResolvedZoneRoute[]> {
439
+ const result = z.array(schema.ZoneRoute).safeParse(options.routes)
440
+ if (!result.success) throw invalid(result.error)
441
+
442
+ const chainIds = new Set<number>()
443
+ const routers = new Set<string>()
444
+ for (const route of result.data) {
445
+ if (chainIds.has(route.chainId))
446
+ throw new InvalidRegistryError(`Zone ${route.chainId} is configured more than once.`)
447
+ if (routers.has(route.earnRouter))
448
+ throw new InvalidRegistryError(
449
+ `Earn router ${route.earnRouter} is configured more than once.`,
450
+ )
451
+ chainIds.add(route.chainId)
452
+ routers.add(route.earnRouter)
453
+ }
454
+ if (result.data.length === 0) return []
455
+
456
+ const client = options.getClient(options.discovery.chainId)
457
+ return Promise.all(
458
+ result.data.map(async (route) => {
459
+ const zone = options.zones.find((candidate) => candidate.id === route.chainId)
460
+ if (!zone) throw new InvalidRegistryError(`Zone ${route.chainId} is not configured.`)
461
+ if (zone.sourceId !== options.discovery.chainId)
462
+ throw new InvalidRegistryError(
463
+ `Zone ${route.chainId} does not belong to chain ${options.discovery.chainId}.`,
464
+ )
465
+ const expectedZoneId = deriveZoneId(route.chainId)
466
+
467
+ const [code, previousCode] = await Promise.all([
468
+ client.getCode({
469
+ address: route.earnRouter,
470
+ blockNumber: BigInt(route.deploymentBlock),
471
+ }),
472
+ route.deploymentBlock === 0
473
+ ? undefined
474
+ : client.getCode({
475
+ address: route.earnRouter,
476
+ blockNumber: BigInt(route.deploymentBlock - 1),
477
+ }),
478
+ ])
479
+ if (!code || code === '0x' || (previousCode !== undefined && previousCode !== '0x'))
480
+ throw mismatch({
481
+ discovery: options.discovery,
482
+ issues: [
483
+ {
484
+ actual: String(route.deploymentBlock),
485
+ code: 'zone-deployment-block-mismatch',
486
+ message: 'Earn router deployment block does not match its code boundary.',
487
+ },
488
+ ],
489
+ })
490
+
491
+ const bindings = await readZoneRouteBindings(client, { earnRouter: route.earnRouter }).catch(
492
+ (error) => {
493
+ if (!isMissingOptionalFunctionError(error)) throw error
494
+ throw mismatch({
495
+ discovery: options.discovery,
496
+ issues: [
497
+ {
498
+ actual: route.earnRouter,
499
+ code: 'zone-router-invalid',
500
+ message: 'Earn router does not expose the required immutable bindings.',
501
+ },
502
+ ],
503
+ })
504
+ },
505
+ )
506
+ const issues: VerificationIssue[] = []
507
+ if (bindings.allowedZoneId !== expectedZoneId)
508
+ issues.push({
509
+ actual: bindings.allowedZoneId.toString(),
510
+ code: 'zone-id-mismatch',
511
+ expected: String(expectedZoneId),
512
+ message: 'Earn router is configured for a different Zone.',
513
+ })
514
+ compareAddress(
515
+ issues,
516
+ 'zone-vault-mismatch',
517
+ 'Earn router is configured for a different Earn vault.',
518
+ options.discovery.vaultAddress,
519
+ bindings.earnVault,
520
+ )
521
+ compareAddress(
522
+ issues,
523
+ 'zone-vault-asset-mismatch',
524
+ 'Earn router vault asset does not match the Earn vault.',
525
+ options.discovery.assetToken.address,
526
+ bindings.vaultAsset,
527
+ )
528
+ compareAddress(
529
+ issues,
530
+ 'zone-share-mismatch',
531
+ 'Earn router share token does not match the Earn vault.',
532
+ options.discovery.shareToken.address,
533
+ bindings.earnShare,
534
+ )
535
+ if (!bindings.deposit || !bindings.redeem)
536
+ issues.push({
537
+ actual: `deposit=${bindings.deposit},redeem=${bindings.redeem}`,
538
+ code: 'zone-flow-unsupported',
539
+ expected: 'deposit=true,redeem=true',
540
+ message: 'Earn router must support private deposits and redemptions.',
541
+ })
542
+ if (issues.length > 0) throw mismatch({ discovery: options.discovery, issues })
543
+
544
+ return {
545
+ ...route,
546
+ inputTokens: [bindings.privateAsset],
547
+ name: zone.name,
548
+ outputTokens: [bindings.privateAsset],
549
+ }
550
+ }),
551
+ )
552
+ }
553
+
554
+ export declare namespace resolveZoneRoutes {
555
+ /** Inputs for resolving and verifying curated Zone routes. */
556
+ type Options = {
557
+ /** Live state of the Earn vault bound by every router. */
558
+ discovery: Discovery
559
+ /** Resolves the parent-chain client used to read each router. */
560
+ getClient: Viem.GetClient
561
+ /** Curated Zone routes to verify. */
562
+ routes: unknown
563
+ /** Private Zones configured by the API. */
564
+ zones: readonly Chain[]
565
+ }
566
+ }
567
+
366
568
  /** Infers the supported engine type from its capability fingerprint. */
367
569
  export function classifyEngineType(
368
570
  options: classifyEngineType.Options,
@@ -729,6 +931,60 @@ declare namespace readEngineBindings {
729
931
  }
730
932
  }
731
933
 
934
+ async function readZoneRouteBindings(
935
+ client: Client,
936
+ options: readZoneRouteBindings.Options,
937
+ ): Promise<ZoneRouteBindings> {
938
+ const [allowedZoneId, earnShare, earnVault, privateAsset, vaultAsset, deposit, redeem] =
939
+ await Promise.all([
940
+ client.readContract({
941
+ abi: Abis.earnRouter,
942
+ address: options.earnRouter,
943
+ functionName: 'allowedZoneId',
944
+ }),
945
+ client.readContract({
946
+ abi: Abis.earnRouter,
947
+ address: options.earnRouter,
948
+ functionName: 'earnShare',
949
+ }),
950
+ client.readContract({
951
+ abi: Abis.earnRouter,
952
+ address: options.earnRouter,
953
+ functionName: 'earnVault',
954
+ }),
955
+ client.readContract({
956
+ abi: Abis.earnRouter,
957
+ address: options.earnRouter,
958
+ functionName: 'privateAsset',
959
+ }),
960
+ client.readContract({
961
+ abi: Abis.earnRouter,
962
+ address: options.earnRouter,
963
+ functionName: 'vaultAsset',
964
+ }),
965
+ client.readContract({
966
+ abi: Abis.earnRouter,
967
+ address: options.earnRouter,
968
+ args: [0],
969
+ functionName: 'supportsFlow',
970
+ }),
971
+ client.readContract({
972
+ abi: Abis.earnRouter,
973
+ address: options.earnRouter,
974
+ args: [1],
975
+ functionName: 'supportsFlow',
976
+ }),
977
+ ])
978
+ return { allowedZoneId, deposit, earnShare, earnVault, privateAsset, redeem, vaultAsset }
979
+ }
980
+
981
+ declare namespace readZoneRouteBindings {
982
+ type Options = {
983
+ /** Parent-chain Earn router to inspect. */
984
+ earnRouter: Address
985
+ }
986
+ }
987
+
732
988
  async function readRouterCapabilities(
733
989
  client: Client,
734
990
  options: readRouterCapabilities.Options,
@@ -840,6 +1096,27 @@ function compareAddress(
840
1096
  if (!isAddressEqual(actual, expected)) issues.push({ actual, code, expected, message })
841
1097
  }
842
1098
 
1099
+ function mismatch(options: mismatch.Options): VerificationError {
1100
+ return new VerificationError({
1101
+ issues: options.issues,
1102
+ snapshot: {
1103
+ assetToken: options.discovery.assetToken,
1104
+ isSynced: options.discovery.state.isAccountingAligned,
1105
+ shareToken: options.discovery.shareToken,
1106
+ },
1107
+ status: 'mismatch',
1108
+ })
1109
+ }
1110
+
1111
+ declare namespace mismatch {
1112
+ type Options = {
1113
+ /** Live vault state captured with the mismatch. */
1114
+ discovery: Discovery
1115
+ /** Verification issues that rejected the deployment. */
1116
+ issues: readonly VerificationIssue[]
1117
+ }
1118
+ }
1119
+
843
1120
  function unavailable(): VerificationUnavailable {
844
1121
  return {
845
1122
  issues: [
@@ -1,6 +1,13 @@
1
1
  import type { Context, Env, MiddlewareHandler, ValidationTargets } from 'hono'
2
2
  import type { HasRequiredKeys } from 'hono/utils/types'
3
- import { resolver, type ResponsesWithResolver, validator } from 'hono-openapi'
3
+ import {
4
+ describeRoute as core_describeRoute,
5
+ type DescribeRouteOptions,
6
+ resolver,
7
+ type ResponsesWithResolver,
8
+ uniqueSymbol,
9
+ validator,
10
+ } from 'hono-openapi'
4
11
  import * as z from 'zod/mini'
5
12
  import * as Response from './Response.js'
6
13
  import * as Schema from './Schema.js'
@@ -41,7 +48,6 @@ const schemaOptions = { options: { override: recoverExamples, unrepresentable: '
41
48
  // re-exports because `uniqueSymbol` is a `unique symbol` whose identity is
42
49
  // lost when copied through a `const` declaration.
43
50
  export {
44
- describeRoute,
45
51
  type HandlerUniqueProperty,
46
52
  resolver,
47
53
  type ResponsesWithResolver,
@@ -49,12 +55,53 @@ export {
49
55
  validator,
50
56
  } from 'hono-openapi'
51
57
 
58
+ function cloneResponseContainers(spec: DescribeRouteOptions): DescribeRouteOptions {
59
+ if (!spec.responses) return spec
60
+ return {
61
+ ...spec,
62
+ responses: Object.fromEntries(
63
+ Object.entries(spec.responses).map(([status, response]) => [
64
+ status,
65
+ !response || !('content' in response)
66
+ ? response
67
+ : {
68
+ ...response,
69
+ content: Object.fromEntries(
70
+ Object.entries(response.content ?? {}).map(([mediaType, media]) => [
71
+ mediaType,
72
+ { ...media },
73
+ ]),
74
+ ),
75
+ },
76
+ ]),
77
+ ),
78
+ }
79
+ }
80
+
81
+ /** Describes a route without allowing spec generation to mutate reusable response definitions. */
82
+ export function describeRoute(spec: DescribeRouteOptions): MiddlewareHandler {
83
+ const handler = core_describeRoute(spec)
84
+ Object.defineProperty(handler, uniqueSymbol, {
85
+ get: () => ({ spec: cloneResponseContainers(spec) }),
86
+ })
87
+ return handler
88
+ }
89
+
90
+ /** Emits a named OpenAPI component and uses its `$ref` wherever the schema appears. */
91
+ export function component<const schema extends z.ZodMiniType>(
92
+ schema: schema,
93
+ name: string,
94
+ ): schema {
95
+ const cloned = schema.clone()
96
+ z.globalRegistry.add(cloned, { ...z.globalRegistry.get(schema), ref: name })
97
+ return cloned as schema
98
+ }
99
+
52
100
  /**
53
101
  * Standard machine-readable `error.code` values per status, shared API-wide.
54
102
  * The reference enumerates `error.code` to these so generated clients narrow it
55
- * to a literal union instead of an open `string`. 400 and 404 vary per
56
- * operation; the values here are the API-wide supersets, narrowable per route
57
- * via the `codes` override in {@link responses.Options}.
103
+ * to a literal union instead of an open `string`. The values here are shared
104
+ * defaults; operation-specific codes are supplied through {@link responses.Options}.
58
105
  */
59
106
  export const errorCodes = {
60
107
  400: [
@@ -80,7 +127,7 @@ export const errorCodes = {
80
127
  'api_key_malformed',
81
128
  ],
82
129
  401: ['api_key_missing', 'api_key_invalid', 'unauthorized'],
83
- 403: ['api_key_forbidden', 'api_key_ip_forbidden', 'limit_exceeded'],
130
+ 403: ['api_key_forbidden', 'api_key_ip_forbidden', 'forbidden'],
84
131
  404: [
85
132
  'not_found',
86
133
  'token_not_found',
@@ -164,11 +211,78 @@ export const rateLimitHeaders = {
164
211
  /** Representative `requestId` used in error-body examples. */
165
212
  const exampleRequestId = '0a1b2c3d-4e5f-6071-8293-a4b5c6d7e8f9'
166
213
 
167
- /** Builds the `application/json` content for a standard error response: the enumerated-code envelope plus an example body. */
168
- function errorContent(codes: readonly [string, ...string[]] | undefined, message: string) {
214
+ const standardErrorNames = {
215
+ 400: 'InvalidRequestError',
216
+ 401: 'AuthenticationError',
217
+ 403: 'ForbiddenError',
218
+ 404: 'ResourceNotFoundError',
219
+ 429: 'RateLimitError',
220
+ 500: 'InternalError',
221
+ 501: 'NotImplementedError',
222
+ 502: 'UpstreamError',
223
+ } as const satisfies Record<keyof typeof errorCodes, string>
224
+
225
+ const reservedErrorNames = new Set<string>(Object.values(standardErrorNames))
226
+ const errorSchemas = new Map<string, z.ZodMiniType>()
227
+
228
+ function errorName(status: number, codes: readonly string[]) {
229
+ const standard = errorCodes[status as keyof typeof errorCodes]
230
+ if (
231
+ standard &&
232
+ standard.length === codes.length &&
233
+ [...standard].sort().every((code, index) => code === codes[index])
234
+ )
235
+ return standardErrorNames[status as keyof typeof standardErrorNames]
236
+ const name = `${codes
237
+ .map((code) =>
238
+ code
239
+ .split('_')
240
+ .map((part) => `${part[0]?.toUpperCase()}${part.slice(1)}`)
241
+ .join(''),
242
+ )
243
+ .join('Or')}Error`
244
+ if (reservedErrorNames.has(name)) return `${name.slice(0, -'Error'.length)}${status}Error`
245
+ return name
246
+ }
247
+
248
+ function errorSchema(status: number, codes: readonly [string, ...string[]] | undefined) {
249
+ const defaults = errorCodes[status as keyof typeof errorCodes]
250
+ if (!codes && !defaults) {
251
+ const cached = errorSchemas.get('*')
252
+ if (cached) return cached
253
+ const schema = component(Schema.errorResponse(), 'ErrorResponse')
254
+ errorSchemas.set('*', schema)
255
+ return schema
256
+ }
257
+ const normalized = [...(codes ?? defaults ?? [])].sort() as [string, ...string[]]
258
+ const key = normalized.join('\0')
259
+ const cached = errorSchemas.get(key)
260
+ if (cached) return cached
261
+ const schema = component(Schema.errorResponse(normalized), errorName(status, normalized))
262
+ errorSchemas.set(key, schema)
263
+ return schema
264
+ }
265
+
266
+ function mergeErrorCodes(
267
+ status: number,
268
+ codes: readonly string[] | undefined,
269
+ ): readonly [string, ...string[]] | undefined {
270
+ if (!codes) return errorCodes[status as keyof typeof errorCodes]
271
+ if (status !== 400 && status !== 403)
272
+ return codes.length ? (codes as [string, ...string[]]) : undefined
273
+ const baseline = status === 400 ? (['api_key_malformed'] as const) : errorCodes[403]
274
+ return [...new Set([...baseline, ...codes])] as [string, ...string[]]
275
+ }
276
+
277
+ /** Builds the `application/json` content for a standard error response: the named enumerated-code envelope plus an example body. */
278
+ function errorContent(
279
+ status: number,
280
+ codes: readonly [string, ...string[]] | undefined,
281
+ message: string,
282
+ ) {
169
283
  return {
170
284
  'application/json': {
171
- schema: resolver(Schema.errorResponse(codes), schemaOptions),
285
+ schema: resolver(errorSchema(status, codes), schemaOptions),
172
286
  example: { error: { code: codes?.[0] ?? 'error', message }, requestId: exampleRequestId },
173
287
  },
174
288
  }
@@ -186,32 +300,30 @@ export const paymentChallenge = {
186
300
  headers: { 'WWW-Authenticate': headerRef('WwwAuthenticate') },
187
301
  } as const
188
302
 
189
- /** Shared `429` rate-limit response, registered as `components.responses.RateLimited`. */
190
- const rateLimitedResponse = {
191
- content: errorContent(errorCodes[429], 'Rate limit exceeded.'),
192
- description:
193
- 'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
194
- headers: { ...rateLimitHeaders },
195
- }
196
-
197
- /** Shared `500` internal-error response, registered as `components.responses.InternalError`. */
198
- const serverErrorResponse = {
199
- content: errorContent(errorCodes[500], 'Internal server error.'),
200
- description: 'Internal server error.',
201
- }
303
+ type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited'
202
304
 
203
305
  /**
204
306
  * Reusable responses registered under `components.responses` (see `App.create`)
205
307
  * and `$ref`-erenced from operations, so the uniform `402`/`429`/`500` responses
206
308
  * are defined once instead of inlined on every operation.
207
309
  */
208
- export const responseComponents: ResponsesWithResolver = {
209
- InternalError: serverErrorResponse,
210
- PaymentRequired: paymentChallenge,
211
- RateLimited: rateLimitedResponse,
310
+ export function responseComponents(): ResponsesWithResolver {
311
+ return {
312
+ InternalError: {
313
+ content: errorContent(500, errorCodes[500], 'Internal server error.'),
314
+ description: 'Internal server error.',
315
+ },
316
+ PaymentRequired: paymentChallenge,
317
+ RateLimited: {
318
+ content: errorContent(429, errorCodes[429], 'Rate limit exceeded.'),
319
+ description:
320
+ 'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
321
+ headers: { ...rateLimitHeaders },
322
+ },
323
+ }
212
324
  }
213
325
 
214
- const responseRef = (name: keyof typeof responseComponents) => ({
326
+ const responseRef = (name: ResponseComponentName) => ({
215
327
  $ref: `#/components/responses/${name}`,
216
328
  })
217
329
 
@@ -232,22 +344,22 @@ export function standardError(
232
344
  ): ResponsesWithResolver[string] {
233
345
  if (status === 429) return responseRef('RateLimited')
234
346
  if (status === 500) return responseRef('InternalError')
235
- return { content: errorContent(codes ?? errorCodes[status], description), description }
347
+ return { content: errorContent(status, mergeErrorCodes(status, codes), description), description }
236
348
  }
237
349
 
238
350
  /**
239
351
  * Builds an OpenAPI `responses` map with the API's standard error responses
240
352
  * pre-filled, plus the success response (with rate-limit headers):
241
353
  *
242
- * - `400` invalid request, `401` missing/invalid key, `429` rate limited,
243
- * `500` internal error, and `502` upstream failure on every operation;
244
- * - `403`/`404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
354
+ * - `400` invalid request, `401` missing/invalid key, `403` forbidden, `429`
355
+ * rate limited, `500` internal error, and `502` upstream failure on every operation;
356
+ * - `404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
245
357
  *
246
- * `error.code` is enumerated per status from {@link errorCodes}; narrow 400/404
247
- * to a route's exact codes by passing `{ description, codes }` for that status.
248
- * `429`/`500` `$ref` the shared {@link responseComponents}. `402` is not emitted
249
- * here it is injected per operation from the route's MPP policy during spec
250
- * generation (see `App.ts`).
358
+ * `error.code` is enumerated per status from {@link errorCodes}. Operation-level
359
+ * 400/403 codes merge with shared auth codes; other overrides replace defaults.
360
+ * The default `429` and `500` `$ref` shared {@link responseComponents}; an exact
361
+ * operation-level `429` override is emitted inline with the standard headers.
362
+ * `402` is injected per operation from the route's MPP policy in `App.ts`.
251
363
  */
252
364
  export function responses<schema extends z.ZodMiniType>(
253
365
  options: responses.Options<schema>,
@@ -257,10 +369,11 @@ export function responses<schema extends z.ZodMiniType>(
257
369
  const override = errors?.[status as 400]
258
370
  const description =
259
371
  typeof override === 'string' ? override : (override?.description ?? fallback)
260
- const codes =
261
- (typeof override === 'object' ? override.codes : undefined) ??
262
- errorCodes[status as keyof typeof errorCodes]
263
- return { content: errorContent(codes, description), description }
372
+ const codes = mergeErrorCodes(status, typeof override === 'object' ? override.codes : undefined)
373
+ return {
374
+ content: errorContent(status, codes, description),
375
+ description,
376
+ }
264
377
  }
265
378
  return {
266
379
  200: {
@@ -279,13 +392,15 @@ export function responses<schema extends z.ZodMiniType>(
279
392
  },
280
393
  400: error(400, 'Invalid request.'),
281
394
  401: error(401, 'Missing or invalid API key.'),
282
- ...(errors?.[403] && { 403: error(403, 'Forbidden.') }),
395
+ 403: error(403, 'Forbidden.'),
283
396
  ...(errors?.[404] && { 404: error(404, 'Not found.') }),
284
397
  ...(errors?.[409] && { 409: error(409, 'Conflict.') }),
285
398
  ...(errors?.[412] && { 412: error(412, 'Precondition failed.') }),
286
399
  ...(errors?.[413] && { 413: error(413, 'Payload too large.') }),
287
400
  ...(errors?.[415] && { 415: error(415, 'Unsupported media type.') }),
288
- 429: responseRef('RateLimited'),
401
+ 429: errors?.[429]
402
+ ? { ...error(429, 'Rate limit exceeded.'), headers: { ...rateLimitHeaders } }
403
+ : responseRef('RateLimited'),
289
404
  500: responseRef('InternalError'),
290
405
  ...(errors?.[501] && { 501: error(501, 'Not implemented.') }),
291
406
  502: error(502, 'Upstream data failure.'),
@@ -295,23 +410,22 @@ export function responses<schema extends z.ZodMiniType>(
295
410
  export declare namespace responses {
296
411
  /**
297
412
  * Override for a standard error response: a description string, or an object
298
- * adding the exact `codes` that status can return (narrowing the enum).
413
+ * adding operation codes. Codes replace defaults except shared 400/403 auth codes.
299
414
  */
300
415
  type ErrorOverride =
301
416
  | string
302
417
  | {
303
418
  /** Human-readable description of the error response. */
304
419
  description?: string | undefined
305
- /** Exact `error.code` values this status returns for the operation. */
306
- codes?: readonly [string, ...string[]] | undefined
420
+ /** Operation-specific `error.code` values for this status. */
421
+ codes?: readonly string[] | undefined
307
422
  }
308
423
 
309
424
  /** Options for building a standard OpenAPI responses map. */
310
425
  type Options<schema> = {
311
426
  /**
312
- * Optional overrides for standard error responses (description and/or exact
313
- * `error.code` enum). Setting `403`/`404`/`409`/`412`/`413`/`415` also
314
- * includes that status in the map.
427
+ * Optional overrides for standard error responses. Setting
428
+ * `404`/`409`/`412`/`413`/`415` includes that status in the map.
315
429
  */
316
430
  errors?:
317
431
  | {
@@ -319,7 +433,7 @@ export declare namespace responses {
319
433
  400?: ErrorOverride | undefined
320
434
  /** Override for the 401 response. */
321
435
  401?: ErrorOverride | undefined
322
- /** Override for the 403 response. Setting this includes 403 in the map. */
436
+ /** Add operation-specific 403 codes or override its description. */
323
437
  403?: ErrorOverride | undefined
324
438
  /** Override for the 404 response. Setting this includes 404 in the map. */
325
439
  404?: ErrorOverride | undefined
@@ -331,6 +445,8 @@ export declare namespace responses {
331
445
  413?: ErrorOverride | undefined
332
446
  /** Override for the 415 response. Setting this includes 415 in the map. */
333
447
  415?: ErrorOverride | undefined
448
+ /** Override the shared 429 response with operation-specific rate-limit codes. */
449
+ 429?: ErrorOverride | undefined
334
450
  /** Override for the 501 response. Setting this includes 501 in the map. */
335
451
  501?: ErrorOverride | undefined
336
452
  /** Override for the 502 response. */