tapimo 0.0.2 → 0.2.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 (517) hide show
  1. package/README.md +38 -16
  2. package/dist/ApiKey.d.ts +14 -11
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +11 -12
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +207 -0
  7. package/dist/ApiKeys.d.ts.map +1 -0
  8. package/dist/ApiKeys.js +282 -0
  9. package/dist/ApiKeys.js.map +1 -0
  10. package/dist/App.d.ts +6771 -3819
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +145 -317
  13. package/dist/App.js.map +1 -1
  14. package/dist/Handler.d.ts +86 -0
  15. package/dist/Handler.d.ts.map +1 -0
  16. package/dist/Handler.js +83 -0
  17. package/dist/Handler.js.map +1 -0
  18. package/dist/Scope.d.ts +14 -4
  19. package/dist/Scope.d.ts.map +1 -1
  20. package/dist/Scope.js +16 -4
  21. package/dist/Scope.js.map +1 -1
  22. package/dist/Webhooks.d.ts +5 -7
  23. package/dist/Webhooks.d.ts.map +1 -1
  24. package/dist/Webhooks.js +11 -4
  25. package/dist/Webhooks.js.map +1 -1
  26. package/dist/admin/Access.d.ts +1 -3
  27. package/dist/admin/Access.d.ts.map +1 -1
  28. package/dist/admin/Access.js +1 -3
  29. package/dist/admin/Access.js.map +1 -1
  30. package/dist/admin/App.d.ts +167 -205
  31. package/dist/admin/App.d.ts.map +1 -1
  32. package/dist/admin/App.js +2 -4
  33. package/dist/admin/App.js.map +1 -1
  34. package/dist/admin/apps/api-keys.d.ts +105 -5
  35. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  36. package/dist/admin/apps/api-keys.js +75 -9
  37. package/dist/admin/apps/api-keys.js.map +1 -1
  38. package/dist/admin/apps/scopes.d.ts +6 -0
  39. package/dist/admin/apps/scopes.d.ts.map +1 -1
  40. package/dist/admin/apps/verified-tokens.d.ts +35 -149
  41. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  42. package/dist/admin/apps/verified-tokens.js +18 -39
  43. package/dist/admin/apps/verified-tokens.js.map +1 -1
  44. package/dist/admin/ui.generated.d.ts +1 -1
  45. package/dist/admin/ui.generated.js +1 -1
  46. package/dist/apps/data/App.d.ts +19176 -0
  47. package/dist/apps/data/App.d.ts.map +1 -0
  48. package/dist/apps/data/App.js +236 -0
  49. package/dist/apps/data/App.js.map +1 -0
  50. package/dist/apps/data/index.d.ts +3 -0
  51. package/dist/apps/data/index.d.ts.map +1 -0
  52. package/dist/apps/data/index.js +3 -0
  53. package/dist/apps/data/index.js.map +1 -0
  54. package/dist/apps/{activities.d.ts → data/routes/activities.d.ts} +32 -32
  55. package/dist/apps/{activities.d.ts.map → data/routes/activities.d.ts.map} +1 -1
  56. package/dist/apps/{activities.js → data/routes/activities.js} +13 -13
  57. package/dist/apps/data/routes/activities.js.map +1 -0
  58. package/dist/apps/{addresses.d.ts → data/routes/addresses.d.ts} +22 -22
  59. package/dist/apps/{addresses.d.ts.map → data/routes/addresses.d.ts.map} +1 -1
  60. package/dist/apps/{addresses.js → data/routes/addresses.js} +5 -5
  61. package/dist/apps/data/routes/addresses.js.map +1 -0
  62. package/dist/apps/{balances.d.ts → data/routes/balances.d.ts} +49 -49
  63. package/dist/apps/data/routes/balances.d.ts.map +1 -0
  64. package/dist/apps/{balances.js → data/routes/balances.js} +42 -11
  65. package/dist/apps/data/routes/balances.js.map +1 -0
  66. package/dist/apps/{blocks.d.ts → data/routes/blocks.d.ts} +47 -47
  67. package/dist/apps/data/routes/blocks.d.ts.map +1 -0
  68. package/dist/apps/{blocks.js → data/routes/blocks.js} +13 -13
  69. package/dist/apps/data/routes/blocks.js.map +1 -0
  70. package/dist/apps/{coingecko.d.ts → data/routes/coingecko.d.ts} +183 -183
  71. package/dist/apps/data/routes/coingecko.d.ts.map +1 -0
  72. package/dist/apps/{coingecko.js → data/routes/coingecko.js} +13 -13
  73. package/dist/apps/data/routes/coingecko.js.map +1 -0
  74. package/dist/apps/{exchanges.d.ts → data/routes/exchanges.d.ts} +460 -460
  75. package/dist/apps/data/routes/exchanges.d.ts.map +1 -0
  76. package/dist/apps/{exchanges.js → data/routes/exchanges.js} +19 -19
  77. package/dist/apps/data/routes/exchanges.js.map +1 -0
  78. package/dist/apps/{fee-amm.d.ts → data/routes/fee-amm.d.ts} +94 -94
  79. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -0
  80. package/dist/apps/{fee-amm.js → data/routes/fee-amm.js} +17 -17
  81. package/dist/apps/data/routes/fee-amm.js.map +1 -0
  82. package/dist/apps/{indexer.d.ts → data/routes/indexer.d.ts} +4 -4
  83. package/dist/apps/data/routes/indexer.d.ts.map +1 -0
  84. package/dist/apps/{indexer.js → data/routes/indexer.js} +13 -9
  85. package/dist/apps/data/routes/indexer.js.map +1 -0
  86. package/dist/apps/{receipts.d.ts → data/routes/receipts.d.ts} +6 -6
  87. package/dist/apps/data/routes/receipts.d.ts.map +1 -0
  88. package/dist/apps/{receipts.js → data/routes/receipts.js} +12 -12
  89. package/dist/apps/data/routes/receipts.js.map +1 -0
  90. package/dist/apps/{rpc.d.ts → data/routes/rpc.d.ts} +4 -4
  91. package/dist/apps/data/routes/rpc.d.ts.map +1 -0
  92. package/dist/apps/{rpc.js → data/routes/rpc.js} +6 -6
  93. package/dist/apps/data/routes/rpc.js.map +1 -0
  94. package/dist/apps/{tokenlist.d.ts → data/routes/tokenlist.d.ts} +4 -4
  95. package/dist/apps/data/routes/tokenlist.d.ts.map +1 -0
  96. package/dist/apps/{tokenlist.js → data/routes/tokenlist.js} +8 -8
  97. package/dist/apps/data/routes/tokenlist.js.map +1 -0
  98. package/dist/apps/{tokens.d.ts → data/routes/tokens.d.ts} +11 -11
  99. package/dist/apps/data/routes/tokens.d.ts.map +1 -0
  100. package/dist/apps/{tokens.js → data/routes/tokens.js} +19 -19
  101. package/dist/apps/data/routes/tokens.js.map +1 -0
  102. package/dist/apps/{transactions.d.ts → data/routes/transactions.d.ts} +288 -288
  103. package/dist/apps/data/routes/transactions.d.ts.map +1 -0
  104. package/dist/apps/{transactions.js → data/routes/transactions.js} +13 -13
  105. package/dist/apps/data/routes/transactions.js.map +1 -0
  106. package/dist/apps/{transfers.d.ts → data/routes/transfers.d.ts} +35 -35
  107. package/dist/apps/data/routes/transfers.d.ts.map +1 -0
  108. package/dist/apps/{transfers.js → data/routes/transfers.js} +13 -13
  109. package/dist/apps/data/routes/transfers.js.map +1 -0
  110. package/dist/apps/{verified-tokens.d.ts → data/routes/verified-tokens.d.ts} +42 -42
  111. package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -0
  112. package/dist/apps/{verified-tokens.js → data/routes/verified-tokens.js} +9 -9
  113. package/dist/apps/data/routes/verified-tokens.js.map +1 -0
  114. package/dist/apps/{webhooks.d.ts → data/routes/webhooks.d.ts} +66 -63
  115. package/dist/apps/{webhooks.d.ts.map → data/routes/webhooks.d.ts.map} +1 -1
  116. package/dist/apps/{webhooks.js → data/routes/webhooks.js} +67 -59
  117. package/dist/apps/data/routes/webhooks.js.map +1 -0
  118. package/dist/apps/docs/App.d.ts +27 -0
  119. package/dist/apps/docs/App.d.ts.map +1 -0
  120. package/dist/apps/docs/App.js +122 -0
  121. package/dist/apps/docs/App.js.map +1 -0
  122. package/dist/{internal/OpenApi.fonts.d.ts → apps/docs/fonts.d.ts} +1 -1
  123. package/dist/apps/docs/fonts.d.ts.map +1 -0
  124. package/dist/{internal/OpenApi.fonts.js → apps/docs/fonts.js} +1 -1
  125. package/dist/apps/docs/fonts.js.map +1 -0
  126. package/dist/apps/docs/index.d.ts +2 -0
  127. package/dist/apps/docs/index.d.ts.map +1 -0
  128. package/dist/apps/docs/index.js +2 -0
  129. package/dist/apps/docs/index.js.map +1 -0
  130. package/dist/{internal/OpenApi.logo.d.ts → apps/docs/logo.d.ts} +1 -1
  131. package/dist/apps/docs/logo.d.ts.map +1 -0
  132. package/dist/{internal/OpenApi.logo.js → apps/docs/logo.js} +1 -1
  133. package/dist/apps/docs/logo.js.map +1 -0
  134. package/dist/apps/index.d.ts +4 -0
  135. package/dist/apps/index.d.ts.map +1 -0
  136. package/dist/apps/index.js +4 -0
  137. package/dist/apps/index.js.map +1 -0
  138. package/dist/apps/metadata.d.ts +7 -0
  139. package/dist/apps/metadata.d.ts.map +1 -0
  140. package/dist/apps/metadata.js +15 -0
  141. package/dist/apps/metadata.js.map +1 -0
  142. package/dist/apps/platform/App.d.ts +2985 -0
  143. package/dist/apps/platform/App.d.ts.map +1 -0
  144. package/dist/apps/platform/App.js +74 -0
  145. package/dist/apps/platform/App.js.map +1 -0
  146. package/dist/apps/platform/index.d.ts +2 -0
  147. package/dist/apps/platform/index.d.ts.map +1 -0
  148. package/dist/apps/platform/index.js +2 -0
  149. package/dist/apps/platform/index.js.map +1 -0
  150. package/dist/apps/platform/routes/api-keys.d.ts +681 -0
  151. package/dist/apps/platform/routes/api-keys.d.ts.map +1 -0
  152. package/dist/apps/platform/routes/api-keys.js +328 -0
  153. package/dist/apps/platform/routes/api-keys.js.map +1 -0
  154. package/dist/apps/platform/routes/invitations.d.ts +733 -0
  155. package/dist/apps/platform/routes/invitations.d.ts.map +1 -0
  156. package/dist/apps/platform/routes/invitations.js +413 -0
  157. package/dist/apps/platform/routes/invitations.js.map +1 -0
  158. package/dist/apps/platform/routes/me.d.ts +95 -0
  159. package/dist/apps/platform/routes/me.d.ts.map +1 -0
  160. package/dist/apps/platform/routes/me.js +81 -0
  161. package/dist/apps/platform/routes/me.js.map +1 -0
  162. package/dist/apps/platform/routes/members.d.ts +554 -0
  163. package/dist/apps/platform/routes/members.d.ts.map +1 -0
  164. package/dist/apps/platform/routes/members.js +251 -0
  165. package/dist/apps/platform/routes/members.js.map +1 -0
  166. package/dist/apps/platform/routes/orgs.d.ts +582 -0
  167. package/dist/apps/platform/routes/orgs.d.ts.map +1 -0
  168. package/dist/apps/platform/routes/orgs.js +265 -0
  169. package/dist/apps/platform/routes/orgs.js.map +1 -0
  170. package/dist/apps/platform/routes/projects.d.ts +740 -0
  171. package/dist/apps/platform/routes/projects.d.ts.map +1 -0
  172. package/dist/apps/platform/routes/projects.js +286 -0
  173. package/dist/apps/platform/routes/projects.js.map +1 -0
  174. package/dist/apps/relay/App.d.ts +41 -0
  175. package/dist/apps/relay/App.d.ts.map +1 -0
  176. package/dist/apps/relay/App.js +103 -0
  177. package/dist/apps/relay/App.js.map +1 -0
  178. package/dist/apps/relay/Sponsorships.d.ts +107 -0
  179. package/dist/apps/relay/Sponsorships.d.ts.map +1 -0
  180. package/dist/apps/relay/Sponsorships.js +193 -0
  181. package/dist/apps/relay/Sponsorships.js.map +1 -0
  182. package/dist/apps/relay/index.d.ts +3 -0
  183. package/dist/apps/relay/index.d.ts.map +1 -0
  184. package/dist/apps/relay/index.js +3 -0
  185. package/dist/apps/relay/index.js.map +1 -0
  186. package/dist/{Cli.d.ts → cli/Cli.d.ts} +13 -2
  187. package/dist/cli/Cli.d.ts.map +1 -0
  188. package/dist/cli/Cli.js +19 -0
  189. package/dist/cli/Cli.js.map +1 -0
  190. package/dist/cli/bin.d.ts +3 -0
  191. package/dist/cli/bin.d.ts.map +1 -0
  192. package/dist/cli/bin.js +4 -0
  193. package/dist/cli/bin.js.map +1 -0
  194. package/dist/cli/commands/admin.d.ts +15 -0
  195. package/dist/cli/commands/admin.d.ts.map +1 -0
  196. package/dist/cli/commands/admin.js +60 -0
  197. package/dist/cli/commands/admin.js.map +1 -0
  198. package/dist/cloudflare.d.ts +7 -0
  199. package/dist/cloudflare.d.ts.map +1 -1
  200. package/dist/cloudflare.js +9 -0
  201. package/dist/cloudflare.js.map +1 -1
  202. package/dist/db/Db.d.ts +113 -0
  203. package/dist/db/Db.d.ts.map +1 -0
  204. package/dist/db/Db.js +402 -0
  205. package/dist/db/Db.js.map +1 -0
  206. package/dist/db/Schema.d.ts +168 -0
  207. package/dist/db/Schema.d.ts.map +1 -0
  208. package/dist/db/Schema.js +229 -0
  209. package/dist/db/Schema.js.map +1 -0
  210. package/dist/db/tables/invitations.d.ts +84 -0
  211. package/dist/db/tables/invitations.d.ts.map +1 -0
  212. package/dist/db/tables/invitations.js +165 -0
  213. package/dist/db/tables/invitations.js.map +1 -0
  214. package/dist/db/tables/memberships.d.ts +108 -0
  215. package/dist/db/tables/memberships.d.ts.map +1 -0
  216. package/dist/db/tables/memberships.js +153 -0
  217. package/dist/db/tables/memberships.js.map +1 -0
  218. package/dist/db/tables/organizations.d.ts +123 -0
  219. package/dist/db/tables/organizations.d.ts.map +1 -0
  220. package/dist/db/tables/organizations.js +170 -0
  221. package/dist/db/tables/organizations.js.map +1 -0
  222. package/dist/db/tables/projects.d.ts +65 -0
  223. package/dist/db/tables/projects.d.ts.map +1 -0
  224. package/dist/db/tables/projects.js +75 -0
  225. package/dist/db/tables/projects.js.map +1 -0
  226. package/dist/db/tables/sponsoredTransactions.d.ts +120 -0
  227. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -0
  228. package/dist/db/tables/sponsoredTransactions.js +161 -0
  229. package/dist/db/tables/sponsoredTransactions.js.map +1 -0
  230. package/dist/db/tables/users.d.ts +48 -0
  231. package/dist/db/tables/users.d.ts.map +1 -0
  232. package/dist/db/tables/users.js +65 -0
  233. package/dist/db/tables/users.js.map +1 -0
  234. package/dist/db/tables/verifiedTokens.d.ts +53 -0
  235. package/dist/db/tables/verifiedTokens.d.ts.map +1 -0
  236. package/dist/db/tables/verifiedTokens.js +74 -0
  237. package/dist/db/tables/verifiedTokens.js.map +1 -0
  238. package/dist/db/tables/webhookDeliveries.d.ts +71 -0
  239. package/dist/db/tables/webhookDeliveries.d.ts.map +1 -0
  240. package/dist/db/tables/webhookDeliveries.js +119 -0
  241. package/dist/db/tables/webhookDeliveries.js.map +1 -0
  242. package/dist/db/tables/webhookSubscriptions.d.ts +158 -0
  243. package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -0
  244. package/dist/db/tables/webhookSubscriptions.js +272 -0
  245. package/dist/db/tables/webhookSubscriptions.js.map +1 -0
  246. package/dist/handlers/internal/executionError.d.ts +25 -0
  247. package/dist/handlers/internal/executionError.d.ts.map +1 -0
  248. package/dist/handlers/internal/executionError.js +186 -0
  249. package/dist/handlers/internal/executionError.js.map +1 -0
  250. package/dist/handlers/internal/multisig.d.ts +233 -0
  251. package/dist/handlers/internal/multisig.d.ts.map +1 -0
  252. package/dist/handlers/internal/multisig.js +542 -0
  253. package/dist/handlers/internal/multisig.js.map +1 -0
  254. package/dist/handlers/internal/requestListener.d.ts +124 -0
  255. package/dist/handlers/internal/requestListener.d.ts.map +1 -0
  256. package/dist/handlers/internal/requestListener.js +173 -0
  257. package/dist/handlers/internal/requestListener.js.map +1 -0
  258. package/dist/handlers/internal/sponsorship.d.ts +113 -0
  259. package/dist/handlers/internal/sponsorship.d.ts.map +1 -0
  260. package/dist/handlers/internal/sponsorship.js +128 -0
  261. package/dist/handlers/internal/sponsorship.js.map +1 -0
  262. package/dist/handlers/internal/types.d.ts +284 -0
  263. package/dist/handlers/internal/types.d.ts.map +1 -0
  264. package/dist/handlers/internal/types.js +2 -0
  265. package/dist/handlers/internal/types.js.map +1 -0
  266. package/dist/handlers/internal/utils.d.ts +34 -0
  267. package/dist/handlers/internal/utils.d.ts.map +1 -0
  268. package/dist/handlers/internal/utils.js +131 -0
  269. package/dist/handlers/internal/utils.js.map +1 -0
  270. package/dist/handlers/relay.d.ts +123 -0
  271. package/dist/handlers/relay.d.ts.map +1 -0
  272. package/dist/handlers/relay.js +1278 -0
  273. package/dist/handlers/relay.js.map +1 -0
  274. package/dist/index.d.ts +4 -2
  275. package/dist/index.d.ts.map +1 -1
  276. package/dist/index.js +4 -2
  277. package/dist/index.js.map +1 -1
  278. package/dist/internal/Auth.d.ts +224 -16
  279. package/dist/internal/Auth.d.ts.map +1 -1
  280. package/dist/internal/Auth.js +572 -33
  281. package/dist/internal/Auth.js.map +1 -1
  282. package/dist/internal/Log.d.ts +7 -3
  283. package/dist/internal/Log.d.ts.map +1 -1
  284. package/dist/internal/Log.js +4 -0
  285. package/dist/internal/Log.js.map +1 -1
  286. package/dist/internal/OpenApi.d.ts +0 -19
  287. package/dist/internal/OpenApi.d.ts.map +1 -1
  288. package/dist/internal/OpenApi.js +0 -57
  289. package/dist/internal/OpenApi.js.map +1 -1
  290. package/dist/internal/RpcSchema.d.ts +10 -0
  291. package/dist/internal/RpcSchema.d.ts.map +1 -0
  292. package/dist/internal/RpcSchema.js +2 -0
  293. package/dist/internal/RpcSchema.js.map +1 -0
  294. package/dist/internal/Store.d.ts +49 -4
  295. package/dist/internal/Store.d.ts.map +1 -1
  296. package/dist/internal/Store.js +81 -5
  297. package/dist/internal/Store.js.map +1 -1
  298. package/dist/internal/VerifiedTokens.d.ts +15 -34
  299. package/dist/internal/VerifiedTokens.d.ts.map +1 -1
  300. package/dist/internal/VerifiedTokens.js +115 -159
  301. package/dist/internal/VerifiedTokens.js.map +1 -1
  302. package/dist/internal/Viem.d.ts +84 -0
  303. package/dist/internal/Viem.d.ts.map +1 -1
  304. package/dist/internal/Webhooks.d.ts +50 -36
  305. package/dist/internal/Webhooks.d.ts.map +1 -1
  306. package/dist/internal/Webhooks.js +92 -205
  307. package/dist/internal/Webhooks.js.map +1 -1
  308. package/package.json +37 -6
  309. package/src/ApiKey.test.ts +3 -3
  310. package/src/ApiKey.ts +11 -12
  311. package/src/ApiKeys.test.ts +278 -0
  312. package/src/ApiKeys.ts +358 -0
  313. package/src/App.test-d.ts +1 -1
  314. package/src/App.test.ts +40508 -19083
  315. package/src/App.ts +239 -416
  316. package/src/Client.test-d.ts +307 -16
  317. package/src/Handler.ts +154 -0
  318. package/src/Scope.ts +17 -4
  319. package/src/Webhooks.test.ts +8 -7
  320. package/src/Webhooks.ts +13 -7
  321. package/src/admin/Access.ts +1 -3
  322. package/src/admin/App.ts +19 -24
  323. package/src/admin/apps/api-keys.test.ts +70 -18
  324. package/src/admin/apps/api-keys.ts +92 -9
  325. package/src/admin/apps/scopes.test.ts +8 -0
  326. package/src/admin/apps/verified-tokens.test.ts +3 -30
  327. package/src/admin/apps/verified-tokens.ts +18 -37
  328. package/src/admin/ui.generated.ts +1 -1
  329. package/src/apps/composition.test.ts +66 -0
  330. package/src/apps/data/App.ts +295 -0
  331. package/src/apps/data/index.ts +2 -0
  332. package/src/apps/{activities.test.ts → data/routes/activities.test.ts} +3 -3
  333. package/src/apps/{activities.ts → data/routes/activities.ts} +15 -15
  334. package/src/apps/{addresses.ts → data/routes/addresses.ts} +6 -6
  335. package/src/apps/{balances.test.ts → data/routes/balances.test.ts} +6 -5
  336. package/src/apps/{balances.ts → data/routes/balances.ts} +46 -12
  337. package/src/apps/{blocks.test.ts → data/routes/blocks.test.ts} +4 -4
  338. package/src/apps/{blocks.ts → data/routes/blocks.ts} +14 -14
  339. package/src/apps/{coingecko.test.ts → data/routes/coingecko.test.ts} +2 -2
  340. package/src/apps/{coingecko.ts → data/routes/coingecko.ts} +14 -14
  341. package/src/apps/{exchanges.test.ts → data/routes/exchanges.test.ts} +2 -2
  342. package/src/apps/{exchanges.ts → data/routes/exchanges.ts} +20 -20
  343. package/src/apps/{fee-amm.test.ts → data/routes/fee-amm.test.ts} +3 -3
  344. package/src/apps/{fee-amm.ts → data/routes/fee-amm.ts} +18 -18
  345. package/src/apps/{indexer.test.ts → data/routes/indexer.test.ts} +27 -6
  346. package/src/apps/{indexer.ts → data/routes/indexer.ts} +13 -10
  347. package/src/apps/{receipts.test.ts → data/routes/receipts.test.ts} +4 -4
  348. package/src/apps/{receipts.ts → data/routes/receipts.ts} +13 -13
  349. package/src/apps/{rpc.test.ts → data/routes/rpc.test.ts} +142 -13
  350. package/src/apps/{rpc.ts → data/routes/rpc.ts} +7 -7
  351. package/src/apps/{tokenlist.test.ts → data/routes/tokenlist.test.ts} +8 -10
  352. package/src/apps/{tokenlist.ts → data/routes/tokenlist.ts} +9 -9
  353. package/src/apps/{tokens.test.ts → data/routes/tokens.test.ts} +6 -5
  354. package/src/apps/{tokens.ts → data/routes/tokens.ts} +20 -20
  355. package/src/apps/{transactions.test.ts → data/routes/transactions.test.ts} +4 -4
  356. package/src/apps/{transactions.ts → data/routes/transactions.ts} +15 -15
  357. package/src/apps/{transfers.test.ts → data/routes/transfers.test.ts} +3 -3
  358. package/src/apps/{transfers.ts → data/routes/transfers.ts} +15 -15
  359. package/src/apps/{verified-tokens.test.ts → data/routes/verified-tokens.test.ts} +27 -15
  360. package/src/apps/{verified-tokens.ts → data/routes/verified-tokens.ts} +10 -10
  361. package/src/apps/{webhooks.test.ts → data/routes/webhooks.test.ts} +137 -150
  362. package/src/apps/{webhooks.ts → data/routes/webhooks.ts} +83 -81
  363. package/src/apps/docs/App.ts +136 -0
  364. package/src/apps/docs/index.ts +1 -0
  365. package/src/apps/index.ts +3 -0
  366. package/src/apps/metadata.ts +23 -0
  367. package/src/apps/platform/App.ts +130 -0
  368. package/src/apps/platform/index.ts +1 -0
  369. package/src/apps/platform/routes/api-keys.test.ts +330 -0
  370. package/src/apps/platform/routes/api-keys.ts +427 -0
  371. package/src/apps/platform/routes/invitations.test.ts +361 -0
  372. package/src/apps/platform/routes/invitations.ts +519 -0
  373. package/src/apps/platform/routes/me.test.ts +121 -0
  374. package/src/apps/platform/routes/me.ts +106 -0
  375. package/src/apps/platform/routes/members.test.ts +195 -0
  376. package/src/apps/platform/routes/members.ts +313 -0
  377. package/src/apps/platform/routes/orgs.test.ts +313 -0
  378. package/src/apps/platform/routes/orgs.ts +343 -0
  379. package/src/apps/platform/routes/projects.test.ts +181 -0
  380. package/src/apps/platform/routes/projects.ts +367 -0
  381. package/src/apps/relay/App.test.ts +484 -0
  382. package/src/apps/relay/App.ts +128 -0
  383. package/src/apps/relay/Sponsorships.test.ts +375 -0
  384. package/src/apps/relay/Sponsorships.ts +305 -0
  385. package/src/apps/relay/index.ts +2 -0
  386. package/src/{Cli.test.ts → cli/Cli.test.ts} +10 -9
  387. package/src/{Cli.ts → cli/Cli.ts} +16 -9
  388. package/src/cli/bin.ts +4 -0
  389. package/src/cli/commands/admin.test.ts +71 -0
  390. package/src/cli/commands/admin.ts +60 -0
  391. package/src/cloudflare.ts +10 -0
  392. package/src/db/Db.test.ts +84 -0
  393. package/src/db/Db.ts +542 -0
  394. package/src/db/Schema.ts +301 -0
  395. package/src/db/tables/invitations.ts +198 -0
  396. package/src/db/tables/memberships.ts +208 -0
  397. package/src/db/tables/organizations.test.ts +160 -0
  398. package/src/db/tables/organizations.ts +232 -0
  399. package/src/db/tables/projects.ts +107 -0
  400. package/src/db/tables/sponsoredTransactions.test.ts +218 -0
  401. package/src/db/tables/sponsoredTransactions.ts +236 -0
  402. package/src/db/tables/users.ts +85 -0
  403. package/src/db/tables/verifiedTokens.ts +111 -0
  404. package/src/db/tables/webhookDeliveries.ts +159 -0
  405. package/src/db/tables/webhookSubscriptions.ts +358 -0
  406. package/src/handlers/internal/executionError.ts +207 -0
  407. package/src/handlers/internal/multisig.test.ts +818 -0
  408. package/src/handlers/internal/multisig.ts +823 -0
  409. package/src/handlers/internal/requestListener.ts +273 -0
  410. package/src/handlers/internal/sponsorship.ts +245 -0
  411. package/src/handlers/internal/types.ts +378 -0
  412. package/src/handlers/internal/utils.ts +153 -0
  413. package/src/handlers/relay.test.ts +2035 -0
  414. package/src/handlers/relay.ts +1623 -0
  415. package/src/index.ts +4 -2
  416. package/src/internal/Auth.test.ts +337 -21
  417. package/src/internal/Auth.ts +783 -44
  418. package/src/internal/Cursor.test.ts +3 -2
  419. package/src/internal/Log.test.ts +1 -1
  420. package/src/internal/Log.ts +11 -3
  421. package/src/internal/MetricSink.ts +1 -1
  422. package/src/internal/OpenApi.ts +0 -59
  423. package/src/internal/RateLimit.test.ts +1 -1
  424. package/src/internal/RpcSchema.ts +10 -0
  425. package/src/internal/Store.test.ts +150 -10
  426. package/src/internal/Store.ts +136 -11
  427. package/src/internal/Tidx.local.test.ts +1 -1
  428. package/src/internal/VerifiedTokens.test.ts +99 -115
  429. package/src/internal/VerifiedTokens.ts +123 -175
  430. package/src/internal/WebhookDestination.test.ts +1 -1
  431. package/src/internal/Webhooks.test.ts +111 -111
  432. package/src/internal/Webhooks.ts +103 -221
  433. package/dist/ApiKeySource.d.ts +0 -166
  434. package/dist/ApiKeySource.d.ts.map +0 -1
  435. package/dist/ApiKeySource.js +0 -234
  436. package/dist/ApiKeySource.js.map +0 -1
  437. package/dist/Cli.d.ts.map +0 -1
  438. package/dist/Cli.js +0 -13
  439. package/dist/Cli.js.map +0 -1
  440. package/dist/apps/activities.js.map +0 -1
  441. package/dist/apps/addresses.js.map +0 -1
  442. package/dist/apps/balances.d.ts.map +0 -1
  443. package/dist/apps/balances.js.map +0 -1
  444. package/dist/apps/blocks.d.ts.map +0 -1
  445. package/dist/apps/blocks.js.map +0 -1
  446. package/dist/apps/coingecko.d.ts.map +0 -1
  447. package/dist/apps/coingecko.js.map +0 -1
  448. package/dist/apps/exchanges.d.ts.map +0 -1
  449. package/dist/apps/exchanges.js.map +0 -1
  450. package/dist/apps/fee-amm.d.ts.map +0 -1
  451. package/dist/apps/fee-amm.js.map +0 -1
  452. package/dist/apps/indexer.d.ts.map +0 -1
  453. package/dist/apps/indexer.js.map +0 -1
  454. package/dist/apps/receipts.d.ts.map +0 -1
  455. package/dist/apps/receipts.js.map +0 -1
  456. package/dist/apps/rpc.d.ts.map +0 -1
  457. package/dist/apps/rpc.js.map +0 -1
  458. package/dist/apps/tokenlist.d.ts.map +0 -1
  459. package/dist/apps/tokenlist.js.map +0 -1
  460. package/dist/apps/tokens.d.ts.map +0 -1
  461. package/dist/apps/tokens.js.map +0 -1
  462. package/dist/apps/transactions.d.ts.map +0 -1
  463. package/dist/apps/transactions.js.map +0 -1
  464. package/dist/apps/transfers.d.ts.map +0 -1
  465. package/dist/apps/transfers.js.map +0 -1
  466. package/dist/apps/verified-tokens.d.ts.map +0 -1
  467. package/dist/apps/verified-tokens.js.map +0 -1
  468. package/dist/apps/webhooks.js.map +0 -1
  469. package/dist/internal/OpenApi.fonts.d.ts.map +0 -1
  470. package/dist/internal/OpenApi.fonts.js.map +0 -1
  471. package/dist/internal/OpenApi.logo.d.ts.map +0 -1
  472. package/dist/internal/OpenApi.logo.js.map +0 -1
  473. package/seeds/31318/icons/0x20c0000000000000000000000000000000000000.svg +0 -1
  474. package/seeds/31318/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  475. package/seeds/31318/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  476. package/seeds/31318/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  477. package/seeds/31318/verified-tokens.json +0 -30
  478. package/seeds/4217/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  479. package/seeds/4217/icons/0x20c000000000000000000000048c8f36df1c9a4a.svg +0 -1
  480. package/seeds/4217/icons/0x20c0000000000000000000000520792dcccccccc.svg +0 -1
  481. package/seeds/4217/icons/0x20c0000000000000000000000a6da882d075a4c3.svg +0 -4
  482. package/seeds/4217/icons/0x20c000000000000000000000111111111e910f0f.svg +0 -30
  483. package/seeds/4217/icons/0x20c00000000000000000000014f22ca97301eb73.svg +0 -1
  484. package/seeds/4217/icons/0x20c0000000000000000000001621e21f71cf12fb.svg +0 -1
  485. package/seeds/4217/icons/0x20c0000000000000000000002f52d5cc21a3207b.svg +0 -1
  486. package/seeds/4217/icons/0x20c0000000000000000000003158081efd85bfc2.svg +0 -11
  487. package/seeds/4217/icons/0x20c0000000000000000000003554d28269e0f3c2.svg +0 -1
  488. package/seeds/4217/icons/0x20c000000000000000000000383a23bacb546ab9.svg +0 -1
  489. package/seeds/4217/icons/0x20c00000000000000000000042109aef2f8b28e1.png +0 -0
  490. package/seeds/4217/icons/0x20c0000000000000000000005c0bac7cef389a11.svg +0 -1
  491. package/seeds/4217/icons/0x20c0000000000000000000006fd9a167923ba194.png +0 -0
  492. package/seeds/4217/icons/0x20c0000000000000000000007f7ba549dd0251b9.svg +0 -1
  493. package/seeds/4217/icons/0x20c0000000000000000000008191667423f70e67.svg +0 -5
  494. package/seeds/4217/icons/0x20c0000000000000000000008ee4fcff88888888.svg +0 -1
  495. package/seeds/4217/icons/0x20c0000000000000000000009a4a4b17e0dc6651.svg +0 -1
  496. package/seeds/4217/icons/0x20c000000000000000000000ab02d39df30bd17e.svg +0 -1
  497. package/seeds/4217/icons/0x20c000000000000000000000ae247a1130450f09.svg +0 -1
  498. package/seeds/4217/icons/0x20c000000000000000000000aeed2ec36a54d0e5.svg +0 -1
  499. package/seeds/4217/icons/0x20c000000000000000000000b9537d11c60e8b50.svg +0 -1
  500. package/seeds/4217/icons/0x20c000000000000000000000bd95bfb69fbe6ce3.svg +0 -1
  501. package/seeds/4217/icons/0x20c000000000000000000000c412ec89d0c08be5.svg +0 -1
  502. package/seeds/4217/icons/0x20c000000000000000000000f047dd7018e50367.png +0 -0
  503. package/seeds/4217/verified-tokens.json +0 -177
  504. package/seeds/42431/icons/0x20c0000000000000000000000000000000000000.svg +0 -25
  505. package/seeds/42431/icons/0x20c0000000000000000000000000000000000001.svg +0 -1
  506. package/seeds/42431/icons/0x20c0000000000000000000000000000000000002.svg +0 -1
  507. package/seeds/42431/icons/0x20c0000000000000000000000000000000000003.svg +0 -1
  508. package/seeds/42431/icons/0x20c0000000000000000000009e8d7eb59b783726.svg +0 -1
  509. package/seeds/42431/icons/0x20c000000000000000000000d72572838bbee59c.svg +0 -1
  510. package/seeds/42431/verified-tokens.json +0 -44
  511. package/seeds/openrpc/README.md +0 -27
  512. package/seeds/openrpc/execution-apis.json +0 -8989
  513. package/src/ApiKeySource.test-d.ts +0 -11
  514. package/src/ApiKeySource.test.ts +0 -295
  515. package/src/ApiKeySource.ts +0 -303
  516. /package/src/{internal/OpenApi.fonts.ts → apps/docs/fonts.ts} +0 -0
  517. /package/src/{internal/OpenApi.logo.ts → apps/docs/logo.ts} +0 -0
