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
@@ -1,21 +1,154 @@
1
+ import * as Accounts from 'accounts/server';
2
+ import { Hono } from 'hono';
1
3
  import { createMiddleware } from 'hono/factory';
2
4
  import { matchedRoutes } from 'hono/route';
3
5
  import { findTargetHandler } from 'hono/utils/handler';
4
6
  import { Credential } from 'mppx';
5
7
  import { Mppx, tempo } from 'mppx/hono';
6
- import * as ApiKeySource from '../ApiKeySource.js';
8
+ import * as z from 'zod/mini';
7
9
  import * as ApiKey from '../ApiKey.js';
10
+ import * as ApiKeys from '../ApiKeys.js';
11
+ import * as Db from '../db/Db.js';
12
+ import * as Memberships from '../db/tables/memberships.js';
13
+ import * as Metadata from '../apps/metadata.js';
8
14
  import * as OpenApi from './OpenApi.js';
15
+ import * as Organizations from '../db/tables/organizations.js';
16
+ import * as Projects from '../db/tables/projects.js';
9
17
  import * as RateLimit from './RateLimit.js';
10
18
  import * as Response from './Response.js';
11
19
  import * as Schema from './Schema.js';
12
20
  import * as Scope from '../Scope.js';
21
+ import * as Users from '../db/tables/users.js';
13
22
  import * as Viem from './Viem.js';
14
23
  const policySymbol = Symbol('tempo-api.auth.policy');
15
24
  /** Reads the authenticated principal from a Hono context. */
16
25
  export function getPrincipal(c) {
17
26
  return c.get('principal') ?? null;
18
27
  }
