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
@@ -310,11 +310,11 @@ function privateResourceAccess(access: Webhooks.Access) {
310
310
  )
311
311
  return (eb: ExpressionBuilder<Db.Database, 'webhook_subscriptions'>) =>
312
312
  eb.or([
313
- eb('eventType', '!=', 'funding:deposit.updated'),
313
+ sql<boolean>`${eb.ref('eventType')} not like ${'funding:%'}`,
314
314
  ...(fundingRead
315
315
  ? [
316
316
  eb.and([
317
- eb('eventType', '=', 'funding:deposit.updated'),
317
+ sql<boolean>`${eb.ref('eventType')} like ${'funding:%'}`,
318
318
  eb('environment', '=', access.environment),
319
319
  ...(access.projectId === undefined ? [] : [eb('projectId', '=', access.projectId)]),
320
320
  ]),
@@ -390,41 +390,48 @@ export declare namespace listActiveForChain {
390
390
  }
391
391
  }
392
392
 
393
- /** Lists live funding deposit subscriptions visible to one deposit owner. */
394
- export async function listActiveForFundingDeposit(
393
+ /** Lists live funding subscriptions visible to one resource owner. */
394
+ export async function listActiveForFundingEvent(
395
395
  db: Db.Db,
396
- options: listActiveForFundingDeposit.Options,
396
+ options: listActiveForFundingEvent.Options,
397
397
  ): Promise<Webhooks.Subscription[]> {
398
398
  let query = db.kysely
399
399
  .selectFrom('webhook_subscriptions')
400
400
  .selectAll()
401
401
  .where('chainId', '=', options.chainId)
402
402
  .where('environment', '=', options.environment)
403
- .where('eventType', '=', 'funding:deposit.updated')
403
+ .where('eventType', '=', options.eventType)
404
404
  .where('ownerId', '=', options.orgId)
405
405
  .where('ownerType', '=', 'api_key')
406
406
  .where('status', '=', 'active')
407
407
  .where(live(options.now))
408
+ if (options.eventCreatedAt !== undefined)
409
+ query = query.where('createdAt', '<=', options.eventCreatedAt)
408
410
  const projectId = options.projectId
409
411
  query =
410
412
  projectId === undefined
411
413
  ? query.where('projectId', 'is', null)
412
414
  : query.where((eb) => eb.or([eb('projectId', 'is', null), eb('projectId', '=', projectId)]))
413
- return (await query.orderBy('id').execute()).map(toSubscription)
415
+ // Keep subscriptions present until their staged queue events commit.
416
+ return (await query.orderBy('id').forKeyShare().execute()).map(toSubscription)
414
417
  }
415
418
 
416
- export declare namespace listActiveForFundingDeposit {
417
- /** Ownership scope and chain for a funding deposit event. */
419
+ export declare namespace listActiveForFundingEvent {
420
+ /** Ownership scope and chain for a funding resource event. */
418
421
  type Options = {
419
422
  /** Destination Tempo chain id. */
420
423
  chainId: number
421
- /** Deposit API-key environment. */
424
+ /** Resource API-key environment. */
422
425
  environment: 'production' | 'sandbox'
426
+ /** Event timestamp used to keep subscriptions future-only, when supplied. */
427
+ eventCreatedAt?: string | undefined
428
+ /** Funding event type to match. */
429
+ eventType: Extract<Webhooks.EventType, `funding:${string}`>
423
430
  /** ISO timestamp used to exclude expired subscriptions. */
424
431
  now: string
425
432
  /** Owning organization id. */
426
433
  orgId: string
427
- /** Attributed deposit project, when present. */
434
+ /** Attributed funding resource project, when present. */
428
435
  projectId?: string | undefined
429
436
  }
430
437
  }
@@ -0,0 +1,53 @@
1
+ import { RpcRequest } from 'ox'
2
+
3
+ import * as Utils from './utils.js'
4
+
5
+ const request = RpcRequest.from({ id: 1, method: 'eth_sendRawTransaction', params: ['0x'] })
6
+
7
+ describe('rpcErrorJson', () => {
8
+ test('maps upstream expired transactions to a transaction-rejected error', () => {
9
+ const error = {
10
+ cause: {
11
+ code: -32603,
12
+ message:
13
+ 'Revm error: transaction expired: current block timestamp 1755616740 >= validBefore 1755616739',
14
+ },
15
+ }
16
+
17
+ expect(Utils.rpcErrorJson(request, error)).toMatchInlineSnapshot(`
18
+ {
19
+ "error": {
20
+ "code": -32003,
21
+ "data": {
22
+ "code": "transaction_expired",
23
+ },
24
+ "message": "Transaction expired.",
25
+ },
26
+ "id": 1,
27
+ "jsonrpc": "2.0",
28
+ }
29
+ `)
30
+ })
31
+
32
+ test('preserves unrelated upstream internal errors', () => {
33
+ const error = {
34
+ code: -32603,
35
+ data: { reason: 'database unavailable' },
36
+ message: 'Revm error: database unavailable',
37
+ }
38
+
39
+ expect(Utils.rpcErrorJson(request, error)).toMatchInlineSnapshot(`
40
+ {
41
+ "error": {
42
+ "code": -32603,
43
+ "data": {
44
+ "reason": "database unavailable",
45
+ },
46
+ "message": "Revm error: database unavailable",
47
+ },
48
+ "id": 1,
49
+ "jsonrpc": "2.0",
50
+ }
51
+ `)
52
+ })
53
+ })
@@ -127,6 +127,21 @@ export function rpcErrorJson(request: RpcRequest.RpcRequest, error: unknown) {
127
127
  { request },
128
128
  )
129
129
 
130
+ if (
131
+ inner.code === RpcResponse.InternalError.code &&
132
+ /^Revm error: transaction expired(?:\.|: .+)?$/.test(inner.message)
133
+ )
134
+ return RpcResponse.from(
135
+ {
136
+ error: {
137
+ code: RpcResponse.TransactionRejectedError.code,
138
+ data: { code: 'transaction_expired' },
139
+ message: 'Transaction expired.',
140
+ },
141
+ },
142
+ { request },
143
+ )
144
+
130
145
  const { code, data, message } = inner
131
146
  return RpcResponse.from(
132
147
  {
@@ -676,7 +676,10 @@ export declare namespace middleware {
676
676
  }
677
677
 
678
678
  /** MPP payment options used by auth middleware. */
679
- type MppOptions = Omit<NonNullable<Parameters<typeof Mppx.create>[0]>, 'methods'> & {
679
+ type MppOptions = Omit<
680
+ Parameters<typeof Mppx.create<readonly [ReturnType<typeof tempo.session>]>>[0],
681
+ 'methods'
682
+ > & {
680
683
  /** Paid-request quota per access principal. Defaults to 100 per minute. */
681
684
  rateLimit?: RateLimit.Limit | undefined
682
685
  /** Global Tempo Session options passed to the MPP method instantiator. */
@@ -1451,8 +1454,8 @@ export function require<environment extends Environment = Environment>(
1451
1454
  return proceed()
1452
1455
  }
1453
1456
 
1454
- const apiKey = await auth.apiKey?.resolve(c, credential.token)
1455
- if (!apiKey) {
1457
+ const apiKey_resolved = await auth.apiKey?.resolve(c, credential.token)
1458
+ if (!apiKey_resolved) {
1456
1459
  // A bearer session token is indistinguishable from an API key at the
1457
1460
  // header, so a failed key lookup falls through to the session lane
1458
1461
  // before rejecting.
@@ -1470,6 +1473,10 @@ export function require<environment extends Environment = Environment>(
1470
1473
  })
1471
1474
  }
1472
1475
 
1476
+ const scopes = Scope.expandAliases(apiKey_resolved.scopes)
1477
+ const apiKey =
1478
+ scopes === apiKey_resolved.scopes ? apiKey_resolved : { ...apiKey_resolved, scopes }
1479
+
1473
1480
  // Sandbox keys are testnet-only. A sandbox key that explicitly targets
1474
1481
  // mainnet (`?chainId`) is rejected with a clear message rather than
1475
1482
  // steered or downgraded to anonymous, so the caller learns their key does
@@ -1847,7 +1854,8 @@ function getRequestId(c: hono_Context) {
1847
1854
  return typeof variables['requestId'] === 'string' ? variables['requestId'] : undefined
1848
1855
  }
1849
1856
 
1850
- function hasPaymentCredential(c: hono_Context) {
1857
+ /** True when the request carries an `Authorization: Payment` MPP credential. */
1858
+ export function hasPaymentCredential(c: hono_Context) {
1851
1859
  const authorization = c.req.header('authorization')
1852
1860
  if (!authorization) return false
1853
1861
  return !!Credential.extractPaymentScheme(authorization)
@@ -21,8 +21,8 @@ describe('deriveZoneId', () => {
21
21
  test('derives IDs from mainnet and testnet Zone chain schemes', () => {
22
22
  expect([
23
23
  EarnVaults.deriveZoneId(421_700_006),
24
- EarnVaults.deriveZoneId(1_424_310_001),
25
- ]).toStrictEqual([6, 1])
24
+ EarnVaults.deriveZoneId(1_424_310_003),
25
+ ]).toStrictEqual([6, 3])
26
26
  })
27
27
 
28
28
  test('rejects a source chain ID', () => {
@@ -245,7 +245,7 @@ describe('resolveZoneRoutes', () => {
245
245
  zones: [TestEarn.zone],
246
246
  }),
247
247
  ).rejects.toThrowErrorMatchingInlineSnapshot(
248
- `[EarnVaults.InvalidRegistryError: Zone 1424310001 is configured more than once.]`,
248
+ `[EarnVaults.InvalidRegistryError: Zone 1424310003 is configured more than once.]`,
249
249
  )
250
250
  await expect(
251
251
  EarnVaults.resolveZoneRoutes({
@@ -157,7 +157,7 @@ export namespace schema {
157
157
  ),
158
158
  vaultAddress: Schema.Address.check(
159
159
  z.describe('Earn vault contract address.'),
160
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
160
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
161
161
  ),
162
162
  })
163
163
  .check(z.describe('Onchain identity of an Earn vault.'))
@@ -167,7 +167,7 @@ export namespace schema {
167
167
  .strictObject({
168
168
  chainId: Schema.ChainId.check(
169
169
  z.describe('Private Zone chain id.'),
170
- z.meta({ examples: [1424310001] }),
170
+ z.meta({ examples: [421700001] }),
171
171
  ),
172
172
  deploymentBlock: z
173
173
  .number()
@@ -175,11 +175,11 @@ export namespace schema {
175
175
  z.int(),
176
176
  z.nonnegative(),
177
177
  z.describe('Parent-chain block that deployed the Earn router.'),
178
- z.meta({ examples: [31039238] }),
178
+ z.meta({ examples: [35816964] }),
179
179
  ),
180
180
  earnRouter: Schema.Address.check(
181
181
  z.describe('Parent-chain router for this Zone and Earn vault.'),
182
- z.meta({ examples: ['0x9144086a79dea966d8bf1b52125ebed8919fc45c'] }),
182
+ z.meta({ examples: ['0x8117e0ba6239b9695f780deb010f72a2fa4bdfb6'] }),
183
183
  ),
184
184
  })
185
185
  .check(z.describe('Curated Earn route through one private Zone.'))
@@ -239,7 +239,7 @@ export namespace schema {
239
239
  state,
240
240
  vaultAddress: Schema.Address.check(
241
241
  z.describe('Earn vault contract address.'),
242
- z.meta({ examples: ['0xf4ae63687d6753a78e7f551d2eda1d0d31a5ea3a'] }),
242
+ z.meta({ examples: ['0x4f94590b636f5878bce585e82379de81e1ec174f'] }),
243
243
  ),
244
244
  })
245
245
  .check(z.describe('Live state resolved from an Earn vault.'))
@@ -0,0 +1,46 @@
1
+ import * as http from 'node:http'
2
+
3
+ import * as Fetch from './Fetch.js'
4
+
5
+ describe('withTimeout', () => {
6
+ test('aborts a fetch after the configured duration', async () => {
7
+ const server = http.createServer(() => {})
8
+ const url = await listen(server)
9
+
10
+ try {
11
+ const fetch = Fetch.withTimeout(globalThis.fetch, { timeout: 10 })
12
+ await expect(fetch(url)).rejects.toMatchObject({ name: 'TimeoutError' })
13
+ } finally {
14
+ server.closeAllConnections()
15
+ await close(server)
16
+ }
17
+ })
18
+ })
19
+
20
+ describe('resolveSignal', () => {
21
+ test('preserves caller and Request signals', () => {
22
+ const signal = AbortSignal.timeout(1_000)
23
+ const request = new Request('https://api.tempo.xyz', { signal })
24
+
25
+ expect(Fetch.resolveSignal('https://api.tempo.xyz', { init: { signal }, timeout: 10 })).toBe(
26
+ signal,
27
+ )
28
+ expect(Fetch.resolveSignal(request, { timeout: 10 })).toBe(request.signal)
29
+ })
30
+ })
31
+
32
+ function close(server: http.Server): Promise<void> {
33
+ return new Promise((resolve, reject) => {
34
+ server.close((error) => (error ? reject(error) : resolve()))
35
+ })
36
+ }
37
+
38
+ function listen(server: http.Server): Promise<string> {
39
+ return new Promise((resolve) => {
40
+ server.listen(0, '127.0.0.1', () => {
41
+ const address = server.address()
42
+ if (!address || typeof address === 'string') throw new Error('Expected a TCP server address.')
43
+ resolve(`http://127.0.0.1:${address.port}`)
44
+ })
45
+ })
46
+ }
@@ -0,0 +1,56 @@
1
+ import * as Timeout from './Timeout.js'
2
+
3
+ /** Installs the default outbound fetch timeout once for this runtime. */
4
+ export function install(): void {
5
+ if (isInstalled(globalThis.fetch)) return
6
+
7
+ const fetch = withTimeout(globalThis.fetch.bind(globalThis), { timeout: Timeout.duration })
8
+ Object.defineProperty(fetch, timeoutMarker, { value: true })
9
+ globalThis.fetch = fetch
10
+ }
11
+
12
+ /** Adds a default maximum duration to fetch calls that do not carry a signal. */
13
+ export function withTimeout(
14
+ fetch: typeof globalThis.fetch,
15
+ options: withTimeout.Options,
16
+ ): typeof globalThis.fetch {
17
+ return ((input, init) => {
18
+ const signal = resolveSignal(input, { init, timeout: options.timeout })
19
+ return fetch(input, { ...init, signal })
20
+ }) as typeof globalThis.fetch
21
+ }
22
+
23
+ /** Resolves a caller signal or creates the default fetch deadline signal. */
24
+ export function resolveSignal(
25
+ input: Parameters<typeof globalThis.fetch>[0],
26
+ options: resolveSignal.Options,
27
+ ): AbortSignal {
28
+ return (
29
+ options.init?.signal ??
30
+ (input instanceof Request ? input.signal : Timeout.signal({ timeout: options.timeout }))
31
+ )
32
+ }
33
+
34
+ export declare namespace resolveSignal {
35
+ /** Options for {@link resolveSignal}. */
36
+ type Options = {
37
+ /** Optional fetch initialization carrying a caller signal. */
38
+ init?: Parameters<typeof globalThis.fetch>[1]
39
+ /** Default maximum duration in milliseconds. */
40
+ timeout: number
41
+ }
42
+ }
43
+
44
+ export declare namespace withTimeout {
45
+ /** Options for {@link withTimeout}. */
46
+ type Options = {
47
+ /** Maximum fetch duration in milliseconds. */
48
+ timeout: number
49
+ }
50
+ }
51
+
52
+ const timeoutMarker = Symbol.for('tempo.api.fetch.timeout')
53
+
54
+ function isInstalled(fetch: typeof globalThis.fetch): boolean {
55
+ return timeoutMarker in fetch
56
+ }
@@ -29,6 +29,8 @@ test('bounds sponsorship diagnostics', () => {
29
29
  'fee_token_unsupported',
30
30
  'internal_error',
31
31
  'production_api_key_required',
32
+ 'project_id_invalid',
33
+ 'project_id_required',
32
34
  'spend_limit_exceeded',
33
35
  'tx_fee_limit_exceeded',
34
36
  ] as const satisfies readonly Log.SponsorshipReason[]
@@ -457,6 +457,27 @@ describe('middleware', () => {
457
457
  `)
458
458
  })
459
459
 
460
+ test('preserves the request error and unfinished stages', async () => {
461
+ const entries: Log.Entry[] = []
462
+ const causes: Error[] = []
463
+ const api = app({
464
+ emit: (entry, cause) => {
465
+ entries.push(entry)
466
+ if (cause) causes.push(cause)
467
+ },
468
+ })
469
+ const cause = new Error('Memoized cache-miss flight timed out after 15000ms.')
470
+ api.get('/activities', (c) => {
471
+ void Timing.time(c, 'transaction_activity_mpp', () => new Promise(() => {}))
472
+ return Response.upstream(c, cause)
473
+ })
474
+
475
+ await api.request('/activities')
476
+
477
+ expect(causes[0]).toBe(cause)
478
+ expect(entries[0]?.pendingTimings?.['transaction_activity_mpp']).toBeGreaterThanOrEqual(0)
479
+ })
480
+
460
481
  test('includes bounded funding provider attempts', async () => {
461
482
  const entries: Log.Entry[] = []
462
483
  const api = app({ emit: (entry) => void entries.push(entry) })
@@ -104,6 +104,8 @@ export type SponsorshipReason =
104
104
  | 'fee_token_unsupported'
105
105
  | 'internal_error'
106
106
  | 'production_api_key_required'
107
+ | 'project_id_invalid'
108
+ | 'project_id_required'
107
109
  | 'spend_limit_exceeded'
108
110
  | 'tx_fee_limit_exceeded'
109
111
 
@@ -151,6 +153,8 @@ export type Entry = {
151
153
  path: string
152
154
  /** MPP payment reason when the request was paid per call. */
153
155
  payment?: Auth.Payment['reason'] | undefined
156
+ /** Operations still running when the response completed, with elapsed milliseconds. */
157
+ pendingTimings?: Record<string, number> | undefined
154
158
  /** Bounded outcome for an MPP relay operation. */
155
159
  mpp?: {
156
160
  /** Resolved Tempo chain selected by the credential. */
@@ -228,7 +232,7 @@ export type Entry = {
228
232
  }
229
233
 
230
234
  /** Sink receiving one {@link Entry} per request. */
231
- export type Emit = (entry: Entry) => Promise<void> | void
235
+ export type Emit = (entry: Entry, cause?: Error) => Promise<void> | void
232
236
 
233
237
  /**
234
238
  * Emits one canonical structured log entry per request, after the response is
@@ -258,7 +262,8 @@ export function middleware<environment extends Environment = Environment>(
258
262
  // Hono cannot resolve variable types through the generic `environment`,
259
263
  // so shared-variable reads are cast from the environment contract above
260
264
  // (the same pattern EdgeCache uses for its cross-layer reads).
261
- const error = c.error as ErrorMetadata | undefined
265
+ const cause = c.error
266
+ const error = cause as (Error & ErrorMetadata) | undefined
262
267
  const principal = c.get('principal' as never) as Auth.Principal | undefined
263
268
  const errorCaptured = c.get('errorCaptured' as never) as boolean | undefined
264
269
  const chainId = c.get('chainId' as never) as number | undefined
@@ -279,7 +284,6 @@ export function middleware<environment extends Environment = Environment>(
279
284
  error?.providerFailures ?? (c.get('providerFailures' as never) as Entry['providerFailures'])
280
285
  const rpc = c.get('rpcResponse' as never) as Entry['rpc']
281
286
  const sponsorship = c.get('sponsorship' as never) as Entry['sponsorship']
282
-
283
287
  // The `request` total metric duplicates `duration` (measured here, one
284
288
  // layer further out), so only operation timings are kept.
285
289
  const metrics = (c.get('serverTiming' as never) as Timing.Metric[] | undefined)?.filter(
@@ -295,6 +299,17 @@ export function middleware<environment extends Environment = Environment>(
295
299
  }, new Map<string, number>()),
296
300
  )
297
301
  : undefined
302
+ const activeTimings = c.get('activeTimings' as never) as Timing.Active[] | undefined
303
+ const pendingTimings = activeTimings?.length
304
+ ? Object.fromEntries(
305
+ activeTimings.reduce((result, timing) => {
306
+ const duration = round(performance.now() - timing.start)
307
+ const existing = result.get(timing.name)
308
+ if (existing === undefined || duration > existing) result.set(timing.name, duration)
309
+ return result
310
+ }, new Map<string, number>()),
311
+ )
312
+ : undefined
298
313
 
299
314
  const rateLimit = (() => {
300
315
  const limit = c.res.headers.get('RateLimit-Limit')
@@ -310,7 +325,7 @@ export function middleware<environment extends Environment = Environment>(
310
325
  }
311
326
  })()
312
327
 
313
- const result = fn({
328
+ const entry = {
314
329
  ...(c.get('edgeCacheStatus' as never) === 'hit' ? { cache: 'hit' as const } : {}),
315
330
  ...(chainId === undefined ? {} : { chainId }),
316
331
  duration: round(duration),
@@ -333,6 +348,7 @@ export function middleware<environment extends Environment = Environment>(
333
348
  ...(mpp === undefined ? {} : { mpp }),
334
349
  path: url.pathname,
335
350
  ...(principal?.payment === undefined ? {} : { payment: principal.payment.reason }),
351
+ ...(pendingTimings === undefined ? {} : { pendingTimings }),
336
352
  ...(principal === undefined
337
353
  ? {}
338
354
  : {
@@ -360,7 +376,8 @@ export function middleware<environment extends Environment = Environment>(
360
376
  ...(sponsorship === undefined ? {} : { sponsorship }),
361
377
  status,
362
378
  ...(timings === undefined ? {} : { timings }),
363
- })
379
+ } satisfies Entry
380
+ const result = fn(entry, cause)
364
381
 
365
382
  if (result instanceof Promise) {
366
383
  const promise = result.catch((error) => console.error('request log sink failed', error))
@@ -148,6 +148,7 @@ export const errorCodes = {
148
148
  500: ['internal_error'],
149
149
  501: ['billing_unconfigured'],
150
150
  502: ['upstream_error'],
151
+ 504: ['request_timeout'],
151
152
  } as const satisfies Record<number, readonly [string, ...string[]]>
152
153
 
153
154
  /**
@@ -220,6 +221,7 @@ const standardErrorNames = {
220
221
  500: 'InternalError',
221
222
  501: 'NotImplementedError',
222
223
  502: 'UpstreamError',
224
+ 504: 'RequestTimeoutError',
223
225
  } as const satisfies Record<keyof typeof errorCodes, string>
224
226
 
225
227
  const reservedErrorNames = new Set<string>(Object.values(standardErrorNames))
@@ -300,12 +302,12 @@ export const paymentChallenge = {
300
302
  headers: { 'WWW-Authenticate': headerRef('WwwAuthenticate') },
301
303
  } as const
302
304
 
303
- type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited'
305
+ type ResponseComponentName = 'InternalError' | 'PaymentRequired' | 'RateLimited' | 'RequestTimeout'
304
306
 
305
307
  /**
306
308
  * Reusable responses registered under `components.responses` (see `App.create`)
307
- * and `$ref`-erenced from operations, so the uniform `402`/`429`/`500` responses
308
- * are defined once instead of inlined on every operation.
309
+ * and `$ref`-erenced from operations, so the uniform `402`/`429`/`500`/`504`
310
+ * responses are defined once instead of inlined on every operation.
309
311
  */
310
312
  export function responseComponents(): ResponsesWithResolver {
311
313
  return {
@@ -320,6 +322,11 @@ export function responseComponents(): ResponsesWithResolver {
320
322
  'Rate limit exceeded. On endpoints that accept MPP, over-quota unpaid requests return `402 Payment Required` instead.',
321
323
  headers: { ...rateLimitHeaders },
322
324
  },
325
+ RequestTimeout: {
326
+ content: errorContent(504, errorCodes[504], 'Request timed out'),
327
+ description:
328
+ 'Request timed out. The request did not complete within the 60-second deadline; retry it.',
329
+ },
323
330
  }
324
331
  }
325
332
 
@@ -344,6 +351,7 @@ export function standardError(
344
351
  ): ResponsesWithResolver[string] {
345
352
  if (status === 429) return responseRef('RateLimited')
346
353
  if (status === 500) return responseRef('InternalError')
354
+ if (status === 504) return responseRef('RequestTimeout')
347
355
  return { content: errorContent(status, mergeErrorCodes(status, codes), description), description }
348
356
  }
349
357
 
@@ -352,7 +360,8 @@ export function standardError(
352
360
  * pre-filled, plus the success response (with rate-limit headers):
353
361
  *
354
362
  * - `400` invalid request, `401` missing/invalid key, `403` forbidden, `429`
355
- * rate limited, `500` internal error, and `502` upstream failure on every operation;
363
+ * rate limited, `500` internal error, `502` upstream failure, and `504`
364
+ * request timeout on every operation;
356
365
  * - `404`/`409`/`412`/`413`/`415` only when an `errors` entry is set.
357
366
  *
358
367
  * `error.code` is enumerated per status from {@link errorCodes}. Operation-level
@@ -404,6 +413,7 @@ export function responses<schema extends z.ZodMiniType>(
404
413
  500: responseRef('InternalError'),
405
414
  ...(errors?.[501] && { 501: error(501, 'Not implemented.') }),
406
415
  502: error(502, 'Upstream data failure.'),
416
+ 504: responseRef('RequestTimeout'),
407
417
  }
408
418
  }
409
419
 
@@ -142,7 +142,7 @@ export declare namespace error {
142
142
  }
143
143
 
144
144
  /** HTTP status code accepted by the public error helper. */
145
- type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503
145
+ type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503 | 504
146
146
 
147
147
  /** Options for creating a JSON error response. */
148
148
  type Options<status extends Status = Status, code extends string = string> = {
@@ -6,6 +6,8 @@ describe('ChainId', () => {
6
6
  test('resolves aliases to their chain id', () => {
7
7
  expect(Schema.ChainId.parse('mainnet')).toMatchInlineSnapshot(`4217`)
8
8
  expect(Schema.ChainId.parse('testnet')).toMatchInlineSnapshot(`42431`)
9
+ expect(Schema.ChainId.parse('1424310001')).toMatchInlineSnapshot(`1424310003`)
10
+ expect(Schema.ChainId.parse(1_424_310_001)).toMatchInlineSnapshot(`1424310003`)
9
11
  })
10
12
 
11
13
  test('accepts numeric chain ids as numbers or strings', () => {
@@ -90,12 +90,19 @@ export function tokenAddress(example: core_Hex.Hex) {
90
90
  )
91
91
  }
92
92
 
93
- /** Maps human-readable chain aliases to their Tempo chain id. */
93
+ /** Maps caller-facing chain aliases to their current Tempo chain id. */
94
94
  export const chainIdAlias = {
95
+ // TODO: Remove this alias after clients migrate to chain 1424310003.
96
+ 1_424_310_001: 1_424_310_003,
95
97
  mainnet: 4217,
96
98
  testnet: 42431,
97
99
  } as const
98
100
 
101
+ /** Resolves a numeric chain id through the caller-facing alias map. */
102
+ export function resolveChainId(chainId: number): number {
103
+ return chainIdAlias[chainId as keyof typeof chainIdAlias] ?? chainId
104
+ }
105
+
99
106
  /**
100
107
  * Tempo chain id. Accepts a chain alias (`mainnet`/`testnet`) or any positive
101
108
  * integer chain id (a number or numeric string), normalizing all forms to a
@@ -110,7 +117,10 @@ export const ChainId = z
110
117
  z.enum(['mainnet', 'testnet']),
111
118
  z.transform((alias) => chainIdAlias[alias]),
112
119
  ),
113
- z.coerce.number(),
120
+ z.pipe(
121
+ z.coerce.number(),
122
+ z.transform((chainId) => resolveChainId(chainId)),
123
+ ),
114
124
  ]),
115
125
  z.number().check(z.int(), z.positive()),
116
126
  )