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
@@ -11,11 +11,13 @@ import * as Cache from '../../../internal/Cache.js'
11
11
  import * as FundingCatalog from '../../../internal/funding/Catalog.js'
12
12
  import * as FundingProvider from '../../../internal/funding/Provider.js'
13
13
  import * as FundingTransfer from '../../../internal/funding/Transfer.js'
14
+ import * as FundingTransferReconciliation from '../../../internal/funding/TransferReconciliation.js'
14
15
  import * as Idempotency from '../../../internal/Idempotency.js'
15
16
  import * as OpenApi from '../../../internal/OpenApi.js'
16
17
  import * as Response from '../../../internal/Response.js'
17
18
  import * as Schema from '../../../internal/Schema.js'
18
19
  import * as Value from '../../../internal/Value.js'
20
+ import type * as Webhooks from '../../../internal/Webhooks.js'
19
21
  import * as Access from '../Access.js'
20
22
  import * as ProviderAttempts from '../ProviderAttempts.js'
21
23
 
@@ -36,15 +38,20 @@ export namespace schema {
36
38
  .check(z.describe('Query parameters for listing funding transfers.'))
37
39
 
38
40
  /** Paginated funding transfer list. */
39
- export const Response = z
40
- .object({
41
- data: z.array(Transfer).check(z.describe('Funding transfers on this page, newest first.')),
42
- meta: z
43
- .optional(Schema.CountMeta)
44
- .check(z.describe('Extra response metadata requested with `include`.')),
45
- nextCursor: Schema.NextCursor,
46
- })
47
- .check(z.describe('A page of funding transfers.'))
41
+ export const Response = OpenApi.component(
42
+ z
43
+ .object({
44
+ data: z
45
+ .array(Transfer)
46
+ .check(z.describe('Funding transfers on this page, newest first.')),
47
+ meta: z
48
+ .optional(Schema.CountMeta)
49
+ .check(z.describe('Extra response metadata requested with `include`.')),
50
+ nextCursor: Schema.NextCursor,
51
+ })
52
+ .check(z.describe('A page of funding transfers.')),
53
+ 'FundingTransferList',
54
+ )
48
55
  }
49
56
 
50
57
  /** Schemas for the createFundingTransfer operation. */
