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
package/dist/App.js CHANGED
@@ -4,11 +4,10 @@ import { cors as hono_cors } from 'hono/cors';
4
4
  import { HTTPException } from 'hono/http-exception';
5
5
  import { requestId } from 'hono/request-id';
6
6
  import { generateSpecs } from 'hono-openapi';
7
- import { Handler } from 'vocs/server';
8
- import * as z from 'zod/mini';
9
7
  import * as ApiKey from './ApiKey.js';
10
8
  import * as Assets from './Assets.js';
11
9
  import * as Auth from './internal/Auth.js';
10
+ import * as Db from './db/Db.js';
12
11
  import * as EdgeCache from './internal/EdgeCache.js';
13
12
  import * as Log from './internal/Log.js';
14
13
  import * as MetricSink from './internal/MetricSink.js';
@@ -16,31 +15,25 @@ import * as OpenApi from './internal/OpenApi.js';
16
15
  import * as Store from './internal/Store.js';
17
16
  import * as Path from './internal/Path.js';
18
17
  import * as Response from './internal/Response.js';
19
- import * as Schema from './internal/Schema.js';
20
- import * as Tidx from './internal/Tidx.js';
21
18
  import * as Timing from './internal/Timing.js';
22
19
  import * as Viem from './internal/Viem.js';
23
20
  import openrpcSpec from './openrpc.json' with { type: 'json' };
24
- import { transactions as transactionActivities } from './apps/activities.js';
25
- import { addresses } from './apps/addresses.js';
26
- import { blocks, blocksByTimestampCompat } from './apps/blocks.js';
27
- import { coingecko } from './apps/coingecko.js';
28
- import { exchanges } from './apps/exchanges.js';
29
- import { feeAmm } from './apps/fee-amm.js';
30
- import { indexer } from './apps/indexer.js';
31
- import { receipts } from './apps/receipts.js';
32
- import { rpc as rpcApp } from './apps/rpc.js';
33
- import { tokens } from './apps/tokens.js';
34
- import { transactions } from './apps/transactions.js';
35
- import { transfers } from './apps/transfers.js';
36
- import { verifiedTokens } from './apps/verified-tokens.js';
37
- import { tokenlist } from './apps/tokenlist.js';
38
- import { schema as webhookSchema, webhooks } from './apps/webhooks.js';
21
+ import * as Metadata from './apps/metadata.js';
22
+ import * as Data from './apps/data/App.js';
23
+ import * as Platform from './apps/platform/App.js';
24
+ export var data = Data.data;
25
+ export var platform = Platform.platform;
26
+ // Type anchor only never invoked. Expresses the canonical composition so
27
+ // `App` (and thus `Client`) reflect the full route surface; real consumers
28
+ // compose explicitly.
29
+ function compose(options) {
30
+ return create(options).route('/', data()).route('/', platform());
31
+ }
39
32
  /** Top-level OpenAPI `info.description`, rendered above the reference. */
40
33
  const infoDescription = 'REST API for reading and interacting with Tempo';
41
34
  /** Creates the Tempo API Hono app. */