@@ -2,19 +2,20 @@ import { type Context, Hono } from 'hono'
2
2
  import { type AbiEvent, parseAbiItem } from 'viem'
3
3
  import * as z from 'zod/mini'
4
4
 
5
- import type * as App from '../App.js'
6
- import * as Auth from '../internal/Auth.js'
7
- import * as Cache from '../internal/Cache.js'
8
- import * as Cursor from '../internal/Cursor.js'
9
- import * as OpenApi from '../internal/OpenApi.js'
10
- import * as Response from '../internal/Response.js'
11
- import * as Schema from '../internal/Schema.js'
12
- import * as Store from '../internal/Store.js'
13
- import type * as Tidx from '../internal/Tidx.js'
14
- import * as Ttl from '../internal/Ttl.js'
15
- import * as Value from '../internal/Value.js'
16
- import type * as Viem from '../internal/Viem.js'
17
- import * as Webhooks from '../internal/Webhooks.js'
5
+ import type * as App from '../../../App.js'
6
+ import * as Auth from '../../../internal/Auth.js'
7
+ import * as Cache from '../../../internal/Cache.js'
8
+ import * as Cursor from '../../../internal/Cursor.js'
9
+ import * as Db from '../../../db/Db.js'
10
+ import * as OpenApi from '../../../internal/OpenApi.js'
11
+ import * as Response from '../../../internal/Response.js'
12
+ import * as Schema from '../../../internal/Schema.js'
13
+ import * as Store from '../../../internal/Store.js'
14
+ import type * as Tidx from '../../../internal/Tidx.js'
15
+ import * as Ttl from '../../../internal/Ttl.js'
16
+ import * as Value from '../../../internal/Value.js'
17
+ import type * as Viem from '../../../internal/Viem.js'
18
+ import * as Webhooks from '../../../internal/Webhooks.js'
18
19
  import * as Receipts from './receipts.js'
