tapimo 0.0.0 → 0.0.2

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 (422) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +119 -0
  3. package/dist/ApiKey.d.ts +65 -0
  4. package/dist/ApiKey.d.ts.map +1 -0
  5. package/dist/ApiKey.js +105 -0
  6. package/dist/ApiKey.js.map +1 -0
  7. package/dist/ApiKeySource.d.ts +166 -0
  8. package/dist/ApiKeySource.d.ts.map +1 -0
  9. package/dist/ApiKeySource.js +234 -0
  10. package/dist/ApiKeySource.js.map +1 -0
  11. package/dist/App.d.ts +19317 -0
  12. package/dist/App.d.ts.map +1 -0
  13. package/dist/App.js +612 -0
  14. package/dist/App.js.map +1 -0
  15. package/dist/Assets.d.ts +44 -0
  16. package/dist/Assets.d.ts.map +1 -0
  17. package/dist/Assets.js +23 -0
  18. package/dist/Assets.js.map +1 -0
  19. package/dist/Auth.d.ts +2 -0
  20. package/dist/Auth.d.ts.map +1 -0
  21. package/dist/Auth.js +2 -0
  22. package/dist/Auth.js.map +1 -0
  23. package/dist/Cli.d.ts +21 -0
  24. package/dist/Cli.d.ts.map +1 -0
  25. package/dist/Cli.js +13 -0
  26. package/dist/Cli.js.map +1 -0
  27. package/dist/Client.d.ts +20 -0
  28. package/dist/Client.d.ts.map +1 -0
  29. package/dist/Client.js +24 -0
  30. package/dist/Client.js.map +1 -0
  31. package/dist/Metrics.d.ts +70 -0
  32. package/dist/Metrics.d.ts.map +1 -0
  33. package/dist/Metrics.js +91 -0
  34. package/dist/Metrics.js.map +1 -0
  35. package/dist/Scope.d.ts +35 -0
  36. package/dist/Scope.d.ts.map +1 -0
  37. package/dist/Scope.js +38 -0
  38. package/dist/Scope.js.map +1 -0
  39. package/dist/Webhooks.d.ts +79 -0
  40. package/dist/Webhooks.d.ts.map +1 -0
  41. package/dist/Webhooks.js +107 -0
  42. package/dist/Webhooks.js.map +1 -0
  43. package/dist/admin/Access.d.ts +41 -0
  44. package/dist/admin/Access.d.ts.map +1 -0
  45. package/dist/admin/Access.js +75 -0
  46. package/dist/admin/Access.js.map +1 -0
  47. package/dist/admin/App.d.ts +1221 -0
  48. package/dist/admin/App.d.ts.map +1 -0
  49. package/dist/admin/App.js +113 -0
  50. package/dist/admin/App.js.map +1 -0
  51. package/dist/admin/apps/api-keys.d.ts +209 -0
  52. package/dist/admin/apps/api-keys.d.ts.map +1 -0
  53. package/dist/admin/apps/api-keys.js +129 -0
  54. package/dist/admin/apps/api-keys.js.map +1 -0
  55. package/dist/admin/apps/scopes.d.ts +46 -0
  56. package/dist/admin/apps/scopes.d.ts.map +1 -0
  57. package/dist/admin/apps/scopes.js +41 -0
  58. package/dist/admin/apps/scopes.js.map +1 -0
  59. package/dist/admin/apps/verified-tokens.d.ts +1206 -0
  60. package/dist/admin/apps/verified-tokens.d.ts.map +1 -0
  61. package/dist/admin/apps/verified-tokens.js +485 -0
  62. package/dist/admin/apps/verified-tokens.js.map +1 -0
  63. package/dist/admin/index.d.ts +3 -0
  64. package/dist/admin/index.d.ts.map +1 -0
  65. package/dist/admin/index.js +3 -0
  66. package/dist/admin/index.js.map +1 -0
  67. package/dist/admin/ui.generated.d.ts +11 -0
  68. package/dist/admin/ui.generated.d.ts.map +1 -0
  69. package/dist/admin/ui.generated.js +43 -0
  70. package/dist/admin/ui.generated.js.map +1 -0
  71. package/dist/apps/activities.d.ts +18725 -0
  72. package/dist/apps/activities.d.ts.map +1 -0
  73. package/dist/apps/activities.js +3138 -0
  74. package/dist/apps/activities.js.map +1 -0
  75. package/dist/apps/addresses.d.ts +3662 -0
  76. package/dist/apps/addresses.d.ts.map +1 -0
  77. package/dist/apps/addresses.js +22 -0
  78. package/dist/apps/addresses.js.map +1 -0
  79. package/dist/apps/balances.d.ts +342 -0
  80. package/dist/apps/balances.d.ts.map +1 -0
  81. package/dist/apps/balances.js +393 -0
  82. package/dist/apps/balances.js.map +1 -0
  83. package/dist/apps/blocks.d.ts +931 -0
  84. package/dist/apps/blocks.d.ts.map +1 -0
  85. package/dist/apps/blocks.js +689 -0
  86. package/dist/apps/blocks.js.map +1 -0
  87. package/dist/apps/coingecko.d.ts +1053 -0
  88. package/dist/apps/coingecko.d.ts.map +1 -0
  89. package/dist/apps/coingecko.js +1015 -0
  90. package/dist/apps/coingecko.js.map +1 -0
  91. package/dist/apps/exchanges.d.ts +3000 -0
  92. package/dist/apps/exchanges.d.ts.map +1 -0
  93. package/dist/apps/exchanges.js +3570 -0
  94. package/dist/apps/exchanges.js.map +1 -0
  95. package/dist/apps/fee-amm.d.ts +640 -0
  96. package/dist/apps/fee-amm.d.ts.map +1 -0
  97. package/dist/apps/fee-amm.js +815 -0
  98. package/dist/apps/fee-amm.js.map +1 -0
  99. package/dist/apps/indexer.d.ts +116 -0
  100. package/dist/apps/indexer.d.ts.map +1 -0
  101. package/dist/apps/indexer.js +270 -0
  102. package/dist/apps/indexer.js.map +1 -0
  103. package/dist/apps/receipts.d.ts +1438 -0
  104. package/dist/apps/receipts.d.ts.map +1 -0
  105. package/dist/apps/receipts.js +874 -0
  106. package/dist/apps/receipts.js.map +1 -0
  107. package/dist/apps/rpc.d.ts +173 -0
  108. package/dist/apps/rpc.d.ts.map +1 -0
  109. package/dist/apps/rpc.js +191 -0
  110. package/dist/apps/rpc.js.map +1 -0
  111. package/dist/apps/tokenlist.d.ts +192 -0
  112. package/dist/apps/tokenlist.d.ts.map +1 -0
  113. package/dist/apps/tokenlist.js +153 -0
  114. package/dist/apps/tokenlist.js.map +1 -0
  115. package/dist/apps/tokens.d.ts +2246 -0
  116. package/dist/apps/tokens.d.ts.map +1 -0
  117. package/dist/apps/tokens.js +1789 -0
  118. package/dist/apps/tokens.js.map +1 -0
  119. package/dist/apps/transactions.d.ts +2327 -0
  120. package/dist/apps/transactions.d.ts.map +1 -0
  121. package/dist/apps/transactions.js +975 -0
  122. package/dist/apps/transactions.js.map +1 -0
  123. package/dist/apps/transfers.d.ts +589 -0
  124. package/dist/apps/transfers.d.ts.map +1 -0
  125. package/dist/apps/transfers.js +769 -0
  126. package/dist/apps/transfers.js.map +1 -0
  127. package/dist/apps/verified-tokens.d.ts +544 -0
  128. package/dist/apps/verified-tokens.d.ts.map +1 -0
  129. package/dist/apps/verified-tokens.js +234 -0
  130. package/dist/apps/verified-tokens.js.map +1 -0
  131. package/dist/apps/webhooks.d.ts +7684 -0
  132. package/dist/apps/webhooks.d.ts.map +1 -0
  133. package/dist/apps/webhooks.js +2112 -0
  134. package/dist/apps/webhooks.js.map +1 -0
  135. package/dist/cloudflare.d.ts +32 -0
  136. package/dist/cloudflare.d.ts.map +1 -0
  137. package/dist/cloudflare.js +45 -0
  138. package/dist/cloudflare.js.map +1 -0
  139. package/dist/index.d.ts +16 -0
  140. package/dist/index.d.ts.map +1 -0
  141. package/dist/index.js +16 -0
  142. package/dist/index.js.map +1 -0
  143. package/dist/internal/Auth.d.ts +298 -0
  144. package/dist/internal/Auth.d.ts.map +1 -0
  145. package/dist/internal/Auth.js +618 -0
  146. package/dist/internal/Auth.js.map +1 -0
  147. package/dist/internal/Cache.d.ts +74 -0
  148. package/dist/internal/Cache.d.ts.map +1 -0
  149. package/dist/internal/Cache.js +215 -0
  150. package/dist/internal/Cache.js.map +1 -0
  151. package/dist/internal/Cursor.d.ts +79 -0
  152. package/dist/internal/Cursor.d.ts.map +1 -0
  153. package/dist/internal/Cursor.js +116 -0
  154. package/dist/internal/Cursor.js.map +1 -0
  155. package/dist/internal/EdgeCache.d.ts +59 -0
  156. package/dist/internal/EdgeCache.d.ts.map +1 -0
  157. package/dist/internal/EdgeCache.js +174 -0
  158. package/dist/internal/EdgeCache.js.map +1 -0
  159. package/dist/internal/Log.d.ts +104 -0
  160. package/dist/internal/Log.d.ts.map +1 -0
  161. package/dist/internal/Log.js +118 -0
  162. package/dist/internal/Log.js.map +1 -0
  163. package/dist/internal/MetricSink.d.ts +65 -0
  164. package/dist/internal/MetricSink.d.ts.map +1 -0
  165. package/dist/internal/MetricSink.js +146 -0
  166. package/dist/internal/MetricSink.js.map +1 -0
  167. package/dist/internal/Mpp.d.ts +71 -0
  168. package/dist/internal/Mpp.d.ts.map +1 -0
  169. package/dist/internal/Mpp.js +105 -0
  170. package/dist/internal/Mpp.js.map +1 -0
  171. package/dist/internal/OpenApi.d.ts +313 -0
  172. package/dist/internal/OpenApi.d.ts.map +1 -0
  173. package/dist/internal/OpenApi.fonts.d.ts +2 -0
  174. package/dist/internal/OpenApi.fonts.d.ts.map +1 -0
  175. package/dist/internal/OpenApi.fonts.js +39 -0
  176. package/dist/internal/OpenApi.fonts.js.map +1 -0
  177. package/dist/internal/OpenApi.js +335 -0
  178. package/dist/internal/OpenApi.js.map +1 -0
  179. package/dist/internal/OpenApi.logo.d.ts +6 -0
  180. package/dist/internal/OpenApi.logo.d.ts.map +1 -0
  181. package/dist/internal/OpenApi.logo.js +19 -0
  182. package/dist/internal/OpenApi.logo.js.map +1 -0
  183. package/dist/internal/Path.d.ts +5 -0
  184. package/dist/internal/Path.d.ts.map +1 -0
  185. package/dist/internal/Path.js +16 -0
  186. package/dist/internal/Path.js.map +1 -0
  187. package/dist/internal/RateLimit.d.ts +60 -0
  188. package/dist/internal/RateLimit.d.ts.map +1 -0
  189. package/dist/internal/RateLimit.js +48 -0
  190. package/dist/internal/RateLimit.js.map +1 -0
  191. package/dist/internal/Response.d.ts +132 -0
  192. package/dist/internal/Response.d.ts.map +1 -0
  193. package/dist/internal/Response.js +72 -0
  194. package/dist/internal/Response.js.map +1 -0
  195. package/dist/internal/Schema.d.ts +257 -0
  196. package/dist/internal/Schema.d.ts.map +1 -0
  197. package/dist/internal/Schema.js +360 -0
  198. package/dist/internal/Schema.js.map +1 -0
  199. package/dist/internal/Store.d.ts +204 -0
  200. package/dist/internal/Store.d.ts.map +1 -0
  201. package/dist/internal/Store.js +291 -0
  202. package/dist/internal/Store.js.map +1 -0
  203. package/dist/internal/Tidx.d.ts +120 -0
  204. package/dist/internal/Tidx.d.ts.map +1 -0
  205. package/dist/internal/Tidx.js +156 -0
  206. package/dist/internal/Tidx.js.map +1 -0
  207. package/dist/internal/Timing.d.ts +22 -0
  208. package/dist/internal/Timing.d.ts.map +1 -0
  209. package/dist/internal/Timing.js +32 -0
  210. package/dist/internal/Timing.js.map +1 -0
  211. package/dist/internal/Ttl.d.ts +25 -0
  212. package/dist/internal/Ttl.d.ts.map +1 -0
  213. package/dist/internal/Ttl.js +49 -0
  214. package/dist/internal/Ttl.js.map +1 -0
  215. package/dist/internal/Value.d.ts +47 -0
  216. package/dist/internal/Value.d.ts.map +1 -0
  217. package/dist/internal/Value.js +122 -0
  218. package/dist/internal/Value.js.map +1 -0
  219. package/dist/internal/VerifiedTokens.d.ts +228 -0
  220. package/dist/internal/VerifiedTokens.d.ts.map +1 -0
  221. package/dist/internal/VerifiedTokens.js +450 -0
  222. package/dist/internal/VerifiedTokens.js.map +1 -0
  223. package/dist/internal/Viem.d.ts +2082 -0
  224. package/dist/internal/Viem.d.ts.map +1 -0
  225. package/dist/internal/Viem.js +63 -0
  226. package/dist/internal/Viem.js.map +1 -0
  227. package/dist/internal/WebhookDestination.d.ts +198 -0
  228. package/dist/internal/WebhookDestination.d.ts.map +1 -0
  229. package/dist/internal/WebhookDestination.js +170 -0
  230. package/dist/internal/WebhookDestination.js.map +1 -0
  231. package/dist/internal/Webhooks.d.ts +433 -0
  232. package/dist/internal/Webhooks.d.ts.map +1 -0
  233. package/dist/internal/Webhooks.js +489 -0
  234. package/dist/internal/Webhooks.js.map +1 -0
  235. package/dist/internal/webhookDestinations/betterStack.d.ts +26 -0
  236. package/dist/internal/webhookDestinations/betterStack.d.ts.map +1 -0
  237. package/dist/internal/webhookDestinations/betterStack.js +76 -0
  238. package/dist/internal/webhookDestinations/betterStack.js.map +1 -0
  239. package/dist/internal/webhookDestinations/slack.d.ts +59 -0
  240. package/dist/internal/webhookDestinations/slack.d.ts.map +1 -0
  241. package/dist/internal/webhookDestinations/slack.js +422 -0
  242. package/dist/internal/webhookDestinations/slack.js.map +1 -0
  243. package/dist/internal/webhookDestinations/url.d.ts +17 -0
  244. package/dist/internal/webhookDestinations/url.d.ts.map +1 -0
  245. package/dist/internal/webhookDestinations/url.js +130 -0
  246. package/dist/internal/webhookDestinations/url.js.map +1 -0
  247. package/dist/openrpc.json +5302 -0
  248. package/package.json +46 -4
  249. package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +1 -0
  250. package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +1 -0
  251. package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +1 -0
  252. package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +1 -0
  253. package/seeds/31318/verified-tokens.json +30 -0
  254. package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +25 -0
  255. package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +1 -0
  256. package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +1 -0
  257. package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +4 -0
  258. package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +30 -0
  259. package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +1 -0
  260. package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +1 -0
  261. package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +1 -0
  262. package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +11 -0
  263. package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +1 -0
  264. package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +1 -0
  265. package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
  266. package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +1 -0
  267. package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
  268. package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +1 -0
  269. package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +5 -0
  270. package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +1 -0
  271. package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +1 -0
  272. package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +1 -0
  273. package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +1 -0
  274. package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +1 -0
  275. package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +1 -0
  276. package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +1 -0
  277. package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +1 -0
  278. package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
  279. package/seeds/4217/verified-tokens.json +177 -0
  280. package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +25 -0
  281. package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +1 -0
  282. package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +1 -0
  283. package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +1 -0
  284. package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +1 -0
  285. package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +1 -0
  286. package/seeds/42431/verified-tokens.json +44 -0
  287. package/seeds/openrpc/README.md +27 -0
  288. package/seeds/openrpc/execution-apis.json +8989 -0
  289. package/src/ApiKey.test.ts +91 -0
  290. package/src/ApiKey.ts +122 -0
  291. package/src/ApiKeySource.test-d.ts +11 -0
  292. package/src/ApiKeySource.test.ts +295 -0
  293. package/src/ApiKeySource.ts +303 -0
  294. package/src/App.test-d.ts +38 -0
  295. package/src/App.test.ts +65927 -0
  296. package/src/App.ts +855 -0
  297. package/src/Assets.ts +58 -0
  298. package/src/Auth.ts +1 -0
  299. package/src/Cli.test.ts +81 -0
  300. package/src/Cli.ts +38 -0
  301. package/src/Client.test-d.ts +1438 -0
  302. package/src/Client.test.ts +134 -0
  303. package/src/Client.ts +45 -0
  304. package/src/Metrics.ts +154 -0
  305. package/src/Scope.ts +50 -0
  306. package/src/Webhooks.test.ts +49 -0
  307. package/src/Webhooks.ts +172 -0
  308. package/src/admin/Access.test.ts +130 -0
  309. package/src/admin/Access.ts +87 -0
  310. package/src/admin/App.test.ts +225 -0
  311. package/src/admin/App.ts +216 -0
  312. package/src/admin/apps/api-keys.test.ts +156 -0
  313. package/src/admin/apps/api-keys.ts +157 -0
  314. package/src/admin/apps/scopes.test.ts +52 -0
  315. package/src/admin/apps/scopes.ts +47 -0
  316. package/src/admin/apps/verified-tokens.test.ts +415 -0
  317. package/src/admin/apps/verified-tokens.ts +566 -0
  318. package/src/admin/index.ts +2 -0
  319. package/src/admin/ui/plugin.ts +135 -0
  320. package/src/admin/ui/src/components/Checkbox.tsx +22 -0
  321. package/src/admin/ui/src/components/Dialog.tsx +32 -0
  322. package/src/admin/ui/src/components/MobileProfile.tsx +31 -0
  323. package/src/admin/ui/src/components/Page.tsx +53 -0
  324. package/src/admin/ui/src/components/TempoLogo.tsx +37 -0
  325. package/src/admin/ui/src/fonts/Pilat-Demi.woff2 +0 -0
  326. package/src/admin/ui/src/fonts/Pilat-Regular.woff2 +0 -0
  327. package/src/admin/ui/src/lib/api-keys.ts +63 -0
  328. package/src/admin/ui/src/lib/client.ts +15 -0
  329. package/src/admin/ui/src/lib/config.ts +57 -0
  330. package/src/admin/ui/src/lib/query-client.ts +26 -0
  331. package/src/admin/ui/src/lib/scopes.ts +25 -0
  332. package/src/admin/ui/src/lib/verified-tokens.ts +89 -0
  333. package/src/admin/ui/src/lib/wagmi.ts +18 -0
  334. package/src/admin/ui/src/routeTree.gen.ts +104 -0
  335. package/src/admin/ui/src/router.tsx +25 -0
  336. package/src/admin/ui/src/routes/__root.tsx +219 -0
  337. package/src/admin/ui/src/routes/api-keys.tsx +329 -0
  338. package/src/admin/ui/src/routes/index.tsx +7 -0
  339. package/src/admin/ui/src/routes/verified-tokens.tsx +331 -0
  340. package/src/admin/ui/src/styles.css +20 -0
  341. package/src/admin/ui/tsconfig.json +16 -0
  342. package/src/admin/ui/vite.config.ts +29 -0
  343. package/src/admin/ui.generated.ts +60 -0
  344. package/src/apps/activities.test.ts +1020 -0
  345. package/src/apps/activities.ts +3934 -0
  346. package/src/apps/addresses.ts +24 -0
  347. package/src/apps/balances.test.ts +274 -0
  348. package/src/apps/balances.ts +533 -0
  349. package/src/apps/blocks.test.ts +385 -0
  350. package/src/apps/blocks.ts +896 -0
  351. package/src/apps/coingecko.test.ts +218 -0
  352. package/src/apps/coingecko.ts +1383 -0
  353. package/src/apps/exchanges.test.ts +958 -0
  354. package/src/apps/exchanges.ts +4773 -0
  355. package/src/apps/fee-amm.test.ts +321 -0
  356. package/src/apps/fee-amm.ts +1121 -0
  357. package/src/apps/indexer.test.ts +153 -0
  358. package/src/apps/indexer.ts +330 -0
  359. package/src/apps/receipts.test.ts +285 -0
  360. package/src/apps/receipts.ts +1193 -0
  361. package/src/apps/rpc.test.ts +302 -0
  362. package/src/apps/rpc.ts +222 -0
  363. package/src/apps/tokenlist.test.ts +80 -0
  364. package/src/apps/tokenlist.ts +207 -0
  365. package/src/apps/tokens.test.ts +1062 -0
  366. package/src/apps/tokens.ts +2292 -0
  367. package/src/apps/transactions.test.ts +408 -0
  368. package/src/apps/transactions.ts +1363 -0
  369. package/src/apps/transfers.test.ts +371 -0
  370. package/src/apps/transfers.ts +1116 -0
  371. package/src/apps/verified-tokens.test.ts +114 -0
  372. package/src/apps/verified-tokens.ts +295 -0
  373. package/src/apps/webhooks.test.ts +1937 -0
  374. package/src/apps/webhooks.ts +2926 -0
  375. package/src/cloudflare.ts +55 -0
  376. package/src/index.ts +15 -0
  377. package/src/internal/Auth.test.ts +980 -0
  378. package/src/internal/Auth.ts +1012 -0
  379. package/src/internal/Cache.test.ts +240 -0
  380. package/src/internal/Cache.ts +262 -0
  381. package/src/internal/Cursor.test.ts +100 -0
  382. package/src/internal/Cursor.ts +149 -0
  383. package/src/internal/EdgeCache.test.ts +234 -0
  384. package/src/internal/EdgeCache.ts +224 -0
  385. package/src/internal/Errors.ts +14 -0
  386. package/src/internal/Log.test.ts +244 -0
  387. package/src/internal/Log.ts +216 -0
  388. package/src/internal/MetricSink.ts +220 -0
  389. package/src/internal/Mpp.test.ts +64 -0
  390. package/src/internal/Mpp.ts +141 -0
  391. package/src/internal/OpenApi.fonts.ts +38 -0
  392. package/src/internal/OpenApi.logo.ts +18 -0
  393. package/src/internal/OpenApi.ts +488 -0
  394. package/src/internal/Path.test.ts +14 -0
  395. package/src/internal/Path.ts +15 -0
  396. package/src/internal/RateLimit.test.ts +93 -0
  397. package/src/internal/RateLimit.ts +93 -0
  398. package/src/internal/Response.ts +131 -0
  399. package/src/internal/Schema.test.ts +34 -0
  400. package/src/internal/Schema.ts +523 -0
  401. package/src/internal/Store.test.ts +545 -0
  402. package/src/internal/Store.ts +526 -0
  403. package/src/internal/Tidx.local.test.ts +33 -0
  404. package/src/internal/Tidx.test.ts +294 -0
  405. package/src/internal/Tidx.ts +238 -0
  406. package/src/internal/Timing.test.ts +22 -0
  407. package/src/internal/Timing.ts +62 -0
  408. package/src/internal/Ttl.test.ts +18 -0
  409. package/src/internal/Ttl.ts +59 -0
  410. package/src/internal/Value.ts +114 -0
  411. package/src/internal/VerifiedTokens.test.ts +333 -0
  412. package/src/internal/VerifiedTokens.ts +645 -0
  413. package/src/internal/Viem.test.ts +115 -0
  414. package/src/internal/Viem.ts +165 -0
  415. package/src/internal/WebhookDestination.test.ts +648 -0
  416. package/src/internal/WebhookDestination.ts +331 -0
  417. package/src/internal/Webhooks.test.ts +668 -0
  418. package/src/internal/Webhooks.ts +940 -0
  419. package/src/internal/webhookDestinations/betterStack.ts +91 -0
  420. package/src/internal/webhookDestinations/slack.ts +496 -0
  421. package/src/internal/webhookDestinations/url.ts +128 -0
  422. package/src/openrpc.json +5302 -0
