tapimo 0.10.2 → 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 (386) hide show
  1. package/dist/App.d.ts +4896 -2166
  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/Webhooks.d.ts +0 -75
  10. package/dist/Webhooks.d.ts.map +1 -1
  11. package/dist/Webhooks.js +1 -143
  12. package/dist/Webhooks.js.map +1 -1
  13. package/dist/admin/App.d.ts +127 -78
  14. package/dist/admin/App.d.ts.map +1 -1
  15. package/dist/admin/apps/earn-vaults.d.ts +115 -1
  16. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  17. package/dist/admin/apps/earn-vaults.js +59 -6
  18. package/dist/admin/apps/earn-vaults.js.map +1 -1
  19. package/dist/admin/apps/organizations.d.ts +3 -3
  20. package/dist/admin/apps/organizations.d.ts.map +1 -1
  21. package/dist/admin/apps/organizations.js +4 -2
  22. package/dist/admin/apps/organizations.js.map +1 -1
  23. package/dist/admin/apps/verified-tokens.d.ts +83 -83
  24. package/dist/admin/ui.generated.d.ts +1 -1
  25. package/dist/admin/ui.generated.d.ts.map +1 -1
  26. package/dist/admin/ui.generated.js +151 -151
  27. package/dist/admin/ui.generated.js.map +1 -1
  28. package/dist/apps/data/App.d.ts +5924 -4310
  29. package/dist/apps/data/App.d.ts.map +1 -1
  30. package/dist/apps/data/App.js +61 -9
  31. package/dist/apps/data/App.js.map +1 -1
  32. package/dist/apps/data/ZoneSelection.d.ts +62 -0
  33. package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
  34. package/dist/apps/data/ZoneSelection.js +44 -0
  35. package/dist/apps/data/ZoneSelection.js.map +1 -0
  36. package/dist/apps/data/routes/activities.d.ts +2368 -5
  37. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  38. package/dist/apps/data/routes/activities.js +423 -114
  39. package/dist/apps/data/routes/activities.js.map +1 -1
  40. package/dist/apps/data/routes/addresses.d.ts +131 -0
  41. package/dist/apps/data/routes/addresses.d.ts.map +1 -1
  42. package/dist/apps/data/routes/balances.d.ts +25 -25
  43. package/dist/apps/data/routes/balances.js +1 -1
  44. package/dist/apps/data/routes/balances.js.map +1 -1
  45. package/dist/apps/data/routes/blocks.d.ts +1 -1
  46. package/dist/apps/data/routes/blocks.js +1 -1
  47. package/dist/apps/data/routes/blocks.js.map +1 -1
  48. package/dist/apps/data/routes/earn.d.ts +135 -10
  49. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  50. package/dist/apps/data/routes/earn.js +157 -25
  51. package/dist/apps/data/routes/earn.js.map +1 -1
  52. package/dist/apps/data/routes/exchanges.d.ts +829 -123
  53. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  54. package/dist/apps/data/routes/exchanges.js +16 -13
  55. package/dist/apps/data/routes/exchanges.js.map +1 -1
  56. package/dist/apps/data/routes/fee-amm.d.ts +26 -26
  57. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  58. package/dist/apps/data/routes/fee-amm.js +9 -11
  59. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  60. package/dist/apps/data/routes/receipts.d.ts +54 -54
  61. package/dist/apps/data/routes/receipts.js +1 -1
  62. package/dist/apps/data/routes/receipts.js.map +1 -1
  63. package/dist/apps/data/routes/rpc.js +24 -10
  64. package/dist/apps/data/routes/rpc.js.map +1 -1
  65. package/dist/apps/data/routes/tokenlist.d.ts +12 -12
  66. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
  67. package/dist/apps/data/routes/tokenlist.js +16 -15
  68. package/dist/apps/data/routes/tokenlist.js.map +1 -1
  69. package/dist/apps/data/routes/tokens.d.ts +17 -3
  70. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  71. package/dist/apps/data/routes/tokens.js +34 -15
  72. package/dist/apps/data/routes/tokens.js.map +1 -1
  73. package/dist/apps/data/routes/transactions.d.ts +1 -1
  74. package/dist/apps/data/routes/transactions.js +1 -1
  75. package/dist/apps/data/routes/transactions.js.map +1 -1
  76. package/dist/apps/data/routes/transfers.d.ts +13 -13
  77. package/dist/apps/data/routes/transfers.d.ts.map +1 -1
  78. package/dist/apps/data/routes/transfers.js +7 -9
  79. package/dist/apps/data/routes/transfers.js.map +1 -1
  80. package/dist/apps/data/routes/valuation.d.ts +21 -21
  81. package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
  82. package/dist/apps/data/routes/webhooks.d.ts +1011 -151
  83. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  84. package/dist/apps/data/routes/webhooks.js +126 -739
  85. package/dist/apps/data/routes/webhooks.js.map +1 -1
  86. package/dist/apps/data/routes/zones.d.ts +15 -15
  87. package/dist/apps/funding/App.d.ts +27 -27
  88. package/dist/apps/funding/routes/chains.d.ts.map +1 -1
  89. package/dist/apps/funding/routes/chains.js +5 -4
  90. package/dist/apps/funding/routes/chains.js.map +1 -1
  91. package/dist/apps/funding/routes/deposit-addresses.d.ts +18 -18
  92. package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
  93. package/dist/apps/funding/routes/deposit-addresses.js +8 -8
  94. package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
  95. package/dist/apps/funding/routes/providers.d.ts.map +1 -1
  96. package/dist/apps/funding/routes/providers.js +3 -2
  97. package/dist/apps/funding/routes/providers.js.map +1 -1
  98. package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
  99. package/dist/apps/funding/routes/quotes.js +2 -2
  100. package/dist/apps/funding/routes/quotes.js.map +1 -1
  101. package/dist/apps/funding/routes/transfers.d.ts +33 -33
  102. package/dist/apps/management/App.d.ts +1433 -322
  103. package/dist/apps/management/App.d.ts.map +1 -1
  104. package/dist/apps/management/Billing.d.ts.map +1 -1
  105. package/dist/apps/management/Billing.js +19 -6
  106. package/dist/apps/management/Billing.js.map +1 -1
  107. package/dist/apps/management/routes/api-keys.d.ts +154 -94
  108. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  109. package/dist/apps/management/routes/api-keys.js +76 -30
  110. package/dist/apps/management/routes/api-keys.js.map +1 -1
  111. package/dist/apps/management/routes/billing.d.ts +103 -30
  112. package/dist/apps/management/routes/billing.d.ts.map +1 -1
  113. package/dist/apps/management/routes/billing.js +91 -32
  114. package/dist/apps/management/routes/billing.js.map +1 -1
  115. package/dist/apps/management/routes/faucet.d.ts +12 -12
  116. package/dist/apps/management/routes/faucet.d.ts.map +1 -1
  117. package/dist/apps/management/routes/faucet.js +23 -12
  118. package/dist/apps/management/routes/faucet.js.map +1 -1
  119. package/dist/apps/management/routes/invitations.d.ts +46 -13
  120. package/dist/apps/management/routes/invitations.d.ts.map +1 -1
  121. package/dist/apps/management/routes/invitations.js +79 -29
  122. package/dist/apps/management/routes/invitations.js.map +1 -1
  123. package/dist/apps/management/routes/invite-links.d.ts +128 -83
  124. package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
  125. package/dist/apps/management/routes/invite-links.js +100 -41
  126. package/dist/apps/management/routes/invite-links.js.map +1 -1
  127. package/dist/apps/management/routes/me.d.ts +5 -5
  128. package/dist/apps/management/routes/me.d.ts.map +1 -1
  129. package/dist/apps/management/routes/me.js +14 -10
  130. package/dist/apps/management/routes/me.js.map +1 -1
  131. package/dist/apps/management/routes/members.d.ts +68 -47
  132. package/dist/apps/management/routes/members.d.ts.map +1 -1
  133. package/dist/apps/management/routes/members.js +37 -18
  134. package/dist/apps/management/routes/members.js.map +1 -1
  135. package/dist/apps/management/routes/orgs.d.ts +48 -8
  136. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  137. package/dist/apps/management/routes/orgs.js +48 -19
  138. package/dist/apps/management/routes/orgs.js.map +1 -1
  139. package/dist/apps/management/routes/projects.d.ts +130 -68
  140. package/dist/apps/management/routes/projects.d.ts.map +1 -1
  141. package/dist/apps/management/routes/projects.js +72 -21
  142. package/dist/apps/management/routes/projects.js.map +1 -1
  143. package/dist/apps/management/routes/scopes.d.ts.map +1 -1
  144. package/dist/apps/management/routes/scopes.js +8 -5
  145. package/dist/apps/management/routes/scopes.js.map +1 -1
  146. package/dist/apps/management/routes/usage.d.ts +38 -38
  147. package/dist/apps/management/routes/usage.d.ts.map +1 -1
  148. package/dist/apps/management/routes/usage.js +41 -31
  149. package/dist/apps/management/routes/usage.js.map +1 -1
  150. package/dist/apps/management/routes/verified-token-requests.d.ts +34 -6
  151. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  152. package/dist/apps/management/routes/verified-token-requests.js +36 -17
  153. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  154. package/dist/apps/management/routes/webhooks.d.ts +1186 -197
  155. package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
  156. package/dist/apps/management/routes/webhooks.js +106 -38
  157. package/dist/apps/management/routes/webhooks.js.map +1 -1
  158. package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
  159. package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
  160. package/dist/apps/mpp/internal/Adapter.js +12 -0
  161. package/dist/apps/mpp/internal/Adapter.js.map +1 -1
  162. package/dist/db/Db.d.ts +2 -0
  163. package/dist/db/Db.d.ts.map +1 -1
  164. package/dist/db/Db.js +61 -0
  165. package/dist/db/Db.js.map +1 -1
  166. package/dist/db/Schema.d.ts +30 -2
  167. package/dist/db/Schema.d.ts.map +1 -1
  168. package/dist/db/Schema.js +28 -3
  169. package/dist/db/Schema.js.map +1 -1
  170. package/dist/db/tables/earnVaults.d.ts +5 -1
  171. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  172. package/dist/db/tables/earnVaults.js +5 -0
  173. package/dist/db/tables/earnVaults.js.map +1 -1
  174. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
  175. package/dist/db/tables/webhookDeliveries.js +10 -0
  176. package/dist/db/tables/webhookDeliveries.js.map +1 -1
  177. package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
  178. package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
  179. package/dist/db/tables/webhookQueueCompletions.js +32 -0
  180. package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
  181. package/dist/db/tables/webhookQueueEvents.d.ts +16 -20
  182. package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
  183. package/dist/db/tables/webhookQueueEvents.js +68 -43
  184. package/dist/db/tables/webhookQueueEvents.js.map +1 -1
  185. package/dist/db/tables/webhookSubscriptions.d.ts +47 -72
  186. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
  187. package/dist/db/tables/webhookSubscriptions.js +92 -105
  188. package/dist/db/tables/webhookSubscriptions.js.map +1 -1
  189. package/dist/internal/Auth.d.ts +8 -1
  190. package/dist/internal/Auth.d.ts.map +1 -1
  191. package/dist/internal/Auth.js +13 -3
  192. package/dist/internal/Auth.js.map +1 -1
  193. package/dist/internal/Cache.d.ts.map +1 -1
  194. package/dist/internal/Cache.js +11 -7
  195. package/dist/internal/Cache.js.map +1 -1
  196. package/dist/internal/EarnVaults.d.ts +41 -2
  197. package/dist/internal/EarnVaults.d.ts.map +1 -1
  198. package/dist/internal/EarnVaults.js +167 -0
  199. package/dist/internal/EarnVaults.js.map +1 -1
  200. package/dist/internal/MetricSink.d.ts +35 -125
  201. package/dist/internal/MetricSink.d.ts.map +1 -1
  202. package/dist/internal/MetricSink.js +50 -121
  203. package/dist/internal/MetricSink.js.map +1 -1
  204. package/dist/internal/OpenApi.d.ts +26 -22
  205. package/dist/internal/OpenApi.d.ts.map +1 -1
  206. package/dist/internal/OpenApi.js +128 -39
  207. package/dist/internal/OpenApi.js.map +1 -1
  208. package/dist/internal/Response.d.ts +13 -8
  209. package/dist/internal/Response.d.ts.map +1 -1
  210. package/dist/internal/Response.js +16 -5
  211. package/dist/internal/Response.js.map +1 -1
  212. package/dist/internal/Schema.d.ts +8 -8
  213. package/dist/internal/Schema.d.ts.map +1 -1
  214. package/dist/internal/Schema.js +10 -9
  215. package/dist/internal/Schema.js.map +1 -1
  216. package/dist/internal/Store.d.ts +15 -6
  217. package/dist/internal/Store.d.ts.map +1 -1
  218. package/dist/internal/Store.js +45 -15
  219. package/dist/internal/Store.js.map +1 -1
  220. package/dist/internal/Tidx.d.ts +2 -0
  221. package/dist/internal/Tidx.d.ts.map +1 -1
  222. package/dist/internal/Tidx.js +16 -4
  223. package/dist/internal/Tidx.js.map +1 -1
  224. package/dist/internal/WebhookTransfer.d.ts +1 -55
  225. package/dist/internal/WebhookTransfer.d.ts.map +1 -1
  226. package/dist/internal/WebhookTransfer.js +1 -239
  227. package/dist/internal/WebhookTransfer.js.map +1 -1
  228. package/dist/internal/Webhooks.d.ts +112 -56
  229. package/dist/internal/Webhooks.d.ts.map +1 -1
  230. package/dist/internal/Webhooks.js +124 -93
  231. package/dist/internal/Webhooks.js.map +1 -1
  232. package/dist/internal/funding/Deposit.d.ts +2 -2
  233. package/dist/internal/funding/Deposit.d.ts.map +1 -1
  234. package/dist/internal/funding/Deposit.js +9 -8
  235. package/dist/internal/funding/Deposit.js.map +1 -1
  236. package/dist/internal/funding/DepositAddress.d.ts +4 -4
  237. package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
  238. package/dist/internal/funding/DepositAddress.js +9 -8
  239. package/dist/internal/funding/DepositAddress.js.map +1 -1
  240. package/dist/internal/funding/DepositWebhook.d.ts +25 -0
  241. package/dist/internal/funding/DepositWebhook.d.ts.map +1 -0
  242. package/dist/internal/funding/DepositWebhook.js +74 -0
  243. package/dist/internal/funding/DepositWebhook.js.map +1 -0
  244. package/dist/internal/funding/Provider.d.ts.map +1 -1
  245. package/dist/internal/funding/Provider.js +13 -12
  246. package/dist/internal/funding/Provider.js.map +1 -1
  247. package/dist/internal/funding/Reconciliation.d.ts +6 -0
  248. package/dist/internal/funding/Reconciliation.d.ts.map +1 -1
  249. package/dist/internal/funding/Reconciliation.js +42 -10
  250. package/dist/internal/funding/Reconciliation.js.map +1 -1
  251. package/dist/internal/funding/index.d.ts +1 -0
  252. package/dist/internal/funding/index.d.ts.map +1 -1
  253. package/dist/internal/funding/index.js +1 -0
  254. package/dist/internal/funding/index.js.map +1 -1
  255. package/dist/internal/funding/providers/stargate.d.ts +19 -0
  256. package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
  257. package/dist/internal/funding/providers/stargate.js +143 -0
  258. package/dist/internal/funding/providers/stargate.js.map +1 -0
  259. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -1
  260. package/dist/internal/webhookDestinations/slack.js +16 -0
  261. package/dist/internal/webhookDestinations/slack.js.map +1 -1
  262. package/dist/providers/index.d.ts +7 -0
  263. package/dist/providers/index.d.ts.map +1 -1
  264. package/dist/providers/index.js +3 -0
  265. package/dist/providers/index.js.map +1 -1
  266. package/package.json +2 -2
  267. package/src/App.test.ts +48 -0
  268. package/src/App.ts +7 -2
  269. package/src/Assets.test.ts +18 -0
  270. package/src/Assets.ts +22 -0
  271. package/src/Client.test-d.ts +287 -17
  272. package/src/Webhooks.ts +1 -220
  273. package/src/admin/apps/earn-vaults.test.ts +143 -0
  274. package/src/admin/apps/earn-vaults.ts +83 -6
  275. package/src/admin/apps/organizations.ts +6 -2
  276. package/src/admin/ui/src/routes/api-keys.tsx +36 -0
  277. package/src/admin/ui.generated.ts +151 -189
  278. package/src/apps/data/App.test.ts +31 -0
  279. package/src/apps/data/App.ts +64 -10
  280. package/src/apps/data/ZoneSelection.test.ts +196 -0
  281. package/src/apps/data/ZoneSelection.ts +108 -0
  282. package/src/apps/data/routes/activities.test.ts +435 -12
  283. package/src/apps/data/routes/activities.ts +562 -125
  284. package/src/apps/data/routes/balances.ts +1 -1
  285. package/src/apps/data/routes/blocks.ts +1 -1
  286. package/src/apps/data/routes/earn.test.ts +183 -23
  287. package/src/apps/data/routes/earn.ts +225 -29
  288. package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
  289. package/src/apps/data/routes/exchanges.test.ts +31 -1
  290. package/src/apps/data/routes/exchanges.ts +19 -15
  291. package/src/apps/data/routes/fee-amm.ts +18 -11
  292. package/src/apps/data/routes/receipts.ts +1 -1
  293. package/src/apps/data/routes/rpc.test.ts +75 -0
  294. package/src/apps/data/routes/rpc.ts +23 -9
  295. package/src/apps/data/routes/tokenlist.ts +21 -18
  296. package/src/apps/data/routes/tokens.test.ts +29 -0
  297. package/src/apps/data/routes/tokens.ts +38 -15
  298. package/src/apps/data/routes/transactions.ts +1 -1
  299. package/src/apps/data/routes/transfers.test.ts +3 -3
  300. package/src/apps/data/routes/transfers.ts +12 -9
  301. package/src/apps/data/routes/webhooks.test.ts +179 -1497
  302. package/src/apps/data/routes/webhooks.ts +156 -976
  303. package/src/apps/data/routes/zones.test.ts +19 -13
  304. package/src/apps/funding/routes/chains.test.ts +211 -7
  305. package/src/apps/funding/routes/chains.ts +19 -12
  306. package/src/apps/funding/routes/deposit-addresses.test.ts +394 -0
  307. package/src/apps/funding/routes/deposit-addresses.ts +84 -72
  308. package/src/apps/funding/routes/providers.ts +9 -5
  309. package/src/apps/funding/routes/quotes.test.ts +46 -0
  310. package/src/apps/funding/routes/quotes.ts +8 -5
  311. package/src/apps/funding/routes/transfers.test.ts +35 -32
  312. package/src/apps/management/Billing.test.ts +26 -0
  313. package/src/apps/management/Billing.ts +24 -7
  314. package/src/apps/management/routes/api-keys.test.ts +178 -0
  315. package/src/apps/management/routes/api-keys.ts +203 -144
  316. package/src/apps/management/routes/billing.test.ts +209 -0
  317. package/src/apps/management/routes/billing.ts +254 -177
  318. package/src/apps/management/routes/faucet.test.ts +39 -0
  319. package/src/apps/management/routes/faucet.ts +75 -41
  320. package/src/apps/management/routes/invitations.test.ts +216 -0
  321. package/src/apps/management/routes/invitations.ts +186 -109
  322. package/src/apps/management/routes/invite-links.test.ts +263 -1
  323. package/src/apps/management/routes/invite-links.ts +295 -214
  324. package/src/apps/management/routes/me.test.ts +49 -0
  325. package/src/apps/management/routes/me.ts +42 -32
  326. package/src/apps/management/routes/members.test.ts +124 -1
  327. package/src/apps/management/routes/members.ts +81 -51
  328. package/src/apps/management/routes/orgs.test.ts +176 -0
  329. package/src/apps/management/routes/orgs.ts +101 -59
  330. package/src/apps/management/routes/projects.test.ts +183 -0
  331. package/src/apps/management/routes/projects.ts +124 -60
  332. package/src/apps/management/routes/scopes.test.ts +44 -0
  333. package/src/apps/management/routes/scopes.ts +37 -28
  334. package/src/apps/management/routes/usage.test.ts +92 -0
  335. package/src/apps/management/routes/usage.ts +186 -151
  336. package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
  337. package/src/apps/management/routes/verified-token-requests.ts +166 -133
  338. package/src/apps/management/routes/webhooks.test.ts +313 -1
  339. package/src/apps/management/routes/webhooks.ts +220 -71
  340. package/src/apps/mpp/internal/Adapter.ts +13 -1
  341. package/src/db/Db.test.ts +42 -5
  342. package/src/db/Db.ts +85 -0
  343. package/src/db/Schema.ts +41 -3
  344. package/src/db/tables/earnVaults.test.ts +22 -0
  345. package/src/db/tables/earnVaults.ts +11 -1
  346. package/src/db/tables/organizations.test.ts +5 -2
  347. package/src/db/tables/webhookDeliveries.ts +13 -0
  348. package/src/db/tables/webhookQueueCompletions.ts +55 -0
  349. package/src/db/tables/webhookQueueEvents.ts +97 -57
  350. package/src/db/tables/webhookSubscriptions.ts +134 -144
  351. package/src/internal/Auth.ts +23 -5
  352. package/src/internal/Cache.ts +14 -7
  353. package/src/internal/EarnVaults.capabilities.test.ts +33 -0
  354. package/src/internal/EarnVaults.test.ts +79 -0
  355. package/src/internal/EarnVaults.ts +277 -0
  356. package/src/internal/MetricSink.test.ts +41 -373
  357. package/src/internal/MetricSink.ts +92 -273
  358. package/src/internal/OpenApi.ts +165 -49
  359. package/src/internal/Response.test.ts +95 -0
  360. package/src/internal/Response.ts +40 -2
  361. package/src/internal/Schema.test.ts +34 -0
  362. package/src/internal/Schema.ts +20 -9
  363. package/src/internal/Store.test.ts +186 -0
  364. package/src/internal/Store.ts +57 -17
  365. package/src/internal/Tidx.test.ts +19 -0
  366. package/src/internal/Tidx.ts +16 -4
  367. package/src/internal/WebhookTransfer.ts +1 -351
  368. package/src/internal/Webhooks.test.ts +222 -145
  369. package/src/internal/Webhooks.ts +234 -135
  370. package/src/internal/funding/Deposit.ts +71 -64
  371. package/src/internal/funding/DepositAddress.ts +50 -43
  372. package/src/internal/funding/DepositWebhook.test.ts +131 -0
  373. package/src/internal/funding/DepositWebhook.ts +101 -0
  374. package/src/internal/funding/Provider.ts +164 -142
  375. package/src/internal/funding/Reconciliation.test.ts +14 -0
  376. package/src/internal/funding/Reconciliation.ts +161 -86
  377. package/src/internal/funding/index.test.ts +1 -0
  378. package/src/internal/funding/index.ts +1 -0
  379. package/src/internal/funding/providers/index.test.ts +185 -0
  380. package/src/internal/funding/providers/stargate.ts +184 -0
  381. package/src/internal/webhookDestinations/slack.ts +15 -0
  382. package/src/providers/index.test.ts +1 -0
  383. package/src/providers/index.ts +9 -0
  384. package/src/Webhooks.bench.ts +0 -714
  385. package/src/Webhooks.memory.bench.ts +0 -250
  386. package/src/Webhooks.test.ts +0 -146