28
+ /**
29
+ * Guards org-scoped routes (`:orgId`). Sessions reach only organizations they
30
+ * are members of; the super admin reaches any. Missing or foreign
31
+ * organizations return `404`, so foreign org ids are indistinguishable from
32
+ * absent ones; a member below the required role gets `403` (the resource is
33
+ * visible to them, the action is not). The resolved organization and
34
+ * membership land on context — read them with {@link org} and
35
+ * {@link membership}.
36
+ */
37
+ export function ensureOrg(options = {}) {
38
+ const { role: minimum = 'member' } = options;
39
+ // Typed loosely (like {@link policy}) so route chains keep their inferred
40
+ // schema; a concrete environment parameter collapses Hono's inference.
41
+ return createMiddleware(async (c, next) => {
42
+ const notFound = () => Response.error(c, {
43
+ code: 'organization_not_found',
44
+ message: 'Organization not found',
45
+ status: 404,
46
+ });
47
+ const orgId = c.req.param('orgId');
48
+ if (!orgId)
49
+ return notFound();
50
+ const principal = getPrincipal(c);
51
+ if (principal?.type !== 'session' && principal?.type !== 'super_admin')
52
+ return notFound();
53
+ const db = Db.get(contextDb(c));
54
+ const record = await Organizations.get(db, orgId);
55
+ if (!record)
56
+ return notFound();
57
+ if (principal.type !== 'super_admin') {
58
+ const member = await Memberships.get(db, orgId, principal.id);
59
+ if (!member)
60
+ return notFound();
61
+ if (Memberships.rank[member.role] < Memberships.rank[minimum])
62
+ return Response.error(c, {
63
+ code: 'forbidden',
64
+ message: `Requires the ${minimum} role`,
65
+ status: 403,
66
+ });
67
+ c.set('membership', member);
68
+ }
69
+ c.set('org', record);
70
+ await next();
71
+ return undefined;
72
+ });
73
+ }
74
+ /**
75
+ * Guards project-scoped routes (`:projectId`) nested under {@link ensureOrg},
76
+ * which must run first. Projects resolve only within the scoped organization;
77
+ * missing or cross-org projects return `404`. The resolved project lands on
78
+ * context — read it with {@link project}.
79
+ */
80
+ export function ensureProject() {
81
+ // Typed loosely (like {@link policy}) so route chains keep their inferred
82
+ // schema; a concrete environment parameter collapses Hono's inference.
83
+ return createMiddleware(async (c, next) => {
84
+ const notFound = () => Response.error(c, {
85
+ code: 'project_not_found',
86
+ message: 'Project not found',
87
+ status: 404,
88
+ });
89
+ const projectId = c.req.param('projectId');
90
+ if (!projectId)
91
+ return notFound();
92
+ const scoped = c.get('org');
93
+ if (!scoped)
94
+ return notFound();
95
+ const record = await Projects.get(Db.get(contextDb(c)), projectId);
96
+ if (!record || record.orgId !== scoped.id)
97
+ return notFound();
98
+ c.set('project', record);
99
+ await next();
100
+ return undefined;
101
+ });
102
+ }
103
+ /**
104
+ * Always false at runtime, but typed as `boolean` so handlers can include a
105
+ * never-reached scope-error branch in Hono's inferred response union (the
106
+ * ensure middlewares produce these `404`s before the handler runs).
107
+ */
108
+ export const narrowScope = false;
109
+ /** Typed org-scope error response for Hono client inference. Never reached at runtime. */
110
+ export function ensureOrgError(c) {
111
+ return Response.error(c, {
112
+ code: 'organization_not_found',
113
+ message: 'Organization not found',
114
+ status: 404,
115
+ });
116
+ }
117
+ /** Typed project-scope error response for Hono client inference. Never reached at runtime. */
118
+ export function ensureProjectError(c) {
119
+ // Project routes run the org scope first, so either not-found can surface.
120
+ const code = c.req.header('tempo-narrow-scope-code') === 'organization_not_found'
121
+ ? 'organization_not_found'
122
+ : 'project_not_found';
123
+ return Response.error(c, {
124
+ code,
125
+ message: 'Project not found',
126
+ status: 404,
127
+ });
128
+ }
129
+ /** Reads the caller's membership resolved by {@link ensureOrg}; `undefined` for `super_admin`. */
130
+ export function membership(c) {
131
+ return c.get('membership');
132
+ }
133
+ /** Reads the organization resolved by {@link ensureOrg}; throws when the middleware did not run. */
134
+ export function org(c) {
135
+ const record = c.get('org');
136
+ if (!record)
137
+ throw new Error('`orgScope` middleware must run before reading the organization');
138
+ return record;
139
+ }
140
+ /** Reads the project resolved by {@link ensureProject}; throws when the middleware did not run. */
141
+ export function project(c) {
142
+ const record = c.get('project');
143
+ if (!record)
144
+ throw new Error('`projectScope` middleware must run before reading the project');
145
+ return record;
146
+ }
147
+ // Reads the app's database source from request context (set by `App.create`
148
+ // from its `db` option).
149
+ function contextDb(c) {
150
+ return c.get('db');
151
+ }
19
152
  /**
20
153
  * Always false at runtime, but typed as `boolean` so handlers can include a
21
154
  * never-reached access-error branch in Hono's inferred response union.
@@ -55,6 +188,31 @@ export function accessError(c) {
55
188
  status: 429,
56
189
  });
57
190
  }
191
+ /** Typed lane-less policy error response for Hono client inference. Never reached at runtime. */
192
+ export function superAdminAccessError(c) {
193
+ const status = Number(c.req.header('tempo-narrow-access-status'));
194
+ if (status === 400)
195
+ return Response.error(c, {
196
+ code: 'api_key_malformed',
197
+ message: 'Malformed API key',
198
+ status: 400,
199
+ });
200
+ if (status === 401) {
201
+ const code = c.req.header('tempo-narrow-access-code') === 'api_key_missing'
202
+ ? 'api_key_missing'
203
+ : 'api_key_invalid';
204
+ return Response.error(c, {
205
+ code,
206
+ message: 'Missing or invalid API key',
207
+ status: 401,
208
+ });
209
+ }
210
+ return Response.error(c, {
211
+ code: 'forbidden',
212
+ message: 'API key not permitted for this route',
213
+ status: 403,
214
+ });
215
+ }
58
216
  /** Typed auth/payment error response for Hono client inference. Never reached at runtime. */