@@ -0,0 +1,134 @@
1
+ import * as Client from './Client.js'
2
+ import * as TestApp from '../test/App.js'
3
+
4
+ test('uses hosted API URL by default', () => {
5
+ const client = Client.create()
6
+
7
+ expect(Client.defaultUrl).toMatchInlineSnapshot(`"https://api.tempo.xyz"`)
8
+ expect(
9
+ client.v1.blocks[':block'].$url({ param: { block: 'latest' } }).toString(),
10
+ ).toMatchInlineSnapshot(`"https://api.tempo.xyz/v1/blocks/latest"`)
11
+ })
12
+
13
+ test('calls Tempo API app through configured fetch implementation', async () => {
14
+ const app = TestApp.create()
15
+ const fetch = (async (input, init) =>
16
+ app.fetch(new Request(input, init))) satisfies typeof globalThis.fetch
17
+ const client = Client.create({ fetch, url: 'http://tempo-api.test' })
18
+
19
+ const response = await client.v1['verified-tokens'].currencies.$get()
20
+ const body = await response.json()
21
+
22
+ expect(response.status).toMatchInlineSnapshot(`200`)
23
+ expect(body).toMatchInlineSnapshot(`
24
+ {
25
+ "data": [],
26
+ }
27
+ `)
28
+ })
29
+
30
+ test('applies `apiKey` to canonical header over base headers', async () => {
31
+ const { calls, fetch } = captureFetch()
32
+ const client = Client.create({
33
+ apiKey: 'key_option',
34
+ fetch,
35
+ headers: {
36
+ authorization: 'Payment proof',
37
+ 'tempo-api-key': 'key_header',
38
+ 'user-agent': 'tempo-api-test',
39
+ },
40
+ url: 'https://api.test',
41
+ })
42
+
43
+ await client.v1.blocks[':block'].$get({ param: { block: 'latest' }, query: {} })
44
+
45
+ expect(calls).toMatchInlineSnapshot(`
46
+ [
47
+ {
48
+ "headers": {
49
+ "authorization": "Payment proof",
50
+ "tempo-api-key": "key_option",
51
+ "user-agent": "tempo-api-test",
52
+ },
53
+ "url": "https://api.test/v1/blocks/latest?",
54
+ },
55
+ ]
56
+ `)
57
+ })
58
+
59
+ test('merges `apiKey` with dynamic base headers', async () => {
60
+ const { calls, fetch } = captureFetch()
61
+ const client = Client.create({
62
+ apiKey: 'key_option',
63
+ fetch,
64
+ headers: async () => ({ authorization: 'Payment proof' }),
65
+ url: 'https://api.test',
66
+ })
67
+
68
+ await client.v1.blocks[':block'].$get({ param: { block: 'latest' }, query: {} })
69
+
70
+ expect(calls).toMatchInlineSnapshot(`
71
+ [
72
+ {
73
+ "headers": {
74
+ "authorization": "Payment proof",
75
+ "tempo-api-key": "key_option",
76
+ },
77
+ "url": "https://api.test/v1/blocks/latest?",
78
+ },
79
+ ]
80
+ `)
81
+ })
82
+
83
+ test('lets per-request headers override base `apiKey`', async () => {
84
+ const { calls, fetch } = captureFetch()
85
+ const client = Client.create({ apiKey: 'key_base', fetch, url: 'https://api.test' })
86
+
87
+ await client.v1.blocks[':block'].$get(
88
+ { param: { block: 'latest' }, query: {} },
89
+ { headers: { 'tempo-api-key': 'key_request' } },
90
+ )
91
+
92
+ expect(calls).toMatchInlineSnapshot(`
93
+ [
94
+ {
95
+ "headers": {
96
+ "tempo-api-key": "key_request",
97
+ },
98
+ "url": "https://api.test/v1/blocks/latest?",
99
+ },
100
+ ]
101
+ `)
102
+ })
103
+
104
+ test('omits empty API keys', async () => {
105
+ const { calls, fetch } = captureFetch()
106
+ const client = Client.create({ apiKey: '', fetch, url: 'https://api.test' })
107
+
108
+ await client.v1.blocks[':block'].$get({ param: { block: 'latest' }, query: {} })
109
+
110
+ expect(calls).toMatchInlineSnapshot(`
111
+ [
112
+ {
113
+ "headers": {},
114
+ "url": "https://api.test/v1/blocks/latest?",
115
+ },
116
+ ]
117
+ `)
118
+ })
119
+
120
+ function captureFetch() {
121
+ const calls: { headers: Record<string, string>; url: string }[] = []
122
+ const fetch = (async (input, init) => {
123
+ calls.push({
124
+ headers: Object.fromEntries(new Headers(init?.headers).entries()),
125
+ url: (() => {
126
+ if (typeof input === 'string') return input
127
+ if (input instanceof URL) return input.toString()
128
+ return input.url
129
+ })(),
130
+ })
131
+ return new Response('{}', { headers: { 'content-type': 'application/json' }, status: 200 })
132
+ }) satisfies typeof globalThis.fetch
133
+ return { calls, fetch }
134
+ }
package/src/Client.ts ADDED
@@ -0,0 +1,45 @@
1
+ import { hc, type ClientRequestOptions } from 'hono/client'
2
+
3
+ import type * as App from './App.js'
4
+
5
+ /** Default hosted Tempo API URL. */
6
+ export const defaultUrl = 'https://api.tempo.xyz'
7
+
8
+ /** Creates a typed client for the hosted Tempo API. */
9
+ export function create(options: create.Options = {}): create.ReturnType {
10
+ const { apiKey, url = defaultUrl, ...client } = options
11
+ const mergedHeaders = headers(client.headers, apiKey)
12
+ if (!mergedHeaders) return hc<App.App>(url, client)
13
+ return hc<App.App>(url, { ...client, headers: mergedHeaders })
14
+ }
15
+
16
+ /** Typed Hono client for the Tempo API. */
17
+ export type Client = ReturnType<typeof hc<App.App>>
18
+
19
+ export declare namespace create {
20
+ /** Typed Hono client returned by {@link create}. */
21
+ type ReturnType = Client
22
+
23
+ /** Options for creating a typed Tempo API client. */
24
+ type Options = ClientRequestOptions & {
25
+ /** API key sent on the canonical `tempo-api-key` header. */
26
+ apiKey?: string | undefined
27
+ /** Tempo API URL. Defaults to {@link defaultUrl}. */
28
+ url?: string | undefined
29
+ }
30
+ }
31
+
32
+ function headers(
33
+ base: ClientRequestOptions['headers'],
34
+ apiKey: string | undefined,
35
+ ): ClientRequestOptions['headers'] {
36
+ if (!apiKey) return base
37
+ if (typeof base === 'function') return async () => mergeHeaders(await base(), apiKey)
38
+ return mergeHeaders(base, apiKey)
39
+ }
40
+
41
+ function mergeHeaders(base: Record<string, string> | undefined, apiKey: string) {
42
+ const headers = new Headers(base)
43
+ headers.set('tempo-api-key', apiKey)
44
+ return Object.fromEntries(headers.entries())
45
+ }
package/src/Metrics.ts ADDED
@@ -0,0 +1,154 @@
1
+ import type * as Log from './internal/Log.js'
2
+
3
+ /** Tag values a metric backend accepts. */
4
+ export type Tags = Record<string, string | number | boolean | undefined | null>
5
+
6
+ /**
7
+ * The bounded StatsD-style surface the built-in metric sinks emit to, plus an
8
+ * optional high-cardinality {@link Metrics.analytics} hook. Apps supply a
9
+ * concrete backend — e.g. {@link cloudflare} — so core carries no metrics-vendor
10
+ * dependency. Pass it as `metrics` to `App.create` and the webhook poller/queue
11
+ * handlers.
12
+ */
13
+ export type Metrics = {
14
+ /**
15
+ * Optional per-request analytics sink, called once with the request-log entry
16
+ * for every response. Unlike the StatsD `count`/`gauge`/`histogram` surface
17
+ * (which stays low-cardinality), this hook carries the full entry — caller
18
+ * ids, org ids, route, status — for a wide-event store (e.g. ClickHouse).
19
+ * Attach it via {@link cloudflare}'s `analytics` option (or {@link from} for a
20
+ * custom backend); omit it to drop analytics. May be async; `App.create` does
21
+ * not await it.
22
+ */
23
+ analytics?: ((entry: Log.Entry) => Promise<void> | void) | undefined
24
+ /** Increments a counter; same name+tags are summed. */
25
+ count(name: string, value: number, tags?: Tags): void
26
+ /** Ships accumulated metrics. */
27
+ flush(): void
28
+ /** Sets a gauge; last write wins for the same name+tags. */
29
+ gauge(name: string, value: number, tags?: Tags): void
30
+ /** Records a histogram observation. */
31
+ histogram(name: string, value: number, tags?: Tags): void
32
+ }
33
+
34
+ /**
35
+ * Creates a {@link Metrics} from a value, type-checking it against the contract.
36
+ * The escape hatch for bringing your own backend (Datadog, Prometheus, …):
37
+ * author the implementation inline and have it validated against {@link Metrics}.
38
+ */
39
+ export function from<const metrics extends Metrics>(metrics: metrics): metrics {
40
+ return metrics
41
+ }
42
+
43
+ /** Options for the {@link cloudflare} preset and its backend. */
44
+ export declare namespace cloudflare {
45
+ /** Shared context handed to the {@link Options.analytics} factory. */
46
+ type Context = {
47
+ /** Resolved `enabled` flag; the analytics sink should drop events when false. */
48
+ enabled: boolean
49
+ /** Deployment environment, also added as the `environment` global tag. */
50
+ environment?: string | undefined
51
+ /** Service name, also added as the `service` global tag. */
52
+ service?: string | undefined
53
+ }
54
+ type Options = {
55
+ /**
56
+ * Builds the per-request {@link Metrics.analytics} hook from the shared
57
+ * {@link Context}, so the sink reuses `enabled`/`environment`/`service`
58
+ * instead of repeating them. Omit to drop analytics.
59
+ */
60
+ analytics?: ((context: Context) => Metrics['analytics']) | undefined
61
+ /** Set false (e.g. in local `wrangler dev`) to drop every metric and analytics event. Default true. */
62
+ enabled?: boolean | undefined
63
+ /** Deployment environment, added as the `environment` global tag and shared with {@link Options.analytics}. */
64
+ environment?: string | undefined
65
+ /** Service name, added as the `service` global tag and shared with {@link Options.analytics}. */
66
+ service?: string | undefined
67
+ }
68
+ }
69
+
70
+ /**
71
+ * A Cloudflare Workers {@link Metrics} — pass it as `metrics` to `App.create`
72
+ * and the webhook poller/queue handlers. It buffers metrics and emits them on
73
+ * `flush()` as `cwm-`-prefixed `console.log` lines (one per ≤250 KiB batch) for
74
+ * a Workers Logs → metrics pipeline to scrape; no external dependency.
75
+ */
76
+ export function cloudflare(options: cloudflare.Options = {}): Metrics {
77
+ type Entry = { n: string; t: 'c' | 'g' | 'h'; tags: Tags; ts: number; v: number }
78
+
79
+ const enabled = options.enabled !== false
80
+
81
+ const analytics = options.analytics?.({
82
+ enabled,
83
+ environment: options.environment,
84
+ service: options.service,
85
+ })
86
+
87
+ if (!enabled) return { analytics, count() {}, flush() {}, gauge() {}, histogram() {} }
88
+
89
+ const globalTags: Tags = {
90
+ ...(options.environment === undefined ? {} : { environment: options.environment }),
91
+ ...(options.service === undefined ? {} : { service: options.service }),
92
+ }
93
+
94
+ const counts = new Map<string, Entry>()
95
+ const gauges = new Map<string, Entry>()
96
+ const histograms: Entry[] = []
97
+
98
+ const key = (name: string, tags: Tags) => {
99
+ let s = name
100
+ for (const k of Object.keys(tags).sort()) s += `\0${k}\0${tags[k]}`
101
+ return s
102
+ }
103
+ const withGlobal = (tags?: Tags): Tags => ({ ...globalTags, ...tags })
104
+
105
+ return {
106
+ analytics,
107
+ count(name, value, tags) {
108
+ const merged = withGlobal(tags)
109
+ const k = key(name, merged)
110
+ const existing = counts.get(k)
111
+ if (existing) existing.v += value
112
+ else counts.set(k, { n: name, t: 'c', tags: merged, ts: 0, v: value })
113
+ },
114
+ flush() {
115
+ const ts = Date.now()
116
+ const entries: Entry[] = []
117
+ for (const e of counts.values()) entries.push({ ...e, ts })
118
+ for (const e of gauges.values()) entries.push({ ...e, ts })
119
+ entries.push(...histograms)
120
+ counts.clear()
121
+ gauges.clear()
122
+ histograms.length = 0
123
+ if (!entries.length) return
124
+
125
+ // Emit as `cwm-[…]` lines, splitting batches over the size cap. Serialize
126
+ // with the field order the Workers Logs pipeline emits (`t,n,v,tags,ts`).
127
+ const parts = entries.map((e) =>
128
+ JSON.stringify({ t: e.t, n: e.n, v: e.v, tags: e.tags, ts: e.ts }),
129
+ )
130
+ let buf: string[] = []
131
+ let bufLen = 0
132
+ for (const part of parts) {
133
+ // 5 bytes for the `cwm-[` / `]` frame, plus one comma per joined part.
134
+ const wouldBe = 5 + (buf.length + 1) + bufLen + part.length
135
+ // 250 KiB: the largest `console.log` payload Workers Logs keeps untruncated.
136
+ if (buf.length > 0 && wouldBe > 250 * 1024) {
137
+ console.log(`cwm-[${buf.join(',')}]`)
138
+ buf = []
139
+ bufLen = 0
140
+ }
141
+ buf.push(part)
142
+ bufLen += part.length
143
+ }
144
+ if (buf.length) console.log(`cwm-[${buf.join(',')}]`)
145
+ },
146
+ gauge(name, value, tags) {
147
+ const merged = withGlobal(tags)
148
+ gauges.set(key(name, merged), { n: name, t: 'g', tags: merged, ts: 0, v: value })
149
+ },
150
+ histogram(name, value, tags) {
151
+ histograms.push({ n: name, t: 'h', tags: withGlobal(tags), ts: Date.now(), v: value })
152
+ },
153
+ }
154
+ }
package/src/Scope.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The issuable API-key scope vocabulary: the single source of truth for the
3
+ * `/scopes` catalog, for key minting (`ApiKeySource.Source.mint`), and for the scopes
4
+ * required by route policies (`Auth.policy`). Exposing it publicly lets operator
5
+ * tooling (e.g. the provisioning CLI) validate scopes against the same list the
6
+ * server enforces.
7
+ */
8
+
9
+ /**
10
+ * Wildcard scope. A key whose `scopes` contains this value satisfies every
11
+ * required scope, so it never needs re-provisioning when new scopes are added.
12
+ * Use sparingly — it grants full access.
13
+ */
14
+ export const wildcard = '*'
15
+
16
+ /** Catalog entry describing an issuable API-key scope. */
17
+ type Entry = {
18
+ /** Human-readable explanation of what the scope grants. */
19
+ description: string
20
+ /** Scope identifier used in a key's `scopes` and in route policies. */
21
+ scope: string
22
+ }
23
+
24
+ /**
25
+ * The issuable API-key scope vocabulary — the single source of truth for the
26
+ * `/scopes` catalog and for key minting. Route policies require values from this
27
+ * set; {@link wildcard} (`'*'`) is an implicit grant-all and is intentionally
28
+ * not listed as an issuable scope.
29
+ */
30
+ export const catalog = [
31
+ {
32
+ description: 'Read public chain data: tokens, transactions, transfers, blocks, and receipts.',
33
+ scope: 'data:read',
34
+ },
35
+ {
36
+ description: 'Run ad-hoc queries against the raw indexer passthrough.',
37
+ scope: 'indexer:query',
38
+ },
39
+ {
40
+ description: 'Read webhook subscriptions.',
41
+ scope: 'webhooks:read',
42
+ },
43
+ {
44
+ description: 'Create, update, and delete webhook subscriptions.',
45
+ scope: 'webhooks:write',
46
+ },
47
+ ] as const satisfies readonly Entry[]
48
+
49
+ /** Issuable API-key scope identifier — the union of every {@link catalog} entry. */
50
+ export type Id = (typeof catalog)[number]['scope']
@@ -0,0 +1,49 @@
1
+ import { Store, Webhooks } from 'cadent'
2
+
3
+ describe('createPoller', () => {
4
+ /** Decodes the opaque `(block, index)` keyset cursor the poller stores. */
5
+ function decodeCursor(token: string | null): [number, number] | null {
6
+ if (!token) return null
7
+ const json = atob(token.replaceAll('-', '+').replaceAll('_', '/'))
8
+ return JSON.parse(json) as [number, number]
9
+ }
10
+
11
+ test('binds a state store and runs a tick at an injected head', async () => {
12
+ const store = Store.memory()
13
+ const subscription = await Webhooks.createSubscription(store, {
14
+ chainId: 42431,
15
+ destination: { type: 'url', url: 'https://hooks.example.com/x' },
16
+ eventType: 'token:transfer',
17
+ owner: { orgId: 'org_test', type: 'api_key' },
18
+ })
19
+
20
+ const poller = Webhooks.createPoller({
21
+ defaultChainId: 42431,
22
+ webhook: { store },
23
+ })
24
+
25
+ // A brand-new subscription anchors at the confirmed head on its first tick
26
+ // (no backfill), so this exercises the createPoller → poll wiring (store
27
+ // binding, default chain id, injected head, result shape) without touching
28
+ // TIDX. Detailed poll/getIndexedHead behavior lives in
29
+ // src/apps/webhooks.test.ts.
30
+ const result = await poller.tick({ headBlockNumber: 200 })
31
+
32
+ expect(result).toMatchInlineSnapshot(`
33
+ {
34
+ "chainId": 42431,
35
+ "dispatched": 0,
36
+ "failed": 0,
37
+ "safeBlock": 198,
38
+ "scanned": 0,
39
+ "subscriptions": 1,
40
+ }
41
+ `)
42
+ expect(decodeCursor(await Webhooks.getCursor(store, subscription.id))).toMatchInlineSnapshot(`
43
+ [
44
+ 198,
45
+ 2147483647,
46
+ ]
47
+ `)
48
+ })
49
+ })
@@ -0,0 +1,172 @@
1
+ import * as AppWebhooks from './apps/webhooks.js'
2
+ import * as MetricSink from './internal/MetricSink.js'
3
+ import type * as Store from './internal/Store.js'
4
+ import type * as Metrics from './Metrics.js'
5
+ import * as Tidx from './internal/Tidx.js'
6
+ import * as Viem from './internal/Viem.js'
7
+
8
+ // Re-export the runtime-agnostic primitives (subscriptions, signing, delivery,
9
+ // `deliverAndRecord`, cursors, …) so consumers reach everything through one
10
+ // `Webhooks` namespace. The apps-layer poller stays private behind
11
+ // `createPoller` below.
12
+ export * from './internal/Webhooks.js'
13
+
14
+ // Re-export the webhook resource's zod schemas so consumers can validate and
15
+ // type delivery bodies: `Webhooks.schema.Envelope` (a discriminated union on
16
+ // `type`), plus the per-event `TransferEvent` / `TransactionEvent` / `PingEvent`
17
+ // payloads. Infer a type with `z.infer<typeof Webhooks.schema.Envelope>`.
18
+ export { eventTypes, schema } from './apps/webhooks.js'
19
+
20
+ /**
21
+ * Builds a scheduled webhook poller bound to a state store and chain config.
22
+ *
23
+ * This is the entry point a host runtime drives on a timer (a Cloudflare
24
+ * `scheduled` cron handler, a self-host `setInterval`, …). Each {@link
25
+ * Poller.tick} scans active subscriptions from their cursors up to `head -
26
+ * confirmations` and dispatches matching events.
27
+ *
28
+ * The monitoring event types (`log:emitted`, `block:created`,
29
+ * `transaction:included`) scan a confirmed window directly over JSON-RPC, so the
30
+ * poller builds memoized viem clients (via {@link Viem.getClient}); the legacy
31
+ * `token:transfer` type still reads from TIDX, so it
32
+ * also builds memoized TIDX clients (via {@link Tidx.createGetClient}) when a
33
+ * `tidx` config is supplied. The poller keeps `App.create` a pure Hono app: it
34
+ * constructs its own clients instead of reaching into app internals, and owns no
35
+ * request state.
36
+ */
37
+ export function createPoller(options: createPoller.Options): createPoller.Poller {
38
+ const { store } = options.webhook
39
+ const getTidx = options.tidx
40
+ ? Tidx.createGetClient({ defaultChainId: options.defaultChainId, tidx: options.tidx })
41
+ : undefined
42
+ const clients = new Map<number, Viem.getClient.ReturnType>()
43
+ const getClient = (chainId: Viem.ChainId) => {
44
+ let client = clients.get(chainId)
45
+ if (!client) {
46
+ client = Viem.getClient({ chainId, rpc: options.rpc })
47
+ clients.set(chainId, client)
48
+ }
49
+ return client
50
+ }
51
+
52
+ const metrics = options.metrics ? MetricSink.webhooks(options.metrics) : undefined
53
+
54
+ return {
55
+ async tick(input = {}) {
56
+ const chainId = input.chainId ?? options.defaultChainId ?? Viem.defaultChainId
57
+
58
+ // Wrap the transport so each enqueue (or inline delivery) emits a timed
59
+ // `webhook:enqueue` metric. The wrapper preserves the dispatch contract: it
60
+ // returns the underlying result unchanged and is a no-op when no metrics
61
+ // backend is configured.
62
+ const inner = input.dispatch ?? options.dispatch
63
+ const dispatch =
64
+ metrics && inner
65
+ ? async (dispatchable: AppWebhooks.poll.Dispatchable) => {
66
+ const start = Date.now()
67
+ const result = await inner(dispatchable)
68
+ metrics.record({
69
+ chainId: dispatchable.envelope.chainId,
70
+ durationMs: Date.now() - start,
71
+ eventType: dispatchable.envelope.type,
72
+ ok: result.ok,
73
+ type: 'webhook:enqueue',
74
+ })
75
+ return result
76
+ }
77
+ : inner
78
+
79
+ const start = Date.now()
80
+ try {
81
+ const result = await AppWebhooks.poll({
82
+ batchSize: input.batchSize ?? options.batchSize,
83
+ chainId,
84
+ client: getClient(chainId),
85
+ confirmations: input.confirmations ?? options.confirmations,
86
+ dispatch,
87
+ eventTypes: input.eventTypes ?? options.eventTypes,
88
+ ...(input.headBlockNumber === undefined
89
+ ? {}
90
+ : { headBlockNumber: input.headBlockNumber }),
91
+ maxBlocks: input.maxBlocks ?? options.maxBlocks,
92
+ now: input.now ?? options.now,
93
+ store,
94
+ ...(getTidx ? { tidx: getTidx(chainId) } : {}),
95
+ })
96
+ metrics?.record({
97
+ meta: { durationMs: Date.now() - start, outcome: 'ok' },
98
+ result,
99
+ type: 'webhook:tick',
100
+ })
101
+ return result
102
+ } catch (error) {
103
+ metrics?.record({
104
+ meta: { chainId, durationMs: Date.now() - start, outcome: 'error' },
105
+ result: undefined,
106
+ type: 'webhook:tick',
107
+ })
108
+ throw error
109
+ } finally {
110
+ metrics?.flush()
111
+ }
112
+ },
113
+ }
114
+ }
115
+
116
+ export declare namespace createPoller {
117
+ /** A row to dispatch, paired with its owning subscription. */
118
+ type Dispatchable = AppWebhooks.poll.Dispatchable
119
+
120
+ /** Delivery transport: hands a matched event to a queue or delivers inline. */
121
+ type Dispatch = NonNullable<AppWebhooks.poll.Options['dispatch']>
122
+
123
+ /** Summary counters returned by {@link Poller.tick}. */
124
+ type Result = AppWebhooks.poll.Result
125
+
126
+ /** Knobs shared by every {@link Poller.tick}; each is overridable per tick. */
127
+ type Defaults = {
128
+ /** Max matching rows scanned per subscription per tick (default 100). */
129
+ batchSize?: number | undefined
130
+ /** Reorg-safety window: only emit blocks this far behind head (default 2). */
131
+ confirmations?: number | undefined
132
+ /**
133
+ * Delivery transport. Defaults to inline `deliverAndRecord` (self-host); on
134
+ * Cloudflare pass a Queue producer so retry/backoff/DLQ are native.
135
+ */
136
+ dispatch?: Dispatch | undefined
137
+ /** Event types to poll (default all). */
138
+ eventTypes?: AppWebhooks.poll.Options['eventTypes']
139
+ /** Backfill cap: most blocks an RPC scanner inspects per tick (default 1000). */
140
+ maxBlocks?: number | undefined
141
+ /** Clock for envelope timestamps; injectable for tests. */
142
+ now?: (() => Date) | undefined
143
+ }
144
+
145
+ /** Options for {@link createPoller}. */
146
+ type Options = Defaults & {
147
+ /** Tempo chain id polled when a tick omits one. */
148
+ defaultChainId?: Viem.ChainId | undefined
149
+ /** Metrics backend; emits `webhook:tick` per tick and `webhook:enqueue` per dispatch. */
150
+ metrics?: Metrics.Metrics | undefined
151
+ /** RPC options for the viem clients the monitoring scanners read from. */
152
+ rpc?: Viem.getClient.Rpc | undefined
153
+ /** TIDX query client options for the legacy `token:transfer` type. */
154
+ tidx?: Tidx.getClient.Tidx | undefined
155
+ /** Webhook state store (subscriptions + cursors). */
156
+ webhook: { store: Store.State }
157
+ }
158
+
159
+ /** Per-tick overrides; falls back to the {@link Options} defaults. */
160
+ type TickOptions = Defaults & {
161
+ /** Chain to poll this tick (default `options.defaultChainId`). */
162
+ chainId?: Viem.ChainId | undefined
163
+ /** Chain head to work back from; resolved from RPC when omitted. */
164
+ headBlockNumber?: bigint | number | undefined
165
+ }
166
+
167
+ /** A scheduled webhook poller. */
168
+ type Poller = {
169
+ /** Runs one poll tick, resolving the indexed head when not supplied. */
170
+ tick(options?: TickOptions): Promise<Result>
171
+ }
172
+ }