19
20
  import * as Transactions from './transactions.js'
20
21
  import * as Transfers from './transfers.js'
@@ -377,7 +378,7 @@ export namespace schema {
377
378
  .record(z.string(), z.unknown())
378
379
  .check(
379
380
  z.describe(
380
- 'Match decoded event arguments by name (indexed or non-indexed). Requires `signature`. Each value is an exact value or an operator object.',
381
+ 'Match decoded event arguments by name (indexed or non-indexed). Requires `signature`. Each value is an exact value or a super admin object.',
381
382
  ),
382
383
  z.meta({ examples: [{ to: '0x9e39034aae71fb89f66061a2602eb6efec271754' }] }),
383
384
  ),
@@ -1224,21 +1225,25 @@ export namespace schema {
1224
1225
  */
1225
1226
  export function webhooks(options: webhooks.Options = {}) {
1226
1227
  const hidden = !options.enabled
1227
- return (
1228
- new Hono<App.Environment>()
1229
- .use('*', async (c, next) => {
1230
- // Gate the whole resource on a configured state store. Without it the
1231
- // outbound-HTTP surface is disabled (read-only deployment).
1232
- if (!c.get('webhook')) return notEnabled(c) as never
1228
+ // Gate the whole resource on a configured state store. Without it the
1229
+ // outbound-HTTP surface is disabled (read-only deployment).
1230
+ const gate = async (c: Context<App.Environment>, next: () => Promise<void>) => {
1231
+ if (!c.get('webhook')) return notEnabled(c) as never
1233
1232
 
1234
- await next()
1233
+ await next()
1235
1234
 
1236
- // Subscriptions are principal-scoped, mutating, and stateful: never cache.
1237
- if (!c.res.headers.has('Cache-Control')) c.res.headers.set('Cache-Control', 'no-store')
1238
- return
1239
- })
1235
+ // Subscriptions are principal-scoped, mutating, and stateful: never cache.
1236
+ if (!c.res.headers.has('Cache-Control')) c.res.headers.set('Cache-Control', 'no-store')
1237
+ return
1238
+ }
1239
+ return (
1240
+ new Hono<App.Environment>()
1241
+ // `/v1/webhooks/*` does not match the collection root, so it gets its
1242
+ // own registration.
1243
+ .use('/v1/webhooks', gate)
1244
+ .use('/v1/webhooks/*', gate)
1240
1245
  .get(
1241
- '/event-types',
1246
+ '/v1/webhooks/event-types',
1242
1247
  Auth.policy({ apiKey: { scopes: ['data:read'] }, mpp: true, public: true }),
1243
1248
  OpenApi.describeRoute({
1244
1249
  description: 'See which onchain event types Tempo can POST to your webhook URL.',
@@ -1274,7 +1279,7 @@ export function webhooks(options: webhooks.Options = {}) {
1274
1279
  },
1275
1280
  )
1276
1281
  .post(
1277
- '/',
1282
+ '/v1/webhooks',
1278
1283
  Auth.policy({ apiKey: { scopes: ['webhooks:write'] } }),
1279
1284
  OpenApi.validate('json', schema.createWebhook.Body, {
1280
1285
  code: 'body_invalid',
@@ -1306,7 +1311,7 @@ export function webhooks(options: webhooks.Options = {}) {
1306
1311
  })
1307
1312
 
1308
1313
  const webhook = c.get('webhook')!
1309
- const store = webhook.store
1314
+ const db = Db.get(c.get('db'))
1310
1315
  const owner = ownerFor(c)
1311
1316
  if (!owner) return unauthorized(c)
1312
1317
 
@@ -1315,7 +1320,7 @@ export function webhooks(options: webhooks.Options = {}) {
1315
1320
 
1316
1321
  try {
1317
1322
  const subscription = await Webhooks.createSubscription(
1318
- store,
1323
+ db,
1319
1324
  {
1320
1325
  chainId,
1321
1326
  ...(body.context === undefined ? {} : { context: body.context }),
@@ -1337,7 +1342,7 @@ export function webhooks(options: webhooks.Options = {}) {
1337
1342
  },
1338
1343
  )
1339
1344
  .get(
1340
- '/',
1345
+ '/v1/webhooks',
1341
1346
  Auth.policy({ apiKey: { scopes: ['webhooks:read'] } }),
1342
1347
  OpenApi.validate('query', schema.listWebhooks.Query, {
1343
1348
  code: 'query_invalid',
@@ -1365,7 +1370,7 @@ export function webhooks(options: webhooks.Options = {}) {
1365
1370
  message: 'Check the query parameters and try again.',
1366
1371
  })
1367
1372
 
1368
- const store = c.get('webhook')!.store
1373
+ const db = Db.get(c.get('db'))
1369
1374
  const owner = ownerFor(c)
1370
1375
  if (!owner) return unauthorized(c)
1371
1376
 
@@ -1375,12 +1380,12 @@ export function webhooks(options: webhooks.Options = {}) {
1375
1380
  // run it concurrently with the page list. Best-effort: a failure
1376
1381
  // omits `meta` rather than failing the page.
1377
1382
  const countPromise = include.includes('totalCount')
1378
- ? Webhooks.countSubscriptions(store, owner).catch(() => undefined)
1383
+ ? Webhooks.countSubscriptions(db, owner).catch(() => undefined)
1379
1384
  : undefined
1380
1385
 
1381
1386
  // Fetch one extra to detect a further page without a second round-trip.
1382
1387
  // `page` translates to a positional slice of `(page - 1) * limit` rows.
1383
- const rows = await Webhooks.listSubscriptions(store, owner, {
1388
+ const rows = await Webhooks.listSubscriptions(db, owner, {
1384
1389
  cursor,
1385
1390
  limit: limit + 1,
1386
1391
  offset: page !== undefined && page > 1 ? (page - 1) * limit : undefined,
@@ -1411,7 +1416,7 @@ export function webhooks(options: webhooks.Options = {}) {
1411
1416
  // constraint, this API-key-only route's policy would be collected for the
1412
1417
  // event-types request and override its (intentionally public) access.
1413
1418
  .get(
1414
- '/:id{wh_[A-Za-z0-9_-]+}',
1419
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}',
1415
1420
  Auth.policy({ apiKey: { scopes: ['webhooks:read'] } }),
1416
1421
  OpenApi.validate('param', schema.getWebhook.Params, {
1417
1422
  code: 'param_invalid',
@@ -1445,13 +1450,13 @@ export function webhooks(options: webhooks.Options = {}) {
1445
1450
  message: 'Check the path parameters and try again.',
1446
1451
  })
1447
1452
 
1448
- const store = c.get('webhook')!.store
1453
+ const db = Db.get(c.get('db'))
1449
1454
  const owner = ownerFor(c)
1450
1455
  if (!owner) return unauthorized(c)
1451
1456
 
1452
1457
  const { id } = c.req.valid('param')
1453
1458
  try {
1454
- const subscription = await Webhooks.getSubscription(store, owner, id)
1459
+ const subscription = await Webhooks.getSubscription(db, owner, id)
1455
1460
  if (!subscription) return notFound(c)
1456
1461
  return c.json(
1457
1462
  Response.validated(schema.getWebhook.Response, toPublic(subscription)),
@@ -1463,7 +1468,7 @@ export function webhooks(options: webhooks.Options = {}) {
1463
1468
  },
1464
1469
  )
1465
1470
  .get(
1466
- '/:id{wh_[A-Za-z0-9_-]+}/deliveries',
1471
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}/deliveries',
1467
1472
  Auth.policy({ apiKey: { scopes: ['webhooks:read'] } }),
1468
1473
  OpenApi.validate('param', schema.listWebhookDeliveries.Params, {
1469
1474
  code: 'param_invalid',
@@ -1506,7 +1511,7 @@ export function webhooks(options: webhooks.Options = {}) {
1506
1511
  message: 'Check the query parameters and try again.',
1507
1512
  })
1508
1513
 
1509
- const store = c.get('webhook')!.store
1514
+ const db = Db.get(c.get('db'))
1510
1515
  const owner = ownerFor(c)
1511
1516
  if (!owner) return unauthorized(c)
1512
1517
 
@@ -1515,19 +1520,19 @@ export function webhooks(options: webhooks.Options = {}) {
1515
1520
  try {
1516
1521
  // Owner-scope first: resolving the subscription under the caller's owner
1517
1522
  // key 404s ids they don't own (indistinguishable from "doesn't exist").
1518
- const subscription = await Webhooks.getSubscription(store, owner, id)
1523
+ const subscription = await Webhooks.getSubscription(db, owner, id)
1519
1524
  if (!subscription) return notFound(c)
1520
1525
 
1521
1526
  // `totalCount` is opt-in and exact (the delivery log is TTL-bounded);
1522
1527
  // run it concurrently with the page list. Best-effort: a failure
1523
1528
  // omits `meta` rather than failing the page.
1524
1529
  const countPromise = include.includes('totalCount')
1525
- ? Webhooks.countDeliveries(store, id).catch(() => undefined)
1530
+ ? Webhooks.countDeliveries(db, id).catch(() => undefined)
1526
1531
  : undefined
1527
1532
 
1528
1533
  // Fetch one extra to detect a further page without a second round-trip.
1529
1534
  // `page` translates to a positional slice of `(page - 1) * limit` rows.
1530
- const rows = await Webhooks.listDeliveries(store, id, {
1535
+ const rows = await Webhooks.listDeliveries(db, id, {
1531
1536
  cursor,
1532
1537
  limit: limit + 1,
1533
1538
  offset: page !== undefined && page > 1 ? (page - 1) * limit : undefined,
@@ -1554,7 +1559,7 @@ export function webhooks(options: webhooks.Options = {}) {
1554
1559
  },
1555
1560
  )
1556
1561
  .post(
1557
- '/:id{wh_[A-Za-z0-9_-]+}/ping',
1562
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}/ping',
1558
1563
  Auth.policy({ apiKey: { scopes: ['webhooks:write'] } }),
1559
1564
  OpenApi.validate('param', schema.pingWebhook.Params, {
1560
1565
  code: 'param_invalid',
@@ -1589,20 +1594,20 @@ export function webhooks(options: webhooks.Options = {}) {
1589
1594
  message: 'Check the path parameters and try again.',
1590
1595
  })
1591
1596
 
1592
- const store = c.get('webhook')!.store
1597
+ const db = Db.get(c.get('db'))
1593
1598
  const owner = ownerFor(c)
1594
1599
  if (!owner) return unauthorized(c)
1595
1600
 
1596
1601
  const { id } = c.req.valid('param')
1597
1602
  try {
1598
1603
  // Owner-scope first so unowned/unknown ids are indistinguishable (404).
1599
- const subscription = await Webhooks.getSubscription(store, owner, id)
1604
+ const subscription = await Webhooks.getSubscription(db, owner, id)
1600
1605
  if (!subscription) return notFound(c)
1601
1606
 
1602
1607
  // Inline delivery (not the queue) so the caller gets an immediate
1603
1608
  // result. `ping` never mutates the subscription's failure/lifecycle
1604
1609
  // state — a test must not disable a healthy endpoint.
1605
- const { envelope, result } = await Webhooks.ping(store, subscription)
1610
+ const { envelope, result } = await Webhooks.ping(db, subscription)
1606
1611
  return c.json(
1607
1612
  Response.validated(schema.pingWebhook.Response, {
1608
1613
  delivered: result.ok,
@@ -1619,7 +1624,7 @@ export function webhooks(options: webhooks.Options = {}) {
1619
1624
  },
1620
1625
  )
1621
1626
  .post(
1622
- '/:id{wh_[A-Za-z0-9_-]+}/deliveries/:deliveryId/retry',
1627
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}/deliveries/:deliveryId/retry',
1623
1628
  Auth.policy({ apiKey: { scopes: ['webhooks:write'] } }),
1624
1629
  OpenApi.validate('param', schema.retryWebhookDelivery.Params, {
1625
1630
  code: 'param_invalid',
@@ -1653,17 +1658,17 @@ export function webhooks(options: webhooks.Options = {}) {
1653
1658
  message: 'Check the path parameters and try again.',
1654
1659
  })
1655
1660
 
1656
- const store = c.get('webhook')!.store
1661
+ const db = Db.get(c.get('db'))
1657
1662
  const owner = ownerFor(c)
1658
1663
  if (!owner) return unauthorized(c)
1659
1664
 
1660
1665
  const { deliveryId, id } = c.req.valid('param')
1661
1666
  try {
1662
1667
  // Owner-scope the subscription first so unowned ids 404 like elsewhere.
1663
- const subscription = await Webhooks.getSubscription(store, owner, id)
1668
+ const subscription = await Webhooks.getSubscription(db, owner, id)
1664
1669
  if (!subscription) return notFound(c)
1665
1670
 
1666
- const delivery = await Webhooks.getDelivery(store, id, deliveryId)
1671
+ const delivery = await Webhooks.getDelivery(db, id, deliveryId)
1667
1672
  if (!delivery)
1668
1673
  return Response.error(c, {
1669
1674
  code: 'delivery_not_found',
@@ -1673,7 +1678,7 @@ export function webhooks(options: webhooks.Options = {}) {
1673
1678
 
1674
1679
  // Replay the exact persisted envelope inline. Unlike `ping`, this is a
1675
1680
  // real event, so the outcome updates the subscription's failure state.
1676
- const result = await Webhooks.deliverAndRecord(store, subscription, delivery.envelope)
1681
+ const result = await Webhooks.deliverAndRecord(db, subscription, delivery.envelope)
1677
1682
  return c.json(
1678
1683
  Response.validated(schema.retryWebhookDelivery.Response, {
1679
1684
  delivered: result.ok,
@@ -1690,7 +1695,7 @@ export function webhooks(options: webhooks.Options = {}) {
1690
1695
  },
1691
1696
  )
1692
1697
  .patch(
1693
- '/:id{wh_[A-Za-z0-9_-]+}',
1698
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}',
1694
1699
  Auth.policy({ apiKey: { scopes: ['webhooks:write'] } }),
1695
1700
  OpenApi.validate('param', schema.updateWebhook.Params, {
1696
1701
  code: 'param_invalid',
@@ -1733,7 +1738,7 @@ export function webhooks(options: webhooks.Options = {}) {
1733
1738
  message: 'Check the request body and try again.',
1734
1739
  })
1735
1740
 
1736
- const store = c.get('webhook')!.store
1741
+ const db = Db.get(c.get('db'))
1737
1742
  const owner = ownerFor(c)
1738
1743
  if (!owner) return unauthorized(c)
1739
1744
 
@@ -1746,11 +1751,11 @@ export function webhooks(options: webhooks.Options = {}) {
1746
1751
  // persisting — otherwise a bad filter would silently widen the match
1747
1752
  // set at scan time.
1748
1753
  if (patch.filters !== undefined) {
1749
- const existing = await Webhooks.getSubscription(store, owner, id)
1754
+ const existing = await Webhooks.getSubscription(db, owner, id)
1750
1755
  if (!existing) return notFound(c)
1751
1756
  parseFilters(existing.eventType, patch.filters)
1752
1757
  }
1753
- const subscription = await Webhooks.updateSubscription(store, owner, id, patch)
1758
+ const subscription = await Webhooks.updateSubscription(db, owner, id, patch)
1754
1759
  if (!subscription) return notFound(c)
1755
1760
  return c.json(
1756
1761
  Response.validated(schema.updateWebhook.Response, toPublic(subscription)),
@@ -1762,7 +1767,7 @@ export function webhooks(options: webhooks.Options = {}) {
1762
1767
  },
1763
1768
  )
1764
1769
  .delete(
1765
- '/:id{wh_[A-Za-z0-9_-]+}',
1770
+ '/v1/webhooks/:id{wh_[A-Za-z0-9_-]+}',
1766
1771
  Auth.policy({ apiKey: { scopes: ['webhooks:write'] } }),
1767
1772
  OpenApi.validate('param', schema.deleteWebhook.Params, {
1768
1773
  code: 'param_invalid',
@@ -1796,13 +1801,13 @@ export function webhooks(options: webhooks.Options = {}) {
1796
1801
  message: 'Check the path parameters and try again.',
1797
1802
  })
1798
1803
 
1799
- const store = c.get('webhook')!.store
1804
+ const db = Db.get(c.get('db'))
1800
1805
  const owner = ownerFor(c)
1801
1806
  if (!owner) return unauthorized(c)
1802
1807
 
1803
1808
  const { id } = c.req.valid('param')
1804
1809
  try {
1805
- const deleted = await Webhooks.deleteSubscription(store, owner, id)
1810
+ const deleted = await Webhooks.deleteSubscription(db, owner, id)
1806
1811
  if (!deleted) return notFound(c)
1807
1812
  return c.json(Response.validated(schema.deleteWebhook.Response, { id }), 200)
1808
1813
  } catch (cause) {
@@ -1874,12 +1879,13 @@ type ScanPage = {
1874
1879
  export async function poll(options: poll.Options): Promise<poll.Result> {
1875
1880
  const {
1876
1881
  batchSize = 100,
1882
+ cache: cache_metadata = Store.memory(),
1877
1883
  chainId,
1878
1884
  client,
1879
1885
  confirmations = 2,
1886
+ db,
1880
1887
  eventTypes = ['token:transfer', 'transaction:included', 'log:emitted', 'block:created'],
1881
1888
  maxBlocks = 1_000,
1882
- store,
1883
1889
  tidx,
1884
1890
  } = options
1885
1891
  const now = options.now ?? (() => new Date())
@@ -1888,7 +1894,7 @@ export async function poll(options: poll.Options): Promise<poll.Result> {
1888
1894
  // Queue producer instead and the consumer runs `deliverAndRecord`.
1889
1895
  const dispatch =
1890
1896
  options.dispatch ??
1891
- (({ envelope, subscription }) => Webhooks.deliverAndRecord(store, subscription, envelope))
1897
+ (({ envelope, subscription }) => Webhooks.deliverAndRecord(db, subscription, envelope))
1892
1898
 
1893
1899
  // Head resolution is lazy and per-source. RPC types work back from the live
1894
1900
  // RPC head; the legacy TIDX types from the indexed head (never ahead of the
@@ -1901,6 +1907,9 @@ export async function poll(options: poll.Options): Promise<poll.Result> {
1901
1907
  (tidxHead ??= tidx ? await getIndexedHead(tidx, chainId) : await resolveRpcHead())
1902
1908
 
1903
1909
  const rpcSafeBlock = Math.max(0, (await resolveRpcHead()) - confirmations)
1910
+ // Reclaim expired rows (MPP-owned subscriptions, aged delivery logs) once
1911
+ // per tick; reads filter expiry at query time, so this is hygiene only.
1912
+ await Webhooks.pruneExpired(db, { now }).catch(() => {})
1904
1913
  // Per-tick lazy cache so multiple subscriptions of the same/related types
1905
1914
  // share fetched blocks and receipts instead of refetching the same window.
1906
1915
  const cache = createChainCache(client)
@@ -1916,19 +1925,15 @@ export async function poll(options: poll.Options): Promise<poll.Result> {
1916
1925
  for (const eventType of eventTypes) {
1917
1926
  const legacy = eventType === 'token:transfer'
1918
1927
  const safeBlock = legacy ? Math.max(0, (await resolveTidxHead()) - confirmations) : rpcSafeBlock
1919
- const subscriptions = await Webhooks.listActive(store, chainId, eventType)
1928
+ const subscriptions = await Webhooks.listActive(db, chainId, eventType)
1920
1929
  for (const subscription of subscriptions) {
1921
1930
  result.subscriptions++
1922
- const cursor = await Webhooks.getCursor(store, subscription.id)
1931
+ const cursor = await Webhooks.getCursor(db, subscription.id)
1923
1932
  if (cursor === null) {
1924
1933
  // First time we've seen this subscription: anchor it at the head of the
1925
1934
  // confirmed window so we never backfill from genesis. Events start
1926
1935
  // flowing from the next tick onward.
1927
- await Webhooks.setCursor(
1928
- store,
1929
- subscription.id,
1930
- Cursor.encode([safeBlock, endOfBlockIndex]),
1931
- )
1936
+ await Webhooks.setCursor(db, subscription.id, Cursor.encode([safeBlock, endOfBlockIndex]))
1932
1937
  continue
1933
1938
  }
1934
1939
  const page = await scanSubscription({
@@ -1951,7 +1956,7 @@ export async function poll(options: poll.Options): Promise<poll.Result> {
1951
1956
  // payloads) can render `amount` in token units. Non-fatal on failure.
1952
1957
  const data =
1953
1958
  eventType === 'token:transfer'
1954
- ? await withTokenMetadata(item.data, { chainId, client, store })
1959
+ ? await withTokenMetadata(item.data, { cache: cache_metadata, chainId, client })
1955
1960
  : item.data
1956
1961
  const envelope = Webhooks.buildEnvelope({
1957
1962
  blockNumber: item.cursor[0],
@@ -1976,21 +1981,16 @@ export async function poll(options: poll.Options): Promise<poll.Result> {
1976
1981
  // matches); keyset scanners advance past the last dispatched row, or — on
1977
1982
  // a complete empty page — to the end of the confirmed window.
1978
1983
  if (failed) {
1979
- if (accepted) await Webhooks.setCursor(store, subscription.id, Cursor.encode([...accepted]))
1984
+ if (accepted) await Webhooks.setCursor(db, subscription.id, Cursor.encode([...accepted]))
1980
1985
  } else if (page.scannedThrough !== undefined)
1981
1986
  await Webhooks.setCursor(
1982
- store,
1987
+ db,
1983
1988
  subscription.id,
1984
1989
  Cursor.encode([page.scannedThrough, endOfBlockIndex]),
1985
1990
  )
1986
- else if (accepted)
1987
- await Webhooks.setCursor(store, subscription.id, Cursor.encode([...accepted]))
1991
+ else if (accepted) await Webhooks.setCursor(db, subscription.id, Cursor.encode([...accepted]))
1988
1992
  else if (!page.hasMore)
1989
- await Webhooks.setCursor(
1990
- store,
1991
- subscription.id,
1992
- Cursor.encode([safeBlock, endOfBlockIndex]),
1993
- )
1993
+ await Webhooks.setCursor(db, subscription.id, Cursor.encode([safeBlock, endOfBlockIndex]))
1994
1994
  }
1995
1995
  }
1996
1996
 
@@ -2009,12 +2009,16 @@ export declare namespace poll {
2009
2009
  type Options = {
2010
2010
  /** Max matching rows scanned per subscription per tick (default 100). */
2011
2011
  batchSize?: number | undefined
2012
+ /** Cache store for the token-metadata memoize (defaults to a fresh in-memory store; pass a persistent one to share lookups across ticks). */
2013
+ cache?: Store.Store | undefined
2012
2014
  /** Chain to poll. Callers loop over chains. */
2013
2015
  chainId: number
2014
2016
  /** viem RPC client for the chain (used by the RPC monitoring scanners). */
2015
2017
  client: Viem.getClient.ReturnType
2016
2018
  /** Reorg-safety window: only emit blocks this far behind head (default 2). */
2017
2019
  confirmations?: number | undefined
2020
+ /** Database holding subscriptions + cursors. */
2021
+ db: Db.Db
2018
2022
  /**
2019
2023
  * Delivery transport. Defaults to inline {@link Webhooks.deliverAndRecord} (self-host);
2020
2024
  * on Cloudflare pass a Queue producer so retry/backoff/DLQ are native.
@@ -2028,8 +2032,6 @@ export declare namespace poll {
2028
2032
  maxBlocks?: number | undefined
2029
2033
  /** Clock for envelope timestamps; injectable for tests. */
2030
2034
  now?: (() => Date) | undefined
2031
- /** Webhook state store (subscriptions + cursors). */
2032
- store: Store.State
2033
2035
  /** TIDX query client for the legacy `token:transfer` type. */
2034
2036
  tidx?: Tidx.Client | undefined
2035
2037
  }
@@ -2059,9 +2061,9 @@ export declare namespace poll {
2059
2061
  async function withTokenMetadata(
2060
2062
  data: unknown,
2061
2063
  deps: {
2064
+ cache: Store.Store
2062
2065
  chainId: number
2063
2066
  client: Viem.getClient.ReturnType
2064
- store: Store.State
2065
2067
  },
2066
2068
  ): Promise<unknown> {
2067
2069
  if (typeof data !== 'object' || data === null) return data
@@ -2079,7 +2081,7 @@ async function withTokenMetadata(
2079
2081
  */
2080
2082
  async function resolveTokenMetadata(
2081
2083
  address: string,
2082
- deps: { chainId: number; client: Viem.getClient.ReturnType; store: Store.State },
2084
+ deps: { cache: Store.Store; chainId: number; client: Viem.getClient.ReturnType },
2083
2085
  ): Promise<{ decimals: number; symbol: string } | undefined> {
2084
2086
  try {
2085
2087
  return await Store.memoize(
@@ -2089,7 +2091,7 @@ async function resolveTokenMetadata(
2089
2091
  },
2090
2092
  {
2091
2093
  key: `webhook:token-meta:v1:${deps.chainId}:${address}`,
2092
- store: deps.store,
2094
+ store: deps.cache,
2093
2095
  ttl: Ttl.minutes(5),
2094
2096
  },
2095
2097
  )
@@ -0,0 +1,136 @@
1
+ import { Hono } from 'hono'
2
+ import { Handler as vocs_Handler } from 'vocs/server'
3
+
4
+ import type * as App from '../../App.js'
5
+ import * as Metadata from '../metadata.js'
6
+ import openrpcSpec from '../../openrpc.json' with { type: 'json' }
7
+ import { pilatFontFaces } from './fonts.js'
8
+ import { logoUrl } from './logo.js'
9
+
10
+ /**
11
+ * The docs route group: the Vocs API reference served at the app root.
12
+ *
13
+ * ```ts
14
+ * import { docs } from 'tapimo/docs'
15
+ * App.create(options).route('/', data()).route('/', platform()).route('/', docs())
16
+ * ```
17
+ *
18
+ * The group registers no routes itself: it carries a reference factory (via
19
+ * {@link Metadata}) that `App.create` mounts on finalize, after every group and
20
+ * the OpenAPI/OpenRPC documents — so the reference always renders the full
21
+ * composed surface and its catch-all stays behind API routes, wherever the
22
+ * group sits in the composition chain.
23
+ *
24
+ * Lives in the `tapimo/docs` subpath (never re-exported from `tapimo/apps`) so
25
+ * the Vocs renderer and its multi-MB icon/font data are bundled only by
26
+ * deployments that actually serve docs.
27
+ */
28
+ export function docs(options: docs.Options = {}) {
29
+ return Metadata.attach(new Hono<App.Environment>(), {
30
+ docs: ({ spec }) =>
31
+ vocs_Handler.openApi(
32
+ {
33
+ // Inline the OpenRPC doc so vocs expands it without a self-subrequest
34
+ // (see `inlineOpenrpc`); the public `/openapi.json` keeps the URL ref.
35
+ spec: () => spec().then(inlineOpenrpc),
36
+ sidebar: { collapsed: true },
37
+ vocs: { logoUrl, title: 'Tempo API Reference', ...options },
38
+ },
39
+ { css, fallback: 'next' },
40
+ ),
41
+ })
42
+ }
43
+
44
+ export declare namespace docs {
45
+ /** Vocs API reference options (theme, top navigation, logo, socials, …). */
46
+ type Options = NonNullable<Parameters<typeof vocs_Handler.openApi>[0]['vocs']>
47
+ }
48
+
49
+ /**
50
+ * Custom CSS injected into the standalone reference's shell `<head>` (via
51
+ * `Handler.openApi(_, { css })`), after the Vocs design-system styles so it
52
+ * overrides them:
53
+ *
54
+ * - Page/surface backgrounds use Tempo's near-black dark palette and pure-white
55
+ * light palette via `light-dark(<light>, <dark>)`.
56
+ * - The dark border color is darkened (the light theme keeps its default).
57
+ * - Every corner is squared. The universal `!important` rule beats hard-coded
58
+ * `border-radius` values and inline styles (e.g. the Scalar playground), which
59
+ * overriding the radius scale variables alone would miss.
60
+ * - The default sans/body font is Pilat (Vocs reads `--vocs-font-family`); the
61
+ * webfont is embedded via {@link pilatFontFaces}. Body stays at the default
62
+ * weight (400); headings are pinned to 500, which renders Pilat Demi (the
63
+ * family has no 500 cut, so Demi covers the 500-600 range — see
64
+ * {@link pilatFontFaces}).
65
+ */
66
+ const css = `${pilatFontFaces}
67
+
68
+ :root {
69
+ --vocs-font-family: "Pilat", Arial, Helvetica, sans-serif;
70
+ --vocs-background-color-primary: light-dark(#fafafa, #0a0a0a);
71
+ --vocs-background-color-surface: light-dark(#fff, #121212);
72
+ }
73
+
74
+ :is(h1, h2, h3, h4, h5, h6)[data-v] {
75
+ font-weight: 500;
76
+ }
77
+
78
+ /* Nudge the header logo a touch larger than the default max-h-7 (1.75rem). */
79
+ [data-v-logo-image] {
80
+ max-height: 2rem;
81
+ }
82
+
83
+ /* Sidebar leaf items render Regular (the nav's 450 default otherwise resolves to
84
+ * Demi via the 500-600 range). Group labels ([data-v-sidebar-section-header])
85
+ * keep their heavier weight. */
86
+ [data-v-sidebar-item] {
87
+ font-weight: 400;
88
+ }
89
+
90
+ [data-vocs-theme='dark'] {
91
+ --vocs-color-gray4: oklch(20% 0 0);
92
+ --vocs-color-gray5: oklch(0.23 0 0);
93
+ --vocs-border-color-primary: oklch(0.25 0 0);
94
+ --vocs-border-color-secondary: oklch(0.25 0 0);
95
+ }
96
+
97
+ *,
98
+ *::before,
99
+ *::after {
100
+ border-radius: 0 !important;
101
+ }`
102
+
103
+ /**
104
+ * Returns a shallow copy of `spec` with the JSON-RPC passthrough operation's
105
+ * `x-openrpc` replaced by the inline OpenRPC document, for the docs handler.
106
+ *
107
+ * Vocs expands `x-openrpc` at request time. A URL reference (as kept in the
108
+ * public `/openapi.json` by `App.create`'s `applyOpenrpcLink`) would make the
109
+ * docs worker fetch its own `/openrpc.json` — a self-subrequest that is
110
+ * unreliable on Cloudflare Workers and silently falls back to a single,
111
+ * unexpanded operation. Inlining the committed artifact keeps expansion
112
+ * deterministic across local and deployed environments, without bloating the
113
+ * public spec. Only the affected path/op are cloned; the rest of the (large)
114
+ * document is shared by reference.
115
+ */
116
+ function inlineOpenrpc<spec extends { paths: Record<string, unknown> }>(spec: spec): spec {
117
+ const paths: Record<string, unknown> = {}
118
+ for (const [pathname, item] of Object.entries(spec.paths)) {
119
+ let next = item
120
+ if (isRecord(item))
121
+ for (const [method, op] of Object.entries(item))
122
+ if (isRpcOperation(op)) next = { ...item, [method]: { ...op, 'x-openrpc': openrpcSpec } }
123
+ paths[pathname] = next
124
+ }
125
+ return { ...spec, paths }
126
+ }
127
+
128
+ // The JSON-RPC passthrough's operation id, set by its route definition and
129
+ // targeted by `App.create`'s `applyOpenrpcLink`.
130
+ function isRpcOperation(op: unknown): op is Record<string, unknown> {
131
+ return isRecord(op) && op['operationId'] === 'rpcRequest'
132
+ }
133
+
134
+ function isRecord(value: unknown): value is Record<string, unknown> {
135
+ return !!value && typeof value === 'object' && !Array.isArray(value)
136
+ }
@@ -0,0 +1 @@
1
+ export { docs } from './App.js'
@@ -0,0 +1,3 @@
1
+ export { data } from './data/index.js'
2
+ export { platform } from './platform/index.js'
3
+ export { relay } from './relay/index.js'
@@ -0,0 +1,23 @@
1
+ import type { Hono } from 'hono'
2
+
3
+ import type * as App from '../App.js'
4
+
5
+ // Hono's `.route()` drops sub-app metadata, so a group's OpenAPI metadata can't
6
+ // ride the instance through it. Each group attaches its metadata here and
7
+ // `App.create` reads it back on mount. The `WeakMap` keeps the association off
8
+ // the app's type, so `testClient`/`hc` inference is untouched.
9
+ const registry = new WeakMap<Hono<any, any>, App.create.Metadata>()
10
+
11
+ /** Attaches a group's OpenAPI metadata to its app instance for `create` to collect on mount. */
12
+ export function attach<const app extends Hono<any, any>>(
13
+ app: app,
14
+ metadata: App.create.Metadata,
15
+ ): app {
16
+ registry.set(app, metadata)
17
+ return app
18
+ }
19
+
20
+ /** Reads the OpenAPI metadata attached to an app instance, if any. */
21
+ export function read(app: Hono<any, any>): App.create.Metadata | undefined {
22
+ return registry.get(app)
23
+ }