@@ -173,7 +173,7 @@ describe('narrows responses by status', () => {
173
173
  'apy.window': '24h',
174
174
  capability: 'deposit',
175
175
  'engine.type': 'erc4626',
176
- include: 'access,apy,capabilities,token.logoUri,tvl,zone',
176
+ include: 'access,apy,capabilities,token.logoUri,tvl,zone,zones',
177
177
  },
178
178
  })
179
179
 
@@ -205,6 +205,8 @@ describe('narrows responses by status', () => {
205
205
  expectTypeOf(json.data[0]!.vaultAddress).toEqualTypeOf<`0x${string}`>()
206
206
  expectTypeOf(json.data[0]!.verified).toEqualTypeOf<boolean>()
207
207
  expectTypeOf(json.data[0]!.zone?.chainId).toEqualTypeOf<number | undefined>()
208
+ expectTypeOf(json.data[0]!.zones?.[0]?.deploymentBlock).toEqualTypeOf<number | undefined>()
209
+ expectTypeOf(json.data[0]!.zones?.[0]?.earnRouter).toEqualTypeOf<`0x${string}` | undefined>()
208
210
  expectTypeOf(json.meta?.valuation?.basis).toEqualTypeOf<'nominal' | undefined>()
209
211
  void json
210
212
  return
@@ -226,7 +228,10 @@ describe('narrows responses by status', () => {
226
228
  test('GET /v1/earn/vaults/verified', async () => {
227
229
  const client = Client.create()
228
230
  const res = await client.v1.earn.vaults.verified.$get({
229
- query: { 'apy.window': '7d', include: 'access,apy,capabilities,token.logoUri,tvl,zone' },
231
+ query: {
232
+ 'apy.window': '7d',
233
+ include: 'access,apy,capabilities,token.logoUri,tvl,zone,zones',
234
+ },
230
235
  })
231
236
 
232
237
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PaidAccessStatus>()
@@ -243,6 +248,7 @@ describe('narrows responses by status', () => {
243
248
  expectTypeOf(json.data[0]!.tvl).toEqualTypeOf<VaultValue | null | undefined>()
244
249
  expectTypeOf(json.data[0]!.tvl?.formatted).toEqualTypeOf<string | undefined>()
245
250
  expectTypeOf(json.data[0]!.verified).toEqualTypeOf<true>()
251
+ expectTypeOf(json.data[0]!.zones?.[0]?.chainId).toEqualTypeOf<number | undefined>()
246
252
  expectTypeOf(json.meta?.valuation?.source).toEqualTypeOf<string | undefined>()
247
253
  void json
248
254
  return
@@ -968,6 +974,46 @@ describe('narrows responses by status', () => {
968
974
  void json
969
975
  return
970
976
  }
977
+ case 403: {
978
+ const json = await res.json()
979
+ expectTypeOf(json.error.code).toEqualTypeOf<
980
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
981
+ >()
982
+ void json
983
+ return
984
+ }
985
+ }
986
+ })
987
+
988
+ test('DELETE /v1/orgs/:orgId', async () => {
989
+ const client = Client.create()
990
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].$delete({
991
+ param: { orgId: 'org_test' },
992
+ })
993
+
994
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
995
+
996
+ switch (res.status) {
997
+ case 403: {
998
+ const json = await res.json()
999
+ expectTypeOf(json.error.code).toEqualTypeOf<
1000
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1001
+ >()
1002
+ void json
1003
+ return
1004
+ }
1005
+ case 404: {
1006
+ const json = await res.json()
1007
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1008
+ void json
1009
+ return
1010
+ }
1011
+ case 409: {
1012
+ const json = await res.json()
1013
+ expectTypeOf(json.error.code).toEqualTypeOf<'sponsorships_unreported'>()
1014
+ void json
1015
+ return
1016
+ }
971
1017
  }
972
1018
  })
973
1019
 
@@ -1035,10 +1081,21 @@ describe('narrows responses by status', () => {
1035
1081
 
1036
1082
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1037
1083
 
1038
- if (res.status === 200) {
1039
- const json = await res.json()
1040
- expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
1041
- void json
1084
+ switch (res.status) {
1085
+ case 200: {
1086
+ const json = await res.json()
1087
+ expectTypeOf(json.allowedIps).toEqualTypeOf<readonly string[]>()
1088
+ void json
1089
+ return
1090
+ }
1091
+ case 403: {
1092
+ const json = await res.json()
1093
+ expectTypeOf(json.error.code).toEqualTypeOf<
1094
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1095
+ >()
1096
+ void json
1097
+ return
1098
+ }
1042
1099
  }
1043
1100
  })
1044
1101
 
@@ -1053,6 +1110,14 @@ describe('narrows responses by status', () => {
1053
1110
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1054
1111
 
1055
1112
  switch (res.status) {
1113
+ case 403: {
1114
+ const json = await res.json()
1115
+ expectTypeOf(json.error.code).toEqualTypeOf<
1116
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1117
+ >()
1118
+ void json
1119
+ return
1120
+ }
1056
1121
  case 404: {
1057
1122
  const json = await res.json()
1058
1123
  expectTypeOf(json.error.code).toEqualTypeOf<
@@ -1117,6 +1182,12 @@ describe('narrows responses by status', () => {
1117
1182
  void json
1118
1183
  return
1119
1184
  }
1185
+ case 404: {
1186
+ const json = await res.json()
1187
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1188
+ void json
1189
+ return
1190
+ }
1120
1191
  }
1121
1192
  })
1122
1193
 
@@ -1129,6 +1200,20 @@ describe('narrows responses by status', () => {
1129
1200
  expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
1130
1201
 
1131
1202
  switch (res.status) {
1203
+ case 403: {
1204
+ const json = await res.json()
1205
+ expectTypeOf(json.error.code).toEqualTypeOf<
1206
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1207
+ >()
1208
+ void json
1209
+ return
1210
+ }
1211
+ case 404: {
1212
+ const json = await res.json()
1213
+ expectTypeOf(json.error.code).toEqualTypeOf<'member_not_found' | 'organization_not_found'>()
1214
+ void json
1215
+ return
1216
+ }
1132
1217
  case 409: {
1133
1218
  const json = await res.json()
1134
1219
  expectTypeOf(json.error.code).toEqualTypeOf<'last_owner'>()
@@ -1138,6 +1223,87 @@ describe('narrows responses by status', () => {
1138
1223
  }
1139
1224
  })
1140
1225
 
1226
+ test('DELETE /v1/orgs/:orgId/members/:userId', async () => {
1227
+ const client = Client.create()
1228
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].members[
1229
+ ':userId{usr_[A-Za-z0-9_-]+}'
1230
+ ].$delete({ param: { orgId: 'org_test', userId: 'usr_test' } })
1231
+
1232
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 409 | 502 | PublicAccessStatus>()
1233
+
1234
+ switch (res.status) {
1235
+ case 200: {
1236
+ const json = await res.json()
1237
+ expectTypeOf(json.userId).toEqualTypeOf<string>()
1238
+ void json
1239
+ return
1240
+ }
1241
+ case 404: {
1242
+ const json = await res.json()
1243
+ expectTypeOf(json.error.code).toEqualTypeOf<'member_not_found' | 'organization_not_found'>()
1244
+ void json
1245
+ return
1246
+ }
1247
+ case 409: {
1248
+ const json = await res.json()
1249
+ expectTypeOf(json.error.code).toEqualTypeOf<'last_owner'>()
1250
+ void json
1251
+ return
1252
+ }
1253
+ }
1254
+ })
1255
+
1256
+ test('POST /v1/orgs/:orgId/invitations', async () => {
1257
+ const client = Client.create()
1258
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].invitations.$post({
1259
+ json: { email: 'dev@example.com', role: 'member' },
1260
+ param: { orgId: 'org_test' },
1261
+ })
1262
+
1263
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1264
+
1265
+ switch (res.status) {
1266
+ case 200: {
1267
+ const json = await res.json()
1268
+ expectTypeOf(json.email).toEqualTypeOf<string>()
1269
+ expectTypeOf(json.role).toEqualTypeOf<'admin' | 'member' | 'owner'>()
1270
+ void json
1271
+ return
1272
+ }
1273
+ case 403: {
1274
+ const json = await res.json()
1275
+ expectTypeOf(json.error.code).toEqualTypeOf<
1276
+ 'api_key_forbidden' | 'api_key_ip_forbidden' | 'forbidden'
1277
+ >()
1278
+ void json
1279
+ return
1280
+ }
1281
+ case 404: {
1282
+ const json = await res.json()
1283
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1284
+ void json
1285
+ return
1286
+ }
1287
+ }
1288
+ })
1289
+
1290
+ test('DELETE /v1/orgs/:orgId/invitations/:invitationId', async () => {
1291
+ const client = Client.create()
1292
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].invitations[
1293
+ ':invitationId{inv_[A-Za-z0-9_-]+}'
1294
+ ].$delete({ param: { invitationId: 'inv_test', orgId: 'org_test' } })
1295
+
1296
+ expectTypeOf(res.status).toEqualTypeOf<200 | 404 | 502 | PublicAccessStatus>()
1297
+
1298
+ if (res.status === 404) {
1299
+ const json = await res.json()
1300
+ expectTypeOf(json.error.code).toEqualTypeOf<
1301
+ 'invitation_not_found' | 'organization_not_found'
1302
+ >()
1303
+ void json
1304
+ }
1305
+ })
1306
+
1141
1307
  test('POST /v1/orgs/:orgId/invite-links', async () => {
1142
1308
  const client = Client.create()
1143
1309
  const orgLinks = client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['invite-links']
@@ -1157,13 +1323,57 @@ describe('narrows responses by status', () => {
1157
1323
  >()
1158
1324
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
1159
1325
 
1160
- if (res.status === 200) {
1161
- const json = await res.json()
1162
- expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<readonly string[] | null>()
1163
- expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<
1164
- z.output<typeof InviteLinks.schema.InviteLink>['allowedEmailDomains']
1165
- >()
1166
- void json
1326
+ switch (res.status) {
1327
+ case 200: {
1328
+ const json = await res.json()
1329
+ expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<readonly string[] | null>()
1330
+ expectTypeOf(json.allowedEmailDomains).toEqualTypeOf<
1331
+ z.output<typeof InviteLinks.schema.InviteLink>['allowedEmailDomains']
1332
+ >()
1333
+ void json
1334
+ return
1335
+ }
1336
+ case 403: {
1337
+ const json = await res.json()
1338
+ expectTypeOf(json.error.code).toEqualTypeOf<'forbidden'>()
1339
+ void json
1340
+ return
1341
+ }
1342
+ case 404: {
1343
+ const json = await res.json()
1344
+ expectTypeOf(json.error.code).toEqualTypeOf<'organization_not_found'>()
1345
+ void json
1346
+ return
1347
+ }
1348
+ }
1349
+ })
1350
+
1351
+ test('PATCH /v1/orgs/:orgId/invite-links/:inviteLinkId', async () => {
1352
+ const client = Client.create()
1353
+ const res = await client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}']['invite-links'][
1354
+ ':inviteLinkId{iln_[A-Za-z0-9_-]+}'
1355
+ ].$patch({
1356
+ json: { enabled: false },
1357
+ param: { inviteLinkId: 'iln_test', orgId: 'org_test' },
1358
+ })
1359
+
1360
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 401 | 403 | 404 | 502>()
1361
+
1362
+ switch (res.status) {
1363
+ case 403: {
1364
+ const json = await res.json()
1365
+ expectTypeOf(json.error.code).toEqualTypeOf<'forbidden'>()
1366
+ void json
1367
+ return
1368
+ }
1369
+ case 404: {
1370
+ const json = await res.json()
1371
+ expectTypeOf(json.error.code).toEqualTypeOf<
1372
+ 'invite_link_not_found' | 'organization_not_found'
1373
+ >()
1374
+ void json
1375
+ return
1376
+ }
1167
1377
  }
1168
1378
  })
1169
1379
 
@@ -1500,14 +1710,18 @@ describe('narrows responses by status', () => {
1500
1710
  param: {
1501
1711
  transactionHash: '0x4845ae2098724ab26a5d89370dce5124d044be6a5acc164afc348662de67d474',
1502
1712
  },
1503
- query: { include: 'token.logoUri,token.verified' },
1713
+ query: {
1714
+ chainId: '4217',
1715
+ include: 'zones,token.logoUri,token.verified',
1716
+ },
1504
1717
  })
1505
1718
 
1506
- expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
1719
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 409 | 502 | PaidAccessStatus>()
1507
1720
 
1508
1721
  switch (res.status) {
1509
1722
  case 200: {
1510
1723
  const json = await res.json()
1724
+ expectTypeOf(json.chainId).toEqualTypeOf<number>()
1511
1725
  expectTypeOf(json.data[0]!.type).toEqualTypeOf<
1512
1726
  z.output<
1513
1727
  typeof Activities.schema.getTransactionActivities.Response
@@ -1550,6 +1764,13 @@ describe('narrows responses by status', () => {
1550
1764
  void json
1551
1765
  return
1552
1766
  }
1767
+ case 409: {
1768
+ const json = await res.json()
1769
+ expectTypeOf(json.error.code).toEqualTypeOf<'transaction_ambiguous'>()
1770
+ expectTypeOf(json.error.message).toEqualTypeOf<string>()
1771
+ void json
1772
+ return
1773
+ }
1553
1774
  case 502: {
1554
1775
  const json = await res.json()
1555
1776
  expectTypeOf(json.error.code).toEqualTypeOf<'upstream_error'>()
@@ -2604,6 +2825,30 @@ describe('narrows responses by status', () => {
2604
2825
  }
2605
2826
  })
2606
2827
 
2828
+ test('QUERY /v1/exchange/quotes', async () => {
2829
+ const client = Client.create()
2830
+ const res = await client.v1.exchange.quotes.$query({
2831
+ json: {
2832
+ account: '0x1111111111111111111111111111111111111111',
2833
+ amount: '1000000',
2834
+ destinationToken: '0x20c000000000000000000000b9537d11c60e8b50',
2835
+ mode: 'exactSource',
2836
+ slippageBps: 50,
2837
+ sourceToken: '0x20c0000000000000000000008f5425160ebe5525',
2838
+ },
2839
+ query: { include: 'token.logoUri,token.verified' },
2840
+ })
2841
+
2842
+ expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 404 | 502 | PaidAccessStatus>()
2843
+ if (res.status === 200) {
2844
+ const json = await res.json()
2845
+ expectTypeOf(json.destinationAmount).toEqualTypeOf<ValuedTokenAmount>()
2846
+ expectTypeOf(json.sourceAmount).toEqualTypeOf<ValuedTokenAmount>()
2847
+ expectTypeOf(json.destinationToken.logoUri).toEqualTypeOf<string | undefined>()
2848
+ expectTypeOf(json.sourceToken.verified).toEqualTypeOf<boolean | undefined>()
2849
+ }
2850
+ })
2851
+
2607
2852
  test('POST /v1/exchange/quotes/execute', async () => {
2608
2853
  const client = Client.create()
2609
2854
  const res = await client.v1.exchange.quotes.execute.$post({
@@ -3292,7 +3537,10 @@ describe('narrows responses by status', () => {
3292
3537
  const client = Client.create()
3293
3538
  const res = await client.v1.addresses[':address'].activities.$get({
3294
3539
  param: { address: '0x0000000000000000000000000000000000000000' },
3295
- query: { include: 'token.logoUri,token.verified' },
3540
+ query: {
3541
+ chainId: '4217',
3542
+ include: 'zones,token.logoUri,token.verified',
3543
+ },
3296
3544
  })
3297
3545
 
3298
3546
  expectTypeOf(res.status).toEqualTypeOf<200 | 400 | 502 | PaidAccessStatus>()
@@ -3300,6 +3548,7 @@ describe('narrows responses by status', () => {
3300
3548
  switch (res.status) {
3301
3549
  case 200: {
3302
3550
  const json = await res.json()
3551
+ expectTypeOf(json.data[0]!.chainId).toEqualTypeOf<number | undefined>()
3303
3552
  expectTypeOf(json.data[0]!.type).toEqualTypeOf<
3304
3553
  z.output<typeof Activities.schema.getAddressActivities.Response>['data'][number]['type']
3305
3554
  >()
@@ -3351,6 +3600,17 @@ describe('narrows responses by status', () => {
3351
3600
 
3352
3601
  test('POST /v1/webhooks', async () => {
3353
3602
  const client = Client.create()
3603
+ void client.v1.webhooks.$post({
3604
+ json: {
3605
+ destination: { type: 'url', url: 'https://example.com/webhook' },
3606
+ eventType: 'funding:deposit.updated',
3607
+ filters: {
3608
+ depositAddressId: 'fda_001785792000000_2ZPE2gvateYEQ0dQslgvkhjx',
3609
+ recipient: `0x${'11'.repeat(20)}`,
3610
+ status: 'completed',
3611
+ },
3612
+ },
3613
+ })
3354
3614
  const res = await client.v1.webhooks.$post({
3355
3615
  json: {
3356
3616
  destination: { type: 'url', url: 'https://example.com/webhook' },
@@ -3376,7 +3636,13 @@ describe('narrows responses by status', () => {
3376
3636
  if (res.status === 400) {
3377
3637
  const json = await res.json()
3378
3638
  expectTypeOf(json.error.code).toEqualTypeOf<
3379
- Access400<'body_invalid' | 'chain_id_unsupported' | 'filters_invalid' | 'url_invalid'>
3639
+ Access400<
3640
+ | 'body_invalid'
3641
+ | 'chain_id_unsupported'
3642
+ | 'event_type_unsupported'
3643
+ | 'filters_invalid'
3644
+ | 'url_invalid'
3645
+ >
3380
3646
  >()
3381
3647
  }
3382
3648
  if (res.status === 403) {
@@ -3632,6 +3898,10 @@ describe('narrows responses by status', () => {
3632
3898
  >()
3633
3899
  if (json.envelope.type === 'block:created')
3634
3900
  expectTypeOf(json.envelope.data.number).toEqualTypeOf<number>()
3901
+ if (json.envelope.type === 'funding:deposit.updated')
3902
+ expectTypeOf(json.envelope.data.status).toEqualTypeOf<
3903
+ z.output<typeof Webhooks.schema.FundingDepositEvent>['status']
3904
+ >()
3635
3905
  expectTypeOf(json.requestUrl).toEqualTypeOf<string>()
3636
3906
  void json
3637
3907
  }
package/src/Webhooks.ts CHANGED
@@ -1,18 +1,6 @@
1
- import * as AppWebhooks from './apps/data/routes/webhooks.js'
2
- import * as Db from './db/Db.js'
3
- import * as core_Webhooks from './internal/Webhooks.js'
4
- import * as MetricSink from './internal/MetricSink.js'
5
- import * as Store from './internal/Store.js'
6
- import type * as Metrics from './Metrics.js'
7
- import * as Viem from './internal/Viem.js'
8
-
9
- /** How often a poller reclaims expired rows, independent of tick cadence. */
10
- const pruneIntervalMs = 60_000
11
-
12
1
  // Re-export the runtime-agnostic primitives (subscriptions, signing, delivery,
13
2
  // `deliverAndRecord`, cursors, …) so consumers reach everything through one
14
- // `Webhooks` namespace. The apps-layer poller stays private behind
15
- // `createPoller` below.
3
+ // `Webhooks` namespace.
16
4
  export * from './internal/Webhooks.js'
17
5
 
18
6
  // Re-export the webhook resource's zod schemas so consumers can validate and
@@ -20,210 +8,3 @@ export * from './internal/Webhooks.js'
20
8
  // `type`), plus the per-event `TransferEvent` / `TransactionEvent` / `PingEvent`
21
9
  // payloads. Infer a type with `z.infer<typeof Webhooks.schema.Envelope>`.
22
10
  export { enrichEventData, eventTypes, scanBlock, schema } from './apps/data/routes/webhooks.js'
23
-
24
- /**
25
- * Builds a webhook poller bound to a state store and chain config.
26
- *
27
- * This is the entry point a host runtime drives from chain-head notifications
28
- * or a timer. Each {@link Poller.tick} scans active subscriptions from their
29
- * cursors up to `head - confirmations` and dispatches matching events.
30
- *
31
- * Every onchain event type scans a confirmed window directly over JSON-RPC, so
32
- * the poller builds memoized viem clients via {@link Viem.createGetClient}. The
33
- * poller keeps `App.create` a pure Hono app: it constructs its own clients
34
- * instead of reaching into app internals, and owns no request state.
35
- */
36
- export function createPoller(options: createPoller.Options): createPoller.Poller {
37
- // Persistent memoize cache for token metadata, shared across ticks (the
38
- // webhook state store used to double-duty as this cache).
39
- const cache = options.cache ?? Store.memory()
40
- const getClient = Viem.createGetClient({
41
- defaultChainId: options.defaultChainId,
42
- rpc: options.rpc,
43
- })
44
- // Chain-head ticks run about once per block, so the janitor is throttled here
45
- // rather than issuing deletes per block. Reads filter expiry at query time, so
46
- // reclaiming late only costs space.
47
- let prunedAt: number | undefined
48
-
49
- const metrics = options.metrics ? MetricSink.webhooks(options.metrics) : undefined
50
-
51
- return {
52
- async tick(input = {}) {
53
- const chainId = input.chainId ?? options.defaultChainId ?? Viem.defaultChainId
54
-
55
- // Wrap the transport so each enqueue (or inline delivery) emits a timed
56
- // `webhook:enqueue` metric. The wrapper preserves the dispatch contract: it
57
- // returns the underlying result unchanged and is a no-op when no metrics
58
- // backend is configured.
59
- const inner = input.dispatch ?? options.dispatch
60
- const innerBatch =
61
- input.dispatchBatch ?? (input.dispatch === undefined ? options.dispatchBatch : undefined)
62
- const dispatch =
63
- metrics && inner
64
- ? async (dispatchable: AppWebhooks.poll.Dispatchable) => {
65
- const start = Date.now()
66
- const result = await inner(dispatchable)
67
- metrics.record({
68
- chainId: dispatchable.envelope.chainId,
69
- durationMs: Date.now() - start,
70
- eventType: dispatchable.envelope.type,
71
- ok: result.ok,
72
- type: 'webhook:enqueue',
73
- })
74
- return result
75
- }
76
- : inner
77
- const dispatchBatch = innerBatch
78
- ? async (
79
- dispatchables: readonly AppWebhooks.poll.Dispatchable[],
80
- context: AppWebhooks.poll.DispatchContext,
81
- ) => {
82
- const start = Date.now()
83
- const result = await innerBatch(dispatchables, context)
84
- const durationMs = Date.now() - start
85
- for (const dispatchable of dispatchables)
86
- metrics?.record({
87
- chainId: dispatchable.envelope.chainId,
88
- durationMs,
89
- eventType: dispatchable.envelope.type,
90
- ok: result.ok,
91
- type: 'webhook:enqueue',
92
- })
93
- return result
94
- }
95
- : undefined
96
-
97
- // Resolve per tick so Workers factories build a fresh Hyperdrive-pooled
98
- // connection each run.
99
- const db = Db.get(options.db)
100
- const now = input.now ?? options.now
101
- if (prunedAt === undefined || Date.now() - prunedAt >= pruneIntervalMs) {
102
- prunedAt = Date.now()
103
- await core_Webhooks.pruneExpired(db, { now }).catch(() => {})
104
- }
105
-
106
- const start = Date.now()
107
- let cursorLagBlocks: number | undefined
108
- try {
109
- const result = await AppWebhooks.poll({
110
- batchSize: input.batchSize ?? options.batchSize,
111
- cache,
112
- chainId,
113
- client: getClient(chainId),
114
- confirmations: input.confirmations ?? options.confirmations,
115
- db,
116
- dispatch,
117
- dispatchBatch,
118
- eventTypes: input.eventTypes ?? options.eventTypes,
119
- ...(input.headBlockNumber === undefined
120
- ? {}
121
- : { headBlockNumber: input.headBlockNumber }),
122
- maxBlocks: input.maxBlocks ?? options.maxBlocks,
123
- now,
124
- signal: input.signal,
125
- ...(metrics
126
- ? {
127
- onCursorLag(blocks: number) {
128
- cursorLagBlocks = blocks
129
- },
130
- onScanCheckpoint(checkpoint: AppWebhooks.poll.ScanCheckpoint) {
131
- metrics.record({ chainId, type: 'webhook:poll-scan', ...checkpoint })
132
- // Ship the start boundary before the RPC allocation can terminate the isolate.
133
- metrics.flush()
134
- },
135
- onStage(stage: AppWebhooks.poll.Stage) {
136
- metrics.record({ chainId, type: 'webhook:poll', ...stage })
137
- },
138
- onSubscriptions(count: number) {
139
- metrics.record({ chainId, count, type: 'webhook:poll-subscriptions' })
140
- },
141
- }
142
- : {}),
143
- })
144
- metrics?.record({
145
- cursorLagBlocks,
146
- meta: { durationMs: Date.now() - start, outcome: 'ok' },
147
- result,
148
- type: 'webhook:tick',
149
- })
150
- return result
151
- } catch (error) {
152
- metrics?.record({
153
- cursorLagBlocks,
154
- meta: { chainId, durationMs: Date.now() - start, outcome: 'error' },
155
- result: undefined,
156
- type: 'webhook:tick',
157
- })
158
- throw error
159
- } finally {
160
- metrics?.flush()
161
- }
162
- },
163
- }
164
- }
165
-
166
- export declare namespace createPoller {
167
- /** A row to dispatch, paired with its owning subscription. */
168
- type Dispatchable = AppWebhooks.poll.Dispatchable
169
-
170
- /** Delivery transport: hands a matched event to a queue or delivers inline. */
171
- type Dispatch = NonNullable<AppWebhooks.poll.Options['dispatch']>
172
-
173
- /** Batch delivery transport: confirms all rows together or leaves their cursor unchanged. */
174
- type DispatchBatch = NonNullable<AppWebhooks.poll.Options['dispatchBatch']>
175
-
176
- /** Summary counters returned by {@link Poller.tick}. */
177
- type Result = AppWebhooks.poll.Result
178
-
179
- /** Knobs shared by every {@link Poller.tick}; each is overridable per tick. */
180
- type Defaults = {
181
- /** Max matching rows scanned per subscription per tick (default 200). */
182
- batchSize?: number | undefined
183
- /** Reorg-safety window: only emit blocks this far behind head (default 1). */
184
- confirmations?: number | undefined
185
- /**
186
- * Delivery transport. Defaults to inline `deliverAndRecord` (self-host); on
187
- * Cloudflare pass a Queue producer so retry/backoff/DLQ are native.
188
- */
189
- dispatch?: Dispatch | undefined
190
- /** Batch delivery transport used when the runtime can enqueue multiple rows atomically. */
191
- dispatchBatch?: DispatchBatch | undefined
192
- /** Event types to poll (default all). */
193
- eventTypes?: AppWebhooks.poll.Options['eventTypes']
194
- /** Backfill cap: most blocks an RPC scanner inspects per tick (default 1000). */
195
- maxBlocks?: number | undefined
196
- /** Clock for envelope timestamps; injectable for tests. */
197
- now?: (() => Date) | undefined
198
- }
199
-
200
- /** Options for {@link createPoller}. */
201
- type Options = Defaults & {
202
- /** Cache for token metadata shared across ticks. */
203
- cache?: Store.Store | undefined
204
- /** Database holding subscriptions + cursors, or a factory resolved per tick (Workers/Hyperdrive). */
205
- db: Db.Source
206
- /** Tempo chain id polled when a tick omits one. */
207
- defaultChainId?: Viem.ChainId | undefined
208
- /** Metrics backend; emits `webhook:tick` per tick and `webhook:enqueue` per dispatch. */
209
- metrics?: Metrics.Metrics | undefined
210
- /** RPC options for the viem clients that scan chain events. */
211
- rpc?: Viem.getClient.Rpc | undefined
212
- }
213
-
214
- /** Per-tick overrides; falls back to the {@link Options} defaults. */
215
- type TickOptions = Defaults & {
216
- /** Chain to poll this tick (default `options.defaultChainId`). */
217
- chainId?: Viem.ChainId | undefined
218
- /** Chain head to work back from; resolved from RPC when omitted. */
219
- headBlockNumber?: bigint | number | undefined
220
- /** Stops scanning and dispatch when the caller loses its execution lease. */
221
- signal?: AbortSignal | undefined
222
- }
223
-
224
- /** A chain-head-driven webhook poller. */
225
- type Poller = {
226
- /** Runs one poll tick, resolving the RPC head when not supplied. */
227
- tick(options?: TickOptions): Promise<Result>
228
- }
229
- }