42
- export function create(options = {}) {
43
- const { assets, defaultChainId = Viem.defaultChainId, path = '/', rpc } = options;
35
+ export function create(options) {
36
+ const { path = '/' } = options;
44
37
  // Capture as the literal generic so `Hono.basePath(...)` preserves the
45
38
  // typed prefix. testClient's `Client<T, ...>` inference collapses to a
46
39
  // `Record<string, ...>` index signature when the BasePath generic is the
@@ -52,33 +45,9 @@ export function create(options = {}) {
52
45
  // miss simply re-fetches — so it defaults to in-memory. Point it at a
53
46
  // colo-local store (`Store.cache(caches.default)`) in production; never the
54
47
  // Durable Object, or edge-cache hits re-incur the round-trip they skip.
55
- // Authoritative state (webhooks) lives in its own state store, configured
56
- // separately via `options.webhook.store` (a Durable Object in production).
48
+ // Authoritative state lives elsewhere: webhooks + verified tokens in
49
+ // `options.db`, API-key records in `options.kv`.
57
50
  const store = options.cache?.store ?? Store.memory();
58
- // Memoize one viem client per resolved upstream. Clients are stateless HTTP
59
- // transports, so reusing them avoids per-request construction cost. The cache
60
- // key is the resolved output (`url` + `basicAuth` + `chainId`), not the
61
- // principal, so a resolver `rpc` may branch on any principal field while
62
- // client cardinality stays bounded by the number of distinct upstreams —
63
- // callers that resolve to the same upstream share a client.
64
- const clients = new Map();
65
- const getClient = (chainId = defaultChainId, principal = null) => {
66
- // Resolve to derive the cache key; `Viem.getClient` re-resolves to build the
67
- // client on a miss. `resolve` is pure and cheap, so the extra call is free.
68
- const { url, basicAuth } = Viem.resolve(rpc, { chainId, principal });
69
- const cacheKey = `${url}|${basicAuth ?? ''}|${chainId}`;
70
- const existing = clients.get(cacheKey);
71
- if (existing)
72
- return existing;
73
- const client = Viem.getClient({ chainId, principal, rpc });
74
- clients.set(cacheKey, client);
75
- return client;
76
- };
77
- // Memoize TIDX clients per `chainId` so the base URL resolver runs once per
78
- // chain instead of on every request. The same factory backs the scheduled
79
- // webhook poller (`Webhooks.createPoller`), keeping client construction in
80
- // one place.
81
- const getTidx = Tidx.createGetClient({ defaultChainId, tidx: options.tidx });
82
51
  // Build the app in two phases: register middleware imperatively, then chain
83
52
  // route mounts so the merged Hono schema flows through the return type. The
84
53
  // chained type is what makes `testClient(create())` produce typed path
@@ -121,8 +90,8 @@ export function create(options = {}) {
121
90
  })();
122
91
  if (log || recordRequest || recordAnalytics)
123
92
  base.use('*', Log.middleware({
124
- emit: (entry) => {
125
- log?.(entry);
93
+ emit: async (entry) => {
94
+ await log?.(entry);
126
95
  recordRequest?.(entry);
127
96
  // Return the analytics promise so `Log.middleware` extends the
128
97
  // response with `waitUntil`; otherwise the async sink's `queue.send`
@@ -131,61 +100,21 @@ export function create(options = {}) {
131
100
  return recordAnalytics?.(entry);
132
101
  },
133
102
  }));
134
- // The chain ids this deployment serves: the built-in public chains plus the
135
- // configured `defaultChainId` and any explicit `supportedChainIds`. Exposed on
136
- // context so mounted apps with a path `chainId` (e.g. GeckoTerminal) can guard
137
- // it too.
138
- const supportedChainIds = new Set([
139
- ...Object.keys(Viem.url).map(Number),
140
- ...Object.keys(Tidx.url).map(Number),
141
- defaultChainId,
142
- ...(options.supportedChainIds ?? []),
143
- ]);
103
+ // Normalize the `db` option: the plain form is `{ source }` with no cached
104
+ // side; `cached` falls back to `source` so consumers never branch.
105
+ const db = 'source' in options.db ? options.db : { source: options.db };
106
+ // Built-in auth: the session surface (mounted last) plus the enforcement
107
+ // middleware (installed below), wired together in `Auth.install`.
108
+ const auth = Auth.install({ auth: options.auth, db: db.source, kv: options.kv });
144
109
  base.use('*', Timing.middleware());
145
110
  base.use('*', async (c, next) => {
146
- // Put app-level dependencies on Hono context so mounted handlers only
147
- // receive request-local state from `c`.
148
111
  c.set('basePath', basePath);
149
- c.set('chainId', defaultChainId);
150
- c.set('getAsset', createGetAsset({ assets, basePath, origin: new URL(c.req.url).origin }));
151
- c.set('getClient', (chainId) => getClient(chainId, Auth.getPrincipal(c)));
152
- c.set('getTidx', (chainId) => getTidx(chainId, Auth.getPrincipal(c)));
153
- c.set('rpc', rpc);
112
+ c.set('db', db.source);
113
+ c.set('dbCached', db.cached ?? db.source);
114
+ c.set('kv', options.kv);
154
115
  c.set('store', store);
155
- c.set('supportedChainIds', supportedChainIds);
156
- c.set('tidx', options.tidx);
157
- c.set('verifiedTokens', options.verifiedTokens);
158
- c.set('webhook', options.webhook);
159
116
  await next();
160
117
  });
161
- // Reject a syntactically valid `chainId` this deployment does not serve before
162
- // it reaches an upstream — an unknown chain otherwise hits the configured
163
- // RPC/indexer (a static `tidx.baseUrl` answers for any chain id) and comes
164
- // back as an opaque `upstream_error`.
165
- base.use('*', async (c, next) => {
166
- const raw = c.req.query('chainId') ?? c.req.query('chain_id');
167
- if (raw === undefined)
168
- return next();
169
- // Only reject a well-formed-but-unsupported chain here; malformed values
170
- // (e.g. `abc`, `0`) fall through to the route's own query validation.
171
- const parsed = Schema.ChainId.safeParse(raw);
172
- if (!parsed.success || supportedChainIds.has(parsed.data))
173
- return next();
174
- return Response.unsupportedChainId(c, parsed.data, supportedChainIds);
175
- });
176
- // Skip the static asset route entirely when no store is configured; token
177
- // logo URIs simply go unresolved.
178
- if (assets)
179
- base.use('/assets/*', async (c, next) => {
180
- const key = stripAssetPath(c.req.path, basePath).replace(/^\/+/, '');
181
- const asset = key ? await assets.get(key) : undefined;
182
- if (!asset)
183
- return next();
184
- return c.body(asset.body, 200, {
185
- 'Cache-Control': 'public, max-age=86400',
186
- 'Content-Type': asset.contentType,
187
- });
188
- });
189
118
  // Safety net: any non-2xx response (auth/validation errors, MPP `402`
190
119
  // challenges, rate-limit `429`s, upstream `502`s, etc.) must never be
191
120
  // cached. This wraps endpoint middleware and handlers registered below.
@@ -202,71 +131,71 @@ export function create(options = {}) {
202
131
  // latency.
203
132
  if (options.cache?.edge !== false)
204
133
  base.use('*', EdgeCache.middleware({ store }));
205
- const base_routed = base.get('/health', OpenApi.describeRoute({ hide: true }), (c) => c.json({ status: 'ok' }, 200));
206
- for (const middleware of options.middleware ?? [])
207
- base_routed.use('*', middleware);
208
- const app = base_routed
209
- .route('/v1/addresses', addresses())
210
- .route('/v1/blocks', blocks())
211
- .route('/v1/exchange', exchanges())
212
- .route('/v1/fee-amm', feeAmm())
213
- .route('/v1/indexer', indexer())
214
- .route('/v1/tokenlist', tokenlist())
215
- .route('/v1/tokens', tokens())
216
- .route('/v1/transactions', receipts())
217
- .route('/v1/transactions', transactions())
218
- .route('/v1/transactions', transactionActivities())
219
- .route('/v1/transfers', transfers())
220
- .route('/v1/verified-tokens', verifiedTokens())
221
- .route('/v1/webhooks', webhooks({ enabled: options.webhook !== undefined }))
222
- .route('/rpc', rpcApp())
223
- .route('/gecko', coingecko())
224
- // Hidden compatibility route for the prior Tempo API's
225
- // `GET /chains/:chainId/blocks/by-timestamp` (chain id in the path).
226
- .route('/chains', blocksByTimestampCompat());
227
- const spec = (async () => {
228
- // OAS 3.1 `webhooks`: document the signed envelope Tempo API POSTs to subscriber
229
- // URLs (an outbound payload, not an endpoint of this API). Only when enabled.
230
- const webhooksDoc = (() => {
231
- if (!options.webhook)
232
- return {};
233
- // `io: 'output'` documents the delivered (serialized) shape; `unrepresentable: 'any'`
234
- // tolerates the transaction payload's transforms (e.g. lazy fee-token metadata),
235
- // which have no JSON-Schema form, by emitting `{}` for those nodes rather than throwing.
236
- const envelope = z.toJSONSchema(webhookSchema.Envelope, {
237
- io: 'output',
238
- target: 'draft-2020-12',
239
- unrepresentable: 'any',
240
- });
241
- delete envelope.$schema;
242
- const header = (name, description) => ({
243
- description,
244
- in: 'header',
245
- name,
246
- required: true,
247
- schema: { type: 'string' },
248
- });
249
- return {
250
- webhooks: {
251
- event: {
252
- post: {
253
- description: 'When an event you subscribed to happens, Tempo sends this signed message to your webhook URL as an HTTP POST (the same shape is used by `POST /webhooks/:id/ping` so you can test your endpoint). Always verify the `tempo-signature` header before trusting the body, then reply with any 2xx status to confirm you received it. If your endpoint returns a non-2xx status, times out, or redirects, Tempo retries with increasing delays; an endpoint that keeps failing is eventually disabled.',
254
- parameters: [
255
- header('tempo-signature', 'Signature proving the message really came from Tempo. An HMAC-SHA256 of the body using your webhook secret, formatted `t=<unix>,v1=<hex>`. Verify this before trusting the payload.'),
256
- header('tempo-event-id', 'A unique, stable id for this event (`evt_…`). The same event may be delivered more than once, so use this id to skip duplicates.'),
257
- header('tempo-event-type', 'What happened: `token:transfer`, `transaction:included`, `log:emitted`, `block:created`, or `ping`.'), // prettier-ignore
258
- ],
259
- requestBody: {
260
- content: { 'application/json': { schema: envelope } },
261
- required: true,
262
- },
263
- responses: { '2xx': { description: 'Delivery acknowledged.' } },
264
- summary: 'Webhook event delivery',
265
- tags: ['Webhooks'],
266
- },
267
- },
268
- },
269
- };
134
+ const app = base.get('/health', OpenApi.describeRoute({ hide: true }), (c) => c.json({ status: 'ok' }, 200));
135
+ // Built-in enforcement: default-closed policies over OpenAPI-registered
136
+ // routes. `auth: false` leaves policies unenforced (tests only).
137
+ if (auth.middleware)
138
+ app.use('*', auth.middleware);
139
+ // Collect each mounted group's OpenAPI metadata: Hono's `.route()` drops
140
+ // sub-app metadata, so a group attaches it to its instance (a WeakMap) and we
141
+ // read it back here. Patching the runtime method, not the type, keeps `hc`.
142
+ const metadata = [];
143
+ const route = app.route.bind(app);
144
+ app.route = ((path, sub) => {
145
+ const entry = Metadata.read(sub);
146
+ if (entry)
147
+ metadata.push(entry);
148
+ return route(path, sub);
149
+ });
150
+ // Register the JSON error envelopes eagerly (they don't depend on mounted
151
+ // routes) so error handling is live before the first request and a consumer's
152
+ // `withSentry(app)` sees them already in place.
153
+ app.notFound((c) => Response.error(c, { code: 'not_found', message: 'Route not found', status: 404 }));
154
+ app.onError((cause, c) => {
155
+ if (cause instanceof HTTPException)
156
+ return errorFromException(c, cause);
157
+ // Redact any leaked API-key token from the logged error/stack.
158
+ console.error(ApiKey.redact(cause instanceof Error ? (cause.stack ?? cause.message) : String(cause)));
159
+ return Response.error(c, {
160
+ code: 'internal_error',
161
+ message: 'Internal server error',
162
+ status: 500,
163
+ });
164
+ });
165
+ // Mount the OpenAPI/OpenRPC documents and docs reference lazily on the first
166
+ // request, so the document sees the full route surface without a `seal()`
167
+ // step. The patched `fetch` runs this before Hono builds its matcher.
168
+ //
169
+ // Spec generation stays lazy: ordinary API traffic only installs the routes,
170
+ // while `/openapi.json` and the Vocs handler start the memoized build.
171
+ let spec;
172
+ const getSpec = () => (spec ??= buildSpec());
173
+ const buildSpec = async () => {
174
+ // Merge each mounted group's contributed OpenAPI metadata (tags, security
175
+ // schemes, webhooks block). Unused tags/schemes don't render, so a subset
176
+ // app's document carries only what its groups contributed.
177
+ // The built-in session surface's metadata appends after every mounted
178
+ // group's, so consumer-mounted groups lead the document order.
179
+ const metadata_all = (() => {
180
+ const entry = auth.app ? Metadata.read(auth.app) : undefined;
181
+ return entry ? [...metadata, entry] : metadata;
182
+ })();
183
+ const contributedSchemes = Object.assign({}, ...metadata_all.map((m) => m.securitySchemes ?? {})); // prettier-ignore
184
+ const tags = metadata_all.flatMap((m) => m.tags ?? []);
185
+ // Tag groups contributed under the same name merge into one sidebar group,
186
+ // deduped and filtered to defined tags (a group may list a tag another
187
+ // surface defines, e.g. `Auth` from the built-in session surface).
188
+ const tagGroups = (() => {
189
+ const defined = new Set(tags.map((tag) => tag.name));
190
+ const groups = new Map();
191
+ for (const { name, tags: members } of metadata_all.flatMap((m) => m['x-tagGroups'] ?? []))
192
+ groups.set(name, { name, tags: [...(groups.get(name)?.tags ?? []), ...members] });
193
+ return [...groups.values()]
194
+ .map((group) => ({
195
+ ...group,
196
+ tags: [...new Set(group.tags)].filter((tag) => defined.has(tag)),
197
+ })) // prettier-ignore
198
+ .filter((group) => group.tags.length > 0);
270
199
  })();
271
200
  const generated = await generateSpecs(app, {
272
201
  documentation: {
@@ -285,6 +214,7 @@ export function create(options = {}) {
285
214
  scheme: 'bearer',
286
215
  type: 'http',
287
216
  },
217
+ ...contributedSchemes,
288
218
  },
289
219
  },
290
220
  info: {
@@ -298,70 +228,22 @@ export function create(options = {}) {
298
228
  { url: basePath || '/', description: 'Relative to the host serving this document.' },
299
229
  ]),
300
230
  ],
301
- tags: [
302
- {
303
- name: 'Activities',
304
- description: 'A readable feed of what an account did onchain.',
305
- },
306
- {
307
- name: 'Balances',
308
- description: 'How much of each token an account holds.',
309
- },
310
- {
311
- name: 'Blocks',
312
- description: 'The ordered batches of transactions making up the chain.',
313
- },
314
- {
315
- name: 'Exchange',
316
- description: "Tempo's built-in stablecoin exchange: pairs, swaps, orders, prices.",
317
- },
318
- {
319
- name: 'Fee AMM',
320
- description: 'Pools that convert stablecoins to pay fees.',
321
- },
322
- {
323
- name: 'Tokens',
324
- description: 'TIP-20 token details, supply, and holders.',
325
- },
326
- {
327
- name: 'Transactions',
328
- description: 'Transactions submitted to Tempo, and their receipts.',
329
- },
330
- {
331
- name: 'Transfers',
332
- description: 'Token movements from executing transactions.',
333
- },
334
- {
335
- name: 'Verified Tokens',
336
- description: 'A curated, trusted list of TIP-20 tokens.',
337
- },
338
- ...(options.webhook
339
- ? [
340
- {
341
- name: 'Webhooks',
342
- description: 'Get signed callbacks when onchain events happen.',
343
- },
344
- ]
345
- : []),
346
- {
347
- name: 'Indexer',
348
- description: "Run read-only SQL queries against Tempo's indexed data.",
349
- },
350
- {
351
- name: 'RPC',
352
- description: 'Direct access to the chain over Ethereum JSON-RPC. Not part of the stable API contract; best-effort support only. No compatibility, latency, availability, or data-freshness guarantees. Breaking changes may happen with limited notice.',
353
- },
354
- {
355
- name: 'CoinGecko',
356
- description: "Exchange data in CoinGecko's GeckoTerminal format.",
357
- },
358
- ],
231
+ tags,
232
+ ...(tagGroups.length ? { 'x-tagGroups': tagGroups } : {}),
359
233
  },
360
234
  });
361
- // Set per-operation `security` and the `402` payment-challenge response from
362
- // each route's resolved auth policy (the single source of truth), so the
363
- // anonymous option and `402` appear only where the public/MPP lanes are
364
- // enabled not on every operation via the document default.
235
+ // Document the outbound `webhooks` block only when the webhook routes are
236
+ // actually mounted; a disabled feature hides its routes, so it must not
237
+ // advertise deliveries.
238
+ const hasWebhookRoutes = Object.keys(generated.paths).some((path) => /\/webhooks(\/|$)/.test(path));
239
+ const webhookBlocks = hasWebhookRoutes ? metadata_all.flatMap((m) => (m.webhooks ? [m.webhooks()] : [])) : []; // prettier-ignore
240
+ const webhooksDoc = webhookBlocks.length
241
+ ? { webhooks: Object.assign({}, ...webhookBlocks) }
242
+ : {};
243
+ // Set per-operation `security` and the `402` payment-challenge response
244
+ // from each route's resolved auth policy (the single source of truth), so
245
+ // the anonymous option and `402` appear only where the public/MPP lanes
246
+ // are enabled, not on every operation via the document default.
365
247
  applyAccess(generated.paths, Auth.describeAccess(app));
366
248
  // Point the `/rpc` operation at the OpenRPC document via `x-openrpc`.
367
249
  applyOpenrpcLink(generated.paths, basePath);
@@ -371,37 +253,32 @@ export function create(options = {}) {
371
253
  // tag and preserves document path order within a tag, so reordering here
372
254
  // drives the sidebar sub-item order.
373
255
  return { ...generated, ...webhooksDoc, paths: sortPaths(generated.paths) };
374
- })();
375
- app.get('/openapi.json', async (c) => c.json(await spec));
376
- // The OpenRPC document is a committed build artifact (no runtime generator);
377
- // see scripts/openrpc/build.ts and `pnpm openrpc:build`.
378
- app.get('/openrpc.json', (c) => c.json(openrpcSpec));
379
- if (options.docs !== false)
380
- app.route('/', Handler.openApi({
381
- // Inline the OpenRPC doc so vocs expands it without a self-subrequest
382
- // (see `inlineOpenrpc`); the public `/openapi.json` keeps the URL ref.
383
- spec: spec.then(inlineOpenrpc),
384
- sidebar: { collapsed: true },
385
- vocs: { logoUrl: OpenApi.logoUrl, title: 'Tempo API Reference', ...options.docs },
386
- }, { fallback: 'next', css: OpenApi.css }));
387
- app.notFound((c) => Response.error(c, { code: 'not_found', message: 'Route not found', status: 404 }));
388
- app.onError((cause, c) => {
389
- if (cause instanceof HTTPException)
390
- return errorFromException(c, cause);
391
- // Redact any leaked API-key token from the logged error/stack.
392
- console.error(ApiKey.redact(cause instanceof Error ? (cause.stack ?? cause.message) : String(cause)));
393
- return Response.error(c, {
394
- code: 'internal_error',
395
- message: 'Internal server error',
396
- status: 500,
397
- });
256
+ };
257
+ let finalized = false;
258
+ const finalize = () => {
259
+ if (finalized)
260
+ return;
261
+ finalized = true;
262
+ app.get('/openapi.json', async (c) => c.json(await getSpec()));
263
+ // The OpenRPC document is a committed build artifact (no runtime generator);
264
+ // see scripts/openrpc/build.ts and `pnpm openrpc:build`.
265
+ app.get('/openrpc.json', (c) => c.json(openrpcSpec));
266
+ // Mount each docs group's reference factory (see `docs()` in `tapimo/docs`)
267
+ // last, so its catch-all sits behind every API route and the documents
268
+ // above regardless of where the group sat in the composition chain.
269
+ for (const entry of metadata)
270
+ if (entry.docs)
271
+ app.route('/', entry.docs({ spec: getSpec }));
272
+ };
273
+ // Patch `fetch` to finalize once before dispatch. `request()` reads
274
+ // `this.fetch` dynamically so it picks up the patch, and the captured
275
+ // `originalFetch` still dispatches as a bare value (used by `App.listener`).
276
+ const originalFetch = app.fetch;
277
+ app.fetch = ((request, ...rest) => {
278
+ finalize();
279
+ return originalFetch(request, ...rest);
398
280
  });
399
- // Return the typed chained Hono directly. Spreading `store`/`listener` onto
400
- // the app would intersect the inferred Hono type and breaks `testClient`'s
401
- // schema inference for downstream consumers. The cache `store` is owned by
402
- // the caller (pass `options.cache.store`), and a Node listener is produced on
403
- // demand via `App.listener(app)`.
404
- return app;
281
+ return route('/', auth.app ?? new Hono());
405
282
  }
406
283
  /**
407
284
  * Wraps a Tempo API app with a `node:http`-compatible request listener.
@@ -484,10 +361,11 @@ function sortPaths(paths) {
484
361
  }
485
362
  /**
486
363
  * Sets per-operation `security` and the `402` payment-challenge response from
487
- * each route's resolved access lanes (see {@link Auth.describeAccess}). The
488
- * anonymous (`{}`) security option and the `402` response are emitted only where
489
- * the route's policy enables the public and MPP lanes respectively; required
490
- * API-key scopes are surfaced as the `x-required-scopes` extension.
364
+ * each route's resolved access lanes (see {@link Auth.describeAccess}).
365
+ * Security options compose from the enabled lanes API keys (header +
366
+ * bearer), sessions (cookie + bearer token), anonymous (`{}`) and the `402`
367
+ * response is emitted only where the MPP lane is enabled; required API-key
368
+ * scopes are surfaced as the `x-required-scopes` extension.
491
369
  */
492
370
  function applyAccess(paths, access) {
493
371
  for (const item of Object.values(paths)) {
@@ -497,7 +375,13 @@ function applyAccess(paths, access) {
497
375
  const lanes = access[op.operationId];
498
376
  if (!lanes)
499
377
  continue;
500
- op.security = [{ apiKey: [] }, { bearerAuth: [] }, ...(lanes.public ? [{}] : [])];
378
+ const security = [
379
+ ...(lanes.apiKey ? [{ apiKey: [] }, { bearerAuth: [] }] : []),
380
+ ...(lanes.session ? [{ session: [] }, ...(lanes.apiKey ? [] : [{ bearerAuth: [] }])] : []),
381
+ ...(lanes.public ? [{}] : []),
382
+ ];
383
+ if (security.length > 0)
384
+ op.security = security;
501
385
  if (lanes.scopes.length > 0)
502
386
  op['x-required-scopes'] = [...lanes.scopes];
503
387
  if (lanes.mpp)
@@ -514,7 +398,7 @@ function applyAccess(paths, access) {
514
398
  * method/param/return schemas it accepts.
515
399
  *
516
400
  * The public `/openapi.json` keeps a URL reference (small, conventional). The
517
- * docs handler instead receives the document inlined — see `inlineOpenrpc`.
401
+ * docs handler instead inlines the document — see `inlineOpenrpc` in `tapimo/docs`.
518
402
  */
519
403
  function applyOpenrpcLink(paths, basePath) {
520
404
  // `basePath` is `/` at the root mount and `/api` etc. otherwise; strip any
@@ -525,30 +409,6 @@ function applyOpenrpcLink(paths, basePath) {
525
409
  if (isMutableOperation(op) && isRpcOperation(op))
526
410
  op['x-openrpc'] = url;
527
411
  }
528
- /**
529
- * Returns a shallow copy of `spec` with the JSON-RPC passthrough operation's
530
- * `x-openrpc` replaced by the inline OpenRPC document, for the docs handler.
531
- *
532
- * Vocs expands `x-openrpc` at request time. A URL reference (as kept in the
533
- * public `/openapi.json`) would make the docs worker fetch its own
534
- * `/openrpc.json` — a self-subrequest that is unreliable on Cloudflare Workers
535
- * and silently falls back to a single, unexpanded operation. Inlining the
536
- * committed artifact keeps expansion deterministic across local and deployed
537
- * environments, without bloating the public spec. Only the affected path/op are
538
- * cloned; the rest of the (large) document is shared by reference.
539
- */
540
- function inlineOpenrpc(spec) {
541
- const paths = {};
542
- for (const [pathname, item] of Object.entries(spec.paths)) {
543
- let next = item;
544
- if (isRecord(item))
545
- for (const [method, op] of Object.entries(item))
546
- if (isMutableOperation(op) && isRpcOperation(op))
547
- next = { ...item, [method]: { ...op, 'x-openrpc': openrpcSpec } };
548
- paths[pathname] = next;
549
- }
550
- return { ...spec, paths };
551
- }
552
412
  function isRpcOperation(op) {
553
413
  return op.operationId === 'rpcRequest';
554
414
  }
@@ -564,38 +424,6 @@ function isJson(response) {
564
424
  function isRecord(value) {
565
425
  return !!value && typeof value === 'object' && !Array.isArray(value);
566
426
  }
567
- function createGetAsset(options) {
568
- const { assets, basePath, origin } = options;
569
- // Without an asset store, every lookup misses so callers fall back to their
570
- // "no static data" behavior (undefined logo URIs).
571
- if (!assets)
572
- return () => undefined;
573
- return async (chainId, path) => {
574
- // Public URLs include `/assets/:chainId`, but the store is keyed by
575
- // `:chainId/:path` (e.g. an R2 object key), decoupled from the URL shape.
576
- // `path` may be absolute (`Path.join` returns a leading slash); strip it so
577
- // the key is `:chainId/:path`, not `:chainId//:path`.
578
- const pathname = Path.join(basePath, 'assets', String(chainId), path);
579
- const key = `${chainId}/${path.replace(/^\/+/, '')}`;
580
- const asset = await assets.get(key);
581
- if (!asset)
582
- return undefined;
583
- // Return an absolute public URL (scheme + host) against the request origin
584
- // so logo URLs work for any consumer regardless of the API's domain.
585
- return {
586
- response: new globalThis.Response(asset.body, {
587
- headers: { 'Content-Type': asset.contentType },
588
- }),
589
- uri: new URL(pathname, origin).toString(),
590
- };
591
- };
592
- }
593
- function stripAssetPath(path, basePath) {
594
- for (const prefix of [`${Path.join(basePath, 'assets')}/`, '/assets/'])
595
- if (path.startsWith(prefix))
596
- return `/${path.slice(prefix.length)}`;
597
- return path;
598
- }
599
427
  function getRequestListener(fetch) {
600
428
  let listener;
601
429
  return async (incoming_, outgoing_) => {