@@ -82,18 +89,21 @@ export namespace schema {
82
89
  /** Schemas for the createFundingTransferVault operation. */
83
90
  export namespace createFundingTransferVault {
84
91
  /** Funding transfer creation request for an Earn vault destination. */
85
- export const Body = z
86
- .strictObject({
87
- ...destinationCreateFields,
88
- vaultAddress: z
89
- .string()
90
- .check(
91
- z.regex(/^0x[0-9a-fA-F]{40}$/),
92
- z.describe('Tempo Earn vault contract address.'),
93
- z.meta({ examples: [`0x${'f4'.repeat(20)}`] }),
94
- ),
95
- })
96
- .check(z.describe('Vault funding transfer creation request.'))
92
+ export const Body = OpenApi.component(
93
+ z
94
+ .strictObject({
95
+ ...destinationCreateFields,
96
+ vaultAddress: z
97
+ .string()
98
+ .check(
99
+ z.regex(/^0x[0-9a-fA-F]{40}$/),
100
+ z.describe('Tempo Earn vault contract address.'),
101
+ z.meta({ examples: [`0x${'f4'.repeat(20)}`] }),
102
+ ),
103
+ })
104
+ .check(z.describe('Vault funding transfer creation request.')),
105
+ 'CreateFundingTransferVaultRequest',
106
+ )
97
107
 
98
108
  /** Required headers for vault funding transfer creation. */
99
109
  export const Headers = createFundingTransfer.Headers
@@ -102,32 +112,35 @@ export namespace schema {
102
112
  /** Schemas for the createFundingTransferZone operation. */
103
113
  export namespace createFundingTransferZone {
104
114
  /** Funding transfer creation request for a Zone destination. */
105
- export const Body = z
106
- .strictObject({
107
- amount: destinationCreateFields.amount,
108
- destinationChain: z
109
- .string()
110
- .check(
111
- z.regex(/^eip155:\d+$/),
112
- z.describe('Configured Zone CAIP-2 id.'),
113
- z.meta({ examples: ['eip155:1424310001'] }),
114
- ),
115
- destinationToken: FundingTransfer.schema.CreateRequest.shape.destinationToken,
116
- mode: destinationCreateFields.mode,
117
- recipient: destinationCreateFields.recipient,
118
- recipientFallback: z
119
- .string()
120
- .check(
121
- z.regex(/^0x[0-9a-fA-F]{40}$/),
122
- z.describe('Public Tempo recipient used if the Zone credit cannot complete.'),
123
- z.meta({ examples: [`0x${'22'.repeat(20)}`] }),
124
- ),
125
- sender: destinationCreateFields.sender,
126
- slippageBps: destinationCreateFields.slippageBps,
127
- sourceChain: destinationCreateFields.sourceChain,
128
- sourceToken: destinationCreateFields.sourceToken,
129
- })
130
- .check(z.describe('Zone funding transfer creation request.'))
115
+ export const Body = OpenApi.component(
116
+ z
117
+ .strictObject({
118
+ amount: destinationCreateFields.amount,
119
+ destinationChain: z
120
+ .string()
121
+ .check(
122
+ z.regex(/^eip155:\d+$/),
123
+ z.describe('Configured Zone CAIP-2 id.'),
124
+ z.meta({ examples: ['eip155:1424310003'] }),
125
+ ),
126
+ destinationToken: FundingTransfer.schema.CreateRequest.shape.destinationToken,
127
+ mode: destinationCreateFields.mode,
128
+ recipient: destinationCreateFields.recipient,
129
+ recipientFallback: z
130
+ .string()
131
+ .check(
132
+ z.regex(/^0x[0-9a-fA-F]{40}$/),
133
+ z.describe('Public Tempo recipient used if the Zone credit cannot complete.'),
134
+ z.meta({ examples: [`0x${'22'.repeat(20)}`] }),
135
+ ),
136
+ sender: destinationCreateFields.sender,
137
+ slippageBps: destinationCreateFields.slippageBps,
138
+ sourceChain: destinationCreateFields.sourceChain,
139
+ sourceToken: destinationCreateFields.sourceToken,
140
+ })
141
+ .check(z.describe('Zone funding transfer creation request.')),
142
+ 'CreateFundingTransferZoneRequest',
143
+ )
131
144
 
132
145
  /** Required headers for Zone funding transfer creation. */
133
146
  export const Headers = createFundingTransfer.Headers
@@ -150,6 +163,25 @@ export namespace schema {
150
163
  /** The funding transfer resource, returned directly. */
151
164
  export const Response = Transfer
152
165
  }
166
+
167
+ /** Schemas for the registerFundingTransferSourceTransaction operation. */
168
+ export namespace registerFundingTransferSourceTransaction {
169
+ /** Source transaction registration request body. */
170
+ export const Body = OpenApi.component(
171
+ z
172
+ .strictObject({
173
+ transactionHash: Schema.hash(`0x${'51'.repeat(32)}`),
174
+ })
175
+ .check(z.describe('Verified source transaction to associate with the transfer.')),
176
+ 'RegisterFundingTransferSourceTransactionRequest',
177
+ )
178
+
179
+ /** Path parameters for source transaction registration. */
180
+ export const Params = getFundingTransfer.Params
181
+
182
+ /** The transfer after source transaction registration. */
183
+ export const Response = Transfer
184
+ }
153
185
  }
154
186
 
155
187
  const baseChainExample = {
@@ -216,6 +248,14 @@ const fundingTransferExample = {
216
248
  version: 1,
217
249
  } satisfies z.output<typeof schema.Transfer>
218
250
 
251
+ const registeredFundingTransferExample = {
252
+ ...fundingTransferExample,
253
+ sourceTransactionHashes: [`0x${'51'.repeat(32)}`],
254
+ status: 'processing',
255
+ updatedAt: '2026-01-01T00:00:20.000Z',
256
+ version: 2,
257
+ } satisfies z.output<typeof schema.registerFundingTransferSourceTransaction.Response>
258
+
219
259
  const listFundingTransfersResponseExample = {
220
260
  data: [fundingTransferExample],
221
261
  nextCursor: null,
@@ -265,9 +305,17 @@ const idempotencyReplayTtlMs = 86_400_000
265
305
  // Pending claims only cover the bounded provider preparation window.
266
306
  const idempotencyPendingTtlMs = 60_000
267
307
  const fundingEtag = etag()
308
+ const bodyValidation = {
309
+ code: 'body_invalid',
310
+ message: 'Check the request body and try again.',
311
+ } as const
312
+ const paramValidation = {
313
+ code: 'param_invalid',
314
+ message: 'Check the path parameters and try again.',
315
+ } as const
268
316
 
269
317
  /** Mounts durable funding transfer routes. */
270
- export function transfers() {
318
+ export function transfers(options: transfers.Options = {}) {
271
319
  return new Hono<App.Environment>()
272
320
  .get(
273
321
  '/v1/funding/transfers',
@@ -411,6 +459,209 @@ export function transfers() {
411
459
  }
412
460
  },
413
461
  )
462
+ .post(
463
+ '/v1/funding/transfers/:id{ftr_[A-Za-z0-9_-]+}/source-transactions',
464
+ Auth.policy({ apiKey: { scopes: ['funding:write'] } }),
465
+ OpenApi.validate(
466
+ 'param',
467
+ schema.registerFundingTransferSourceTransaction.Params,
468
+ paramValidation,
469
+ ),
470
+ OpenApi.validate(
471
+ 'json',
472
+ schema.registerFundingTransferSourceTransaction.Body,
473
+ bodyValidation,
474
+ ),
475
+ OpenApi.describeRoute({
476
+ description: 'Registers and verifies a funding source transaction.',
477
+ operationId: 'registerFundingTransferSourceTransaction',
478
+ responses: OpenApi.responses({
479
+ errors: {
480
+ 400: {
481
+ codes: ['body_invalid', 'param_invalid', 'source_transaction_invalid'],
482
+ description: 'The path, body, or submitted source transaction is invalid.',
483
+ },
484
+ 404: {
485
+ codes: ['funding_transfer_not_found'],
486
+ description: 'No visible funding transfer exists for the identifier.',
487
+ },
488
+ 409: {
489
+ codes: [
490
+ 'funding_transfer_not_awaiting_source',
491
+ 'source_transaction_conflict',
492
+ 'source_transaction_pending',
493
+ ],
494
+ description: 'The transfer or source transaction cannot be registered yet.',
495
+ },
496
+ 501: {
497
+ codes: ['not_implemented'],
498
+ description: 'Source transaction reconciliation is not configured.',
499
+ },
500
+ 502: {
501
+ codes: ['upstream_error'],
502
+ description: 'Source verification or reconciliation dispatch failed.',
503
+ },
504
+ },
505
+ success: {
506
+ description: 'The transfer with its verified source transaction.',
507
+ example: registeredFundingTransferExample,
508
+ schema: schema.registerFundingTransferSourceTransaction.Response,
509
+ },
510
+ }),
511
+ summary: 'Register source transaction',
512
+ tags: ['Funding Transfers'],
513
+ }),
514
+ async (c) => {
515
+ if (Auth.narrowAccess) return Auth.accessError(c)
516
+ if (OpenApi.narrowValidation) return OpenApi.validationError(c, paramValidation)
517
+ if (OpenApi.narrowValidation) return OpenApi.validationError(c, bodyValidation)
518
+
519
+ const owner = Access.owner(c)
520
+ if (!owner) return Access.unauthorized(c)
521
+ c.header('Cache-Control', Cache.policies.noStore)
522
+ c.header('Vary', 'Accept-Encoding, Authorization, Tempo-API-Key, X-API-Key')
523
+
524
+ const dispatch = options.dispatchTransferReconciliation
525
+ if (!dispatch)
526
+ return Response.error(c, {
527
+ code: 'not_implemented',
528
+ message: 'Source transaction reconciliation is not configured',
529
+ status: 501,
530
+ })
531
+
532
+ const db = Db.get(c.get('db'))
533
+ const { id } = c.req.valid('param')
534
+ const { transactionHash } = c.req.valid('json')
535
+ try {
536
+ const record = await FundingTransfers.getOwned(db, owner, id)
537
+ if (!record)
538
+ return Response.error(c, {
539
+ code: 'funding_transfer_not_found',
540
+ message: 'Funding transfer not found',
541
+ status: 404,
542
+ })
543
+ if (
544
+ record.snapshot.sourceTransactionHashes?.some(
545
+ (candidate) => candidate.toLowerCase() === transactionHash,
546
+ )
547
+ ) {
548
+ if (record.status === 'processing')
549
+ await dispatch({ transferId: record.id, type: 'funding:transfer:reconcile' })
550
+ return c.json(
551
+ Response.validated(
552
+ schema.registerFundingTransferSourceTransaction.Response,
553
+ FundingTransfer.toPublic(record),
554
+ ),
555
+ 200,
556
+ )
557
+ }
558
+ const provider = c
559
+ .get('providers')
560
+ .filter(FundingProvider.is)
561
+ .find((candidate) => candidate.id === record.providerId)
562
+ if (!provider || !FundingProvider.canVerifySourceTransaction(provider))
563
+ return Response.error(c, {
564
+ code: 'funding_transfer_not_awaiting_source',
565
+ message: 'Funding transfer does not accept source transactions',
566
+ status: 409,
567
+ })
568
+ if (record.status !== 'awaiting-source')
569
+ return Response.error(c, {
570
+ code: 'funding_transfer_not_awaiting_source',
571
+ message: 'Funding transfer is not awaiting a source transaction',
572
+ status: 409,
573
+ })
574
+
575
+ const catalog = await FundingCatalog.snapshot(c)
576
+ const destinationChain = catalog.chainsByKey.get(record.snapshot.destinationChain.id)
577
+ const sourceChain = catalog.chainsByKey.get(record.snapshot.sourceChain.id)
578
+ const routeConfiguration = catalog.routesByProvider
579
+ .get(record.providerId)
580
+ ?.find(
581
+ (candidate) =>
582
+ candidate.route.source.chain.id === record.snapshot.sourceChain.id &&
583
+ candidate.route.source.address.toLowerCase() ===
584
+ record.snapshot.sourceToken.address.toLowerCase() &&
585
+ candidate.route.destination.chain.id === record.snapshot.destinationChain.id &&
586
+ candidate.route.destination.address.toLowerCase() ===
587
+ record.snapshot.destinationToken.address.toLowerCase(),
588
+ )?.configuration
589
+ if (!destinationChain || !sourceChain)
590
+ return Response.error(c, {
591
+ code: 'funding_transfer_not_awaiting_source',
592
+ message: 'Funding transfer route chains are no longer configured',
593
+ status: 409,
594
+ })
595
+
596
+ const evidence = await provider.verifySourceTransaction(
597
+ {
598
+ destinationChain,
599
+ providerState: record.providerState ?? undefined,
600
+ routeConfiguration,
601
+ sourceChain,
602
+ transactionHash,
603
+ transfer: record.snapshot,
604
+ },
605
+ c.req.raw.signal,
606
+ )
607
+ if (evidence.type === 'pending')
608
+ return Response.error(c, {
609
+ code: 'source_transaction_pending',
610
+ message: 'Source transaction is not confirmed yet',
611
+ status: 409,
612
+ })
613
+ if (evidence.type === 'invalid')
614
+ return Response.error(c, {
615
+ code: 'source_transaction_invalid',
616
+ message: 'Source transaction does not match the funding transfer',
617
+ status: 400,
618
+ })
619
+
620
+ const registered = await FundingTransfer.registerSourceTransaction(db, {
621
+ chainId: record.snapshot.sourceChain.id,
622
+ id: record.id,
623
+ providerState: evidence.providerState ?? {},
624
+ transactionHash,
625
+ })
626
+ if (registered.type === 'not_found')
627
+ return Response.error(c, {
628
+ code: 'funding_transfer_not_found',
629
+ message: 'Funding transfer not found',
630
+ status: 404,
631
+ })
632
+ if (registered.type === 'conflict')
633
+ return Response.error(c, {
634
+ code: 'source_transaction_conflict',
635
+ message: 'Source transaction is already assigned to another funding transfer',
636
+ status: 409,
637
+ })
638
+ if (registered.type === 'invalid')
639
+ return Response.error(c, {
640
+ code: 'funding_transfer_not_awaiting_source',
641
+ message: 'Funding transfer is not awaiting a source transaction',
642
+ status: 409,
643
+ })
644
+
645
+ await Promise.all([
646
+ dispatch({ transferId: record.id, type: 'funding:transfer:reconcile' }),
647
+ registered.type === 'registered' &&
648
+ options.dispatchTransferUpdates &&
649
+ registered.references.length > 0
650
+ ? options.dispatchTransferUpdates(registered.references)
651
+ : undefined,
652
+ ])
653
+ return c.json(
654
+ Response.validated(
655
+ schema.registerFundingTransferSourceTransaction.Response,
656
+ FundingTransfer.toPublic(registered.record),
657
+ ),
658
+ 200,
659
+ )
660
+ } catch (cause) {
661
+ return Response.upstream(c, cause)
662
+ }
663
+ },
664
+ )
414
665
  .post(
415
666
  '/v1/funding/transfers',
416
667
  Auth.policy({ apiKey: { scopes: ['funding:write'] } }),
@@ -516,6 +767,7 @@ export function transfers() {
516
767
  method: 'transaction',
517
768
  mode: body.mode,
518
769
  onAttempt: (attempt) => attempts.push(attempt),
770
+ provider: body.provider,
519
771
  providers,
520
772
  recipient: body.recipient,
521
773
  sender: body.sender,
@@ -532,8 +784,6 @@ export function transfers() {
532
784
  }
533
785
 
534
786
  const { candidate, result } = selected
535
- const feeToken = (side: 'destination' | 'source') =>
536
- side === 'source' ? candidate.sourceToken : candidate.destinationToken
537
787
  const snapshot: FundingTransfer.Snapshot = {
538
788
  destinationAmount: Value.tokenAmount({
539
789
  baseUnits: result.destinationAmount,
@@ -547,16 +797,21 @@ export function transfers() {
547
797
  }),
548
798
  destinationChain: candidate.destinationChain,
549
799
  destinationToken: candidate.destinationToken,
550
- fees: result.fees.map((fee) => ({
551
- amount: Value.tokenAmount({
552
- baseUnits: fee.amount,
553
- currency: feeToken(fee.side).currency,
554
- decimals: feeToken(fee.side).decimals,
555
- }),
556
- side: fee.side,
557
- token: feeToken(fee.side),
558
- type: 'provider',
559
- })),
800
+ fees: result.fees.map((fee) => {
801
+ const token =
802
+ fee.token ??
803
+ (fee.side === 'source' ? candidate.sourceToken : candidate.destinationToken)
804
+ return {
805
+ amount: Value.tokenAmount({
806
+ baseUnits: fee.amount,
807
+ currency: token.currency,
808
+ decimals: token.decimals,
809
+ }),
810
+ side: fee.side,
811
+ token,
812
+ type: 'provider',
813
+ }
814
+ }),
560
815
  method: 'transaction',
561
816
  mode: body.mode,
562
817
  provider: candidate.provider,
@@ -575,12 +830,18 @@ export function transfers() {
575
830
  // The transfer row, its version-1 event, and the replay body commit
576
831
  // atomically so a crash cannot leave a claimed key without a replay.
577
832
  const created = await db.transaction(async (tx) => {
578
- const record = await FundingTransfer.createIn(tx, {
833
+ const { record, references } = await FundingTransfer.createIn(tx, {
579
834
  apiKeyId: principal.id,
580
835
  environment: owner.environment,
581
836
  orgId: owner.orgId,
582
837
  projectId: owner.projectId,
583
- providerState: result.correlation,
838
+ providerState:
839
+ result.correlation || result.providerState
840
+ ? {
841
+ ...result.correlation,
842
+ ...result.providerState,
843
+ }
844
+ : undefined,
584
845
  snapshot,
585
846
  })
586
847
  const validated = Response.validated(
@@ -597,13 +858,21 @@ export function transfers() {
597
858
  })
598
859
  if (!completion)
599
860
  throw new IdempotencyLeaseLostError('Funding transfer creation lease was lost.')
600
- return validated
861
+ return { references, response: validated }
601
862
  })
602
- return c.json(created, 200)
863
+ if (options.dispatchTransferUpdates && created.references.length > 0)
864
+ try {
865
+ await options.dispatchTransferUpdates(created.references)
866
+ } catch (cause) {
867
+ return Response.upstream(c, cause)
868
+ }
869
+ return c.json(created.response, 200)
603
870
  } catch (cause) {
604
871
  await release()
605
872
  if (cause instanceof FundingProvider.InvalidAmountError)
606
873
  return Response.error(c, { code: 'body_invalid', message: 'Invalid `amount`.', status: 400 }) // prettier-ignore
874
+ if (cause instanceof FundingProvider.UnsupportedProviderError)
875
+ return Response.error(c, { code: 'body_invalid', message: 'Unsupported `provider`.', status: 400 }) // prettier-ignore
607
876
  if (cause instanceof FundingProvider.UnsupportedSourceChainError)
608
877
  return quoteNotAvailable(c)
609
878
  if (cause instanceof FundingProvider.ProviderQuoteError) {
@@ -691,6 +960,20 @@ export function transfers() {
691
960
  )
692
961
  }
693
962
 
963
+ export declare namespace transfers {
964
+ /** Funding transfer route dependencies. */
965
+ type Options = {
966
+ /** Enqueues one registered transfer for destination reconciliation. */
967
+ dispatchTransferReconciliation?:
968
+ | ((message: FundingTransferReconciliation.Message) => Promise<void>)
969
+ | undefined
970
+ /** Enqueues webhook updates staged with transfer mutations. */
971
+ dispatchTransferUpdates?:
972
+ | ((references: readonly Webhooks.QueueReference[]) => Promise<number>)
973
+ | undefined
974
+ }
975
+ }
976
+
694
977
  function quoteNotAvailable(c: Context<App.Environment>) {
695
978
  return Response.error(c, {
696
979
  code: 'quote_not_available',
@@ -1,7 +1,7 @@
1
1
  import { Hash, Hex, Value } from 'ox'
2
2
  import type Stripe from 'stripe'
3
3
 
4
- import type * as Store from '../../internal/Store.js'
4
+ import * as ApiKey from '../../ApiKey.js'
5
5
  import * as ApiKeys from '../../ApiKeys.js'
6
6
  import type * as BillingSettings from '../../db/tables/billingSettings.js'
7
7
  import * as Db from '../../db/Db.js'
@@ -9,6 +9,7 @@ import * as Fees from '../../internal/Fees.js'
9
9
  import * as RequestUsage from '../../db/tables/requestUsage.js'
10
10
  import type * as Scope from '../../Scope.js'
11
11
  import * as SponsoredTransactions from '../../db/tables/sponsoredTransactions.js'
12
+ import type * as Store from '../../internal/Store.js'
12
13
  import * as StripeCustomers from '../../db/tables/stripeCustomers.js'
13
14
  import * as Viem from '../../internal/Viem.js'
14
15
 
@@ -567,10 +568,22 @@ export function createRequestUsageReporter(
567
568
  reported++
568
569
  } catch (error) {
569
570
  failed++
570
- console.error(
571
- `Billing.createRequestUsageReporter: reporting ${environment} bucket ${orgId}/${bucketStart} failed`,
572
- error,
573
- )
571
+ // Cloudflare flattens multiple console arguments, so keep the driver details on one structured entry.
572
+ const cause = error instanceof Error ? error : undefined
573
+ console.error({
574
+ bucketStart,
575
+ component: 'request_usage_meter',
576
+ environment,
577
+ error: ApiKey.redact(cause?.message ?? String(error)).slice(0, 500),
578
+ ...(cause &&
579
+ 'code' in cause &&
580
+ (typeof cause.code === 'string' || typeof cause.code === 'number')
581
+ ? { errorCode: ApiKey.redact(String(cause.code)).slice(0, 100) }
582
+ : {}),
583
+ errorType: cause?.name ?? typeof error,
584
+ orgId,
585
+ ...(cause?.stack ? { stack: ApiKey.redact(cause.stack).slice(0, 4_000) } : {}),
586
+ })
574
587
  }
575
588
  }
576
589
  }