59
217
  export function paidAccessError(c) {
60
218
  const status = Number(c.req.header('tempo-narrow-access-status'));
@@ -68,17 +226,24 @@ export function paidAccessError(c) {
68
226
  export function middleware(options) {
69
227
  const { charge = {}, ...mpp } = options.mpp === false ? {} : (options.mpp ?? {});
70
228
  const defaults = laneDefaults(options);
71
- const base = basePolicy(options, defaults);
229
+ // Default-deny: no lanes open until a route grants them via `policy`.
230
+ // Otherwise the `super_admin` principal bypasses lane checks entirely.
231
+ const base = {};
232
+ // Keys resolve against the app's KV state store on request context
233
+ // (`App.create({ kv })`), so the middleware needs no storage wiring; when no
234
+ // store is configured, every token resolves to `null` (closed).
72
235
  // Resolution is cached per isolate by default (positive 60s / negative 10s,
73
- // keyed by token sha256 — see `ApiKeySource.cached`) so hot keys skip the
74
- // backend read on the auth path of every request. Pass `apiKey.cache: false`
75
- // when instant revocation matters more than the per-request read.
76
- const source = (() => {
77
- if (options.apiKey === false || !options.apiKey?.source)
78
- return ApiKeySource.noop;
79
- if (options.apiKey.cache === false)
80
- return options.apiKey.source;
81
- return ApiKeySource.cached(options.apiKey.source, options.apiKey.cache);
236
+ // keyed by token sha256) so hot keys skip the backend read on the auth path
237
+ // of every request. Pass `apiKey.cache: false` when instant revocation
238
+ // matters more than the per-request read.
239
+ const resolve = (() => {
240
+ const uncached = (c, token) => {
241
+ const kv = contextKv(c);
242
+ return kv ? ApiKeys.resolve(kv.store, token) : Promise.resolve(null);
243
+ };
244
+ if (options.apiKey === false || options.apiKey?.cache === false)
245
+ return uncached;
246
+ return cachedResolve(uncached, options.apiKey?.cache ?? {});
82
247
  })();
83
248
  const auth = {
84
249
  ...(options.apiKey === false
@@ -86,7 +251,7 @@ export function middleware(options) {
86
251
  : {
87
252
  apiKey: {
88
253
  ...(options.apiKey?.rateLimits ? { rateLimits: options.apiKey.rateLimits } : {}),
89
- source,
254
+ resolve,
90
255
  },
91
256
  }),
92
257
  ...(options.mpp === false
@@ -99,6 +264,10 @@ export function middleware(options) {
99
264
  }),
100
265
  }),
101
266
  rateLimit: RateLimit.memory(options.rateLimit),
267
+ ...(options.session ? { session: options.session } : {}),
268
+ ...(options.superAdmin?.secret
269
+ ? { superAdmin: { tokenHash: ApiKey.hash(options.superAdmin.secret) } }
270
+ : {}),
102
271
  };
103
272
  return createMiddleware((c, next) => {
104
273
  const route = openApiRoute(c);
@@ -113,6 +282,220 @@ export function middleware(options) {
113
282
  return require(endpointPolicy)(c, next);
114
283
  });
115
284
  }
285
+ /** Zod schemas documenting the session sign-in surface (`/v1/auth/siwe`). */
286
+ var schema;
287
+ (function (schema) {
288
+ const siweMessage = 'api.tempo.xyz wants you to sign in with your Ethereum account:\n0x0000000000000000000000000000000000000000\n\nURI: https://api.tempo.xyz\nVersion: 1\nChain ID: 0\nNonce: 3D0sZfnHqTBmc9tKR\nIssued At: 2026-01-01T00:00:00.000Z\nExpiration Time: 2026-01-01T00:10:00.000Z';
289
+ /** Error body returned by the sign-in handler (SDK shape, not the API error envelope). */
290
+ schema.HandlerError = z.object({
291
+ error: z
292
+ .string()
293
+ .check(z.describe('Human-readable failure reason.'), z.meta({ examples: ['domain mismatch'] })),
294
+ issues: z
295
+ .optional(z.array(z.unknown()))
296
+ .check(z.describe('Field-level validation issues, present on request-schema failures.')),
297
+ });
298
+ /** Schemas for `POST /v1/auth/siwe/challenge`. */
299
+ let challenge;
300
+ (function (challenge) {
301
+ /** Request body. Accepted fields beyond this document pass through to the SDK handler. */
302
+ challenge.Body = z.object({});
303
+ /** Response body. */
304
+ challenge.Response = z.object({
305
+ message: z
306
+ .string()
307
+ .check(z.describe('Single-use EIP-4361 (SIWE) message to sign and submit for verification.'), z.meta({ examples: [siweMessage] })),
308
+ });
309
+ })(challenge = schema.challenge || (schema.challenge = {}));
310
+ /** Schemas for `POST /v1/auth/siwe` (verify). */
311
+ let verify;
312
+ (function (verify) {
313
+ /** Request body. */
314
+ verify.Body = z.object({
315
+ address: z
316
+ .string()
317
+ .check(z.describe('Wallet address that signed the message; becomes the session subject.'), z.meta({ examples: ['0x0000000000000000000000000000000000000001'] })),
318
+ idToken: z.optional(z.string()).check(z.describe('Wallet-minted OIDC identity token (JWT) asserting a verified email, folded onto the session.'), // prettier-ignore
319
+ z.meta({ examples: ['eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIweDAwMDAifQ.c2lnbmF0dXJl'] })),
320
+ keyAuthorization: z.optional(z.string()).check(z.describe('RLP-serialized signed key authorization (TIP-1053) whose witness binds this message; verification recovers over its digest.'), // prettier-ignore
321
+ z.meta({ examples: [`0x${'aa'.repeat(60)}`] })),
322
+ message: z
323
+ .string()
324
+ .check(z.describe('The exact challenge message issued by `POST /v1/auth/siwe/challenge`.'), z.meta({ examples: [siweMessage] })),
325
+ returnToken: z.optional(z.boolean()).check(z.describe('Return the session token in the body instead of setting the session cookie.'), // prettier-ignore
326
+ z.meta({ examples: [true] })),
327
+ signature: z
328
+ .string()
329
+ .check(z.describe('Signature over the challenge message (or the key-authorization digest).'), z.meta({ examples: [`0x${'aa'.repeat(65)}`] })),
330
+ });
331
+ /** Response body. */
332
+ verify.Response = z.object({
333
+ token: z
334
+ .optional(z.string())
335
+ .check(z.describe('Bearer session token; present only when `returnToken` is true.'), z.meta({ examples: ['aa'.repeat(32)] })),
336
+ });
337
+ })(verify = schema.verify || (schema.verify = {}));
338
+ })(schema || (schema = {}));
339
+ /** `{ error }` response for a sign-in handler failure status. */
340
+ function handlerError(description) {
341
+ return {
342
+ content: { 'application/json': { schema: OpenApi.resolver(schema.HandlerError) } },
343
+ description,
344
+ };
345
+ }
346
+ /**
347
+ * Builds the built-in auth pieces from `App.create`'s `auth` option: the
348
+ * session-surface app to mount (when `session` is configured) and the
349
+ * enforcement middleware, wired with the surface's resolver. `auth: false`
350
+ * disables both.
351
+ */
352
+ export function install(options) {
353
+ const { db, kv } = options;
354
+ const { session: options_session, ...options_middleware } = options.auth === false ? {} : (options.auth ?? {});
355
+ if (options_session && !kv)
356
+ throw new Error('`auth.session` requires the `kv` state store: sessions and sign-in challenges persist there.'); // prettier-ignore
357
+ // Session sign-in surface (challenge, verify, logout — SIWE wallet sign-in
358
+ // today) plus the capability the session lane resolves through. Public but
359
+ // policy-gated: the hidden describeRoute engages the middleware for the
360
+ // mounted sub-app, and the public lane rate-limits challenge-store writes.
361
+ const app = (() => {
362
+ if (!options_session || !kv)
363
+ return undefined;
364
+ const { issuer, origin, ttl } = (typeof options_session === 'object' ? options_session.wallet : undefined) ?? {};
365
+ const handler = Accounts.Handler.auth({
366
+ ...(issuer ? { identity: { issuer } } : {}),
367
+ // Sign-in upserts the `users` row keyed by address.
368
+ onAuthenticate: async ({ address }) => {
369
+ await Users.upsertByAddress(Db.get(db), { address });
370
+ },
371
+ // No pinned origin: on Workers the edge proxy headers are trustworthy, so
372
+ // opt in explicitly (the SDK's guard ignores its own Workers default).
373
+ // Off-Workers the SDK keeps throwing until `wallet.origin` is set.
374
+ ...(origin
375
+ ? { origin }
376
+ : globalThis.navigator?.userAgent === 'Cloudflare-Workers'
377
+ ? { trustProxy: true }
378
+ : {}),
379
+ // The app's KV store under the SDK's Kv contract: JSON values,
380
+ // second-based TTLs, `auth:`-prefixed keys disjoint from API-key
381
+ // records. `take` is omitted; the SDK falls back to get+delete.
382
+ store: {
383
+ async delete(key) {
384
+ await kv.store.delete(`auth:${key}`);
385
+ },
386
+ async get(key) {
387
+ const value = await kv.store.get(`auth:${key}`);
388
+ return value === null ? undefined : JSON.parse(value);
389
+ },
390
+ async set(key, value, options) {
391
+ await kv.store.put(`auth:${key}`, JSON.stringify(value), options?.ttl ? { ttl: options.ttl * 1_000 } : {});
392
+ },
393
+ },
394
+ ...(ttl ? { ttl } : {}),
395
+ });
396
+ const session = {
397
+ resolve: async (c) => {
398
+ const payload = await handler.getSession(c.req.raw);
399
+ if (!payload)
400
+ return null;
401
+ const database = Db.get(db);
402
+ const user = await Users.getByAddress(database, payload.address);
403
+ if (!user)
404
+ return null;
405
+ // Fold a newly verified email onto the user row: identity tokens are
406
+ // optional per sign-in, so the column fills lazily.
407
+ if (payload.email && user.email !== payload.email)
408
+ await Users.setEmail(database, user.id, payload.email);
409
+ const email = payload.email ?? user.email ?? undefined;
410
+ return {
411
+ ...(email ? { email } : {}),
412
+ id: user.id,
413
+ identity: { provider: 'wallet', subject: payload.address },
414
+ type: 'session',
415
+ };
416
+ },
417
+ };
418
+ const policy_public = policy({ public: true });
419
+ const describe = OpenApi.describeRoute({ hide: true });
420
+ const app = new Hono()
421
+ .use('/v1/auth/siwe', policy_public, describe)
422
+ .use('/v1/auth/siwe/*', policy_public, describe);
423
+ // Documented operations: pre-routes carrying the OpenAPI metadata and the
424
+ // envelope-shaped body validation; the mounted handler owns behavior.
425
+ // Statement form keeps them off the app type (`hc` surface).
426
+ app.post('/v1/auth/siwe/challenge', policy_public, OpenApi.validate('json', schema.challenge.Body, {
427
+ code: 'body_invalid',
428
+ message: 'Invalid request body',
429
+ }), OpenApi.describeRoute({
430
+ description: 'Issues a single-use SIWE challenge message to sign. The challenge expires after a short TTL.',
431
+ // Overrides the surface-wide hidden mount guard for this documented route.
432
+ hide: false,
433
+ operationId: 'createSiweChallenge',
434
+ responses: {
435
+ 200: {
436
+ content: { 'application/json': { schema: OpenApi.resolver(schema.challenge.Response) } }, // prettier-ignore
437
+ description: 'The challenge message to sign.',
438
+ headers: { ...OpenApi.successHeaders },
439
+ },
440
+ 400: OpenApi.standardError(400, 'Malformed request body.', ['body_invalid']),
441
+ 429: OpenApi.standardError(429, 'Rate limited.'),
442
+ 500: OpenApi.standardError(500, 'Internal server error.'),
443
+ },
444
+ summary: 'Create challenge (SIWE)',
445
+ tags: ['Authentication'],
446
+ }));
447
+ app.post('/v1/auth/siwe', policy_public, OpenApi.validate('json', schema.verify.Body, {
448
+ code: 'body_invalid',
449
+ message: 'Invalid request body',
450
+ }), OpenApi.describeRoute({
451
+ description: 'Verifies the signed challenge and establishes a session. Sets a session cookie by default; pass `returnToken` to receive a bearer token instead.',
452
+ hide: false,
453
+ operationId: 'verifySiwe',
454
+ responses: {
455
+ 200: {
456
+ content: { 'application/json': { schema: OpenApi.resolver(schema.verify.Response) } },
457
+ description: 'Session established. Cookie mode sets `Set-Cookie`; token mode returns `token`.', // prettier-ignore
458
+ headers: {
459
+ ...OpenApi.successHeaders,
460
+ 'Set-Cookie': {
461
+ description: 'Session cookie (`accounts_auth`); omitted when `returnToken` is true.', // prettier-ignore
462
+ schema: { type: 'string' },
463
+ },
464
+ },
465
+ },
466
+ 400: handlerError('Invalid, expired, or mismatched challenge message.'),
467
+ 401: handlerError('Signature or identity verification failed.'),
468
+ 409: handlerError('Challenge nonce already used or unknown.'),
469
+ 429: OpenApi.standardError(429, 'Rate limited.'),
470
+ 500: OpenApi.standardError(500, 'Internal server error.'),
471
+ },
472
+ summary: 'Authenticate (SIWE)',
473
+ tags: ['Authentication'],
474
+ }));
475
+ app.post('/v1/auth/siwe/logout', policy_public, OpenApi.describeRoute({
476
+ description: 'Revokes the current session and clears the session cookie.',
477
+ hide: false,
478
+ operationId: 'siweLogout',
479
+ responses: {
480
+ 204: { description: 'Session revoked and cookie cleared.' },
481
+ 429: OpenApi.standardError(429, 'Rate limited.'),
482
+ 500: OpenApi.standardError(500, 'Internal server error.'),
483
+ },
484
+ summary: 'Sign out',
485
+ tags: ['Authentication'],
486
+ }));
487
+ return Object.assign(
488
+ // The tag joins the `Platform API` group at `platform()`'s chosen slot;
489
+ // group listings filter to defined tags, so it drops out when unmounted.
490
+ Metadata.attach(app.route('/v1/auth/siwe', handler), {
491
+ tags: [{ name: 'Authentication', description: 'Authenticate into the Tempo Platform.' }],
492
+ }), { session });
493
+ })();
494
+ const middleware_ = options.auth === false
495
+ ? undefined
496
+ : middleware({ ...options_middleware, ...(app ? { session: app.session } : {}) });
497
+ return { app, middleware: middleware_ };
498
+ }
116
499
  /** Creates route middleware that contributes an auth policy override. */
117
500
  export function policy(options) {
118
501
  const middleware = createMiddleware((_, next) => next());
@@ -137,21 +520,14 @@ function laneDefaults(options) {
137
520
  },
138
521
  mpp: { charge: {} },
139
522
  public: { rateLimit: public_?.rateLimit ?? { perMinute: 60 } },
523
+ session: true,
140
524
  };
141
525
  }
142
- /**
143
- * Base policy before route overrides. Default-closed except the API-key lane:
144
- * a route that declares nothing is API-key-only, and must opt into the public
145
- * and paid lanes explicitly. This makes a partial override fail safe — omitting
146
- * a lane leaves it closed rather than silently inheriting open access.
147
- */
148
- function basePolicy(options, defaults) {
149
- return options.apiKey === false ? {} : { apiKey: defaults.apiKey };
150
- }
151
526
  function resolvePolicy(base, defaults, overrides, description) {
152
527
  let apiKey = base.apiKey;
153
528
  let mpp = base.mpp;
154
529
  let public_ = base.public;
530
+ let session = base.session;
155
531
  for (const override of overrides) {
156
532
  if (override === false)
157
533
  return undefined;
@@ -160,18 +536,20 @@ function resolvePolicy(base, defaults, overrides, description) {
160
536
  apiKey = resolveApiKeyLane(apiKey, override.apiKey, defaults.apiKey);
161
537
  mpp = resolveMppLane(mpp, override.mpp, defaults.mpp);
162
538
  public_ = resolvePublicLane(public_, override.public, defaults.public);
539
+ session = resolveSessionLane(session, override.session, defaults.session);
163
540
  }
164
541
  // The OpenAPI summary/description rides along as the payment-challenge
165
542
  // description. It is metadata, not a policy override, so it only applies when
166
543
  // the paid lane is actually enabled and has no explicit description already.
167
544
  if (mpp && description !== undefined && mpp.charge.description === undefined)
168
545
  mpp = { charge: { ...mpp.charge, description } };
169
- if (!apiKey && !mpp && !public_)
170
- return undefined;
546
+ // A lane-less policy stays enforced for super admin; only an explicit
547
+ // `false` override opts a route out of auth entirely.
171
548
  return {
172
549
  ...(apiKey ? { apiKey } : {}),
173
550
  ...(mpp ? { mpp } : {}),
174
551
  ...(public_ ? { public: public_ } : {}),
552
+ ...(session ? { session } : {}),
175
553
  };
176
554
  }
177
555
  function resolveApiKeyLane(current, override, default_) {
@@ -207,6 +585,13 @@ function resolvePublicLane(current, override, default_) {
207
585
  const base = current ?? default_;
208
586
  return { rateLimit: override.rateLimit ?? base.rateLimit };
209
587
  }
588
+ function resolveSessionLane(current, override, default_) {
589
+ if (override === undefined)
590
+ return current;
591
+ if (override === false)
592
+ return undefined;
593
+ return current ?? default_;
594
+ }
210
595
  function openApiRoute(c) {
211
596
  const route = matchedRoutes(c)
212
597
  .slice(c.req.routeIndex + 1)
@@ -243,8 +628,8 @@ function policyFromRoute(route) {
243
628
  * Maps each documented operation id to its resolved access lanes by reading the
244
629
  * `policy` overrides co-located on the app's routes. This is the single source
245
630
  * of truth for per-operation `security` and the `402` response in the generated
246
- * OpenAPI document (see `App.create`): the API-key lane is default-on, and the
247
- * public/MPP lanes apply only where a route opts in via {@link policy}.
631
+ * OpenAPI document (see `App.create`): all lanes are default-closed, and an
632
+ * operation surfaces only the lanes its route opts into via {@link policy}.
248
633
  */
249
634
  export function describeAccess(app) {
250
635
  const groups = new Map();
@@ -263,10 +648,11 @@ export function describeAccess(app) {
263
648
  for (const { operationId, overrides } of groups.values()) {
264
649
  if (!operationId)
265
650
  continue;
266
- let apiKey = true;
651
+ let apiKey = false;
267
652
  let scopes = [];
268
653
  let public_ = false;
269
654
  let mpp = false;
655
+ let session = false;
270
656
  for (const override of overrides) {
271
657
  if (override.apiKey !== undefined)
272
658
  apiKey = override.apiKey !== false;
@@ -276,8 +662,10 @@ export function describeAccess(app) {
276
662
  public_ = override.public !== false;
277
663
  if (override.mpp !== undefined)
278
664
  mpp = override.mpp !== false;
665
+ if (override.session !== undefined)
666
+ session = override.session !== false;
279
667
  }
280
- access[operationId] = { mpp, public: public_, scopes: apiKey ? scopes : [] };
668
+ access[operationId] = { apiKey, mpp, public: public_, scopes: apiKey ? scopes : [], session };
281
669
  }
282
670
  return access;
283
671
  }
@@ -329,13 +717,30 @@ export function require(policy) {
329
717
  });
330
718
  const hasPayment = hasPaymentCredential(c) && isPaymentEnabled(auth, policy);
331
719
  if (credential) {
332
- const apiKey = await auth.apiKey?.source.resolve(credential.token);
333
- if (!apiKey)
720
+ // The super admin secret precedes key lookup: it is not a stored key.
721
+ // It must never reach KV resolution or scope/quota checks.
722
+ if (auth.superAdmin && ApiKey.hash(credential.token) === auth.superAdmin.tokenHash) {
723
+ c.set('principal', { actor: 'super_admin', id: 'super_admin', type: 'super_admin' });
724
+ return next();
725
+ }
726
+ const apiKey = await auth.apiKey?.resolve(c, credential.token);
727
+ if (!apiKey) {
728
+ // A bearer session token is indistinguishable from an API key at the
729
+ // header, so a failed key lookup falls through to the session lane
730
+ // before rejecting.
731
+ if (policy.session) {
732
+ const session = await resolveSession(c, auth);
733
+ if (session) {
734
+ c.set('principal', session);
735
+ return next();
736
+ }
737
+ }
334
738
  return jsonError(c, {
335
739
  code: 'api_key_invalid',
336
740
  message: 'Invalid API key',
337
741
  status: 401,
338
742
  });
743
+ }
339
744
  // Sandbox keys are restricted to non-mainnet chains. An explicit
340
745
  // `chainId` of mainnet makes the key unusable for this request, so it is
341
746
  // ignored and the request falls through to the public policy below (as if
@@ -354,6 +759,14 @@ export function require(policy) {
354
759
  c.set('chainId', Viem.chainId.testnet);
355
760
  const principal = principalFromApiKey(apiKey);
356
761
  c.set('principal', principal);
762
+ // Default-deny: routes with no API-key lane allow only the super admin.
763
+ // A valid key is authenticated but forbidden.
764
+ if (!policy.apiKey)
765
+ return jsonError(c, {
766
+ code: 'forbidden',
767
+ message: 'API key not permitted for this route',
768
+ status: 403,
769
+ });
357
770
  const missing = apiKey.scopes.includes(Scope.wildcard)
358
771
  ? []
359
772
  : (policy.apiKey?.scopes.filter((scope) => !apiKey.scopes.includes(scope)) ?? []);
@@ -399,6 +812,16 @@ export function require(policy) {
399
812
  return next();
400
813
  }
401
814
  }
815
+ // Cookie sessions carry no Authorization credential; resolve the session
816
+ // lane before the public/paid lanes so signed-in browsers skip anonymous
817
+ // quotas.
818
+ if (policy.session) {
819
+ const session = await resolveSession(c, auth);
820
+ if (session) {
821
+ c.set('principal', session);
822
+ return next();
823
+ }
824
+ }
402
825
  const publicPrincipal = principalFromPublic(c);
403
826
  if (hasPayment) {
404
827
  c.set('principal', publicPrincipal);
@@ -446,16 +869,55 @@ export function require(policy) {
446
869
  });
447
870
  });
448
871
  }
872
+ /**
873
+ * How long to wait for the rate-limit counter before failing open. A hot
874
+ * counter backend (e.g. a single Durable Object serving one busy quota bucket)
875
+ * can stall for tens of seconds during a storage-latency blip; without this cap
876
+ * every request for that bucket blocks on it, turning a localized backend
877
+ * hiccup into an API-wide latency spike. The abandoned increment still applies
878
+ * server-side — we just stop waiting for it.
879
+ */
880
+ const rateLimitConsumeTimeout = 300;
449
881
  function consumeRateLimit(auth, options) {
450
882
  if (!auth.rateLimit)
451
883
  return Promise.resolve(null);
452
- // Fail open: a rate-limit store error (e.g. a lost Durable Object
453
- // connection) degrades to unenforced quota instead of failing the request.
454
- return auth.rateLimit.consume(options).catch((error) => {
455
- console.error('[auth] rate-limit consume failed; failing open', error);
884
+ // Fail open: a rate-limit store error (e.g. a lost Durable Object connection)
885
+ // or a stall past `rateLimitConsumeTimeout` degrades to unenforced quota
886
+ // instead of failing — or blocking — the request.
887
+ return withTimeout(auth.rateLimit.consume(options), rateLimitConsumeTimeout).catch((error) => {
888
+ // A timeout or Cloudflare Durable Object overload is an expected
889
+ // degradation (a slow/hot counter backend), logged at warn so it stays out
890
+ // of error dashboards; an unexpected store throw is a genuine error.
891
+ if (error instanceof RateLimitTimeoutError || isDurableObjectOverload(error))
892
+ console.warn('[auth] rate-limit consume degraded; failing open', error);
893
+ else
894
+ console.error('[auth] rate-limit consume failed; failing open', error);
456
895
  return null;
457
896
  });
458
897
  }
898
+ function isDurableObjectOverload(error) {
899
+ return (typeof error === 'object' &&
900
+ error !== null &&
901
+ 'overloaded' in error &&
902
+ error.overloaded === true);
903
+ }
904
+ /**
905
+ * Rejects with a {@link RateLimitTimeoutError} if `promise` does not settle
906
+ * within `ms`, clearing the timer on either outcome so it never keeps the
907
+ * isolate alive.
908
+ */
909
+ function withTimeout(promise, ms) {
910
+ return new Promise((resolve, reject) => {
911
+ const timer = setTimeout(() => reject(new RateLimitTimeoutError(ms)), ms);
912
+ promise.then((value) => {
913
+ clearTimeout(timer);
914
+ resolve(value);
915
+ }, (error) => {
916
+ clearTimeout(timer);
917
+ reject(error);
918
+ });
919
+ });
920
+ }
459
921
  /**
460
922
  * Resolves the rate limit for an API-key request against a quota bucket.
461
923
  * Most-specific wins: a per-key per-scope grant is the only thing that pierces a
@@ -566,6 +1028,7 @@ function principalFromApiKey(apiKey) {
566
1028
  environment: apiKey.environment,
567
1029
  id: apiKey.id,
568
1030
  orgId: apiKey.orgId,
1031
+ ...(apiKey.projectId === undefined ? {} : { projectId: apiKey.projectId }),
569
1032
  type: 'api_key',
570
1033
  };
571
1034
  }
@@ -615,4 +1078,80 @@ function setRateLimitHeaders(c, result) {
615
1078
  c.header('RateLimit-Remaining', String(result.remaining));
616
1079
  c.header('RateLimit-Reset', String(result.reset));
617
1080
  }
1081
+ // Reads the app's KV state store from request context (set by `App.create`
1082
+ // from its `kv` option); `undefined` leaves API-key auth closed.
1083
+ function contextKv(c) {
1084
+ return c.get('kv');
1085
+ }
1086
+ // Resolve the session lane from the auth context's capability. Failures
1087
+ // resolve to `null` so the remaining lanes and the final `401` still apply.
1088
+ async function resolveSession(c, auth) {
1089
+ const session = auth.session;
1090
+ if (!session)
1091
+ return null;
1092
+ try {
1093
+ return await session.resolve(c);
1094
+ }
1095
+ catch (error) {
1096
+ console.error('[auth] session resolve failed; treating as no session', error);
1097
+ return null;
1098
+ }
1099
+ }
1100
+ /** Maximum resolve-cache entries held per isolate before eviction. */
1101
+ const cachedMaxEntries = 10_000;
1102
+ /**
1103
+ * Wraps token resolution with a short-TTL per-isolate cache so hot keys skip
1104
+ * the backend read on every request. Positive results cache for `ttl`
1105
+ * (default 60s), negative for `negativeTtl` (default 10s) so a freshly minted
1106
+ * key is usable quickly; concurrent misses for one token are single-flighted.
1107
+ * Entries are keyed by the token's sha256 (`ApiKey.hash`) — never the
1108
+ * plaintext. A revoked key may stay resolvable for up to `ttl` — the accepted
1109
+ * trade-off for removing a backend read from the auth path.
1110
+ */
1111
+ function cachedResolve(resolve, options) {
1112
+ const { negativeTtl = 10_000, now = Date.now, ttl = 60_000 } = options;
1113
+ const cells = new Map();
1114
+ const flights = new Map();
1115
+ return async (c, token) => {
1116
+ // Versioned so a future record-shape change can't serve stale shapes.
1117
+ const key = `v1:${ApiKey.hash(token)}`;
1118
+ const cell = cells.get(key);
1119
+ if (cell && cell.expiresAt > now())
1120
+ return cell.value;
1121
+ if (cell)
1122
+ cells.delete(key);
1123
+ const existing = flights.get(key);
1124
+ if (existing)
1125
+ return existing;
1126
+ const flight = (async () => {
1127
+ const value = await resolve(c, token);
1128
+ // Bound the cache: random invalid tokens each add a (negative) entry,
1129
+ // so sweep expired cells at the cap and then drop the oldest.
1130
+ if (cells.size >= cachedMaxEntries) {
1131
+ const time = now();
1132
+ for (const [name, entry] of cells)
1133
+ if (entry.expiresAt <= time)
1134
+ cells.delete(name);
1135
+ while (cells.size >= cachedMaxEntries)
1136
+ cells.delete(cells.keys().next().value);
1137
+ }
1138
+ cells.set(key, { expiresAt: now() + (value ? ttl : negativeTtl), value });
1139
+ return value;
1140
+ })();
1141
+ flights.set(key, flight);
1142
+ try {
1143
+ return await flight;
1144
+ }
1145
+ finally {
1146
+ flights.delete(key);
1147
+ }
1148
+ };
1149
+ }
1150
+ /** Thrown when a rate-limit consume exceeds {@link rateLimitConsumeTimeout}. */
1151
+ export class RateLimitTimeoutError extends Error {
1152
+ name = 'Auth.RateLimitTimeoutError';
1153
+ constructor(ms) {
1154
+ super(`Rate-limit consume timed out after ${ms}ms; failing open.`);
1155
+ }
1156
+ }
618
1157
  //# sourceMappingURL=Auth.js.map