tapimo 0.15.1 → 0.18.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 (709) hide show
  1. package/README.md +137 -0
  2. package/dist/ApiKey.d.ts +1 -0
  3. package/dist/ApiKey.d.ts.map +1 -1
  4. package/dist/ApiKey.js +4 -2
  5. package/dist/ApiKey.js.map +1 -1
  6. package/dist/ApiKeys.d.ts +37 -11
  7. package/dist/ApiKeys.d.ts.map +1 -1
  8. package/dist/ApiKeys.js +163 -10
  9. package/dist/ApiKeys.js.map +1 -1
  10. package/dist/App.d.ts +13085 -11974
  11. package/dist/App.d.ts.map +1 -1
  12. package/dist/App.js +46 -15
  13. package/dist/App.js.map +1 -1
  14. package/dist/Scope.d.ts +1 -1
  15. package/dist/Scope.d.ts.map +1 -1
  16. package/dist/Scope.js +1 -1
  17. package/dist/Scope.js.map +1 -1
  18. package/dist/admin/App.d.ts +893 -191
  19. package/dist/admin/App.d.ts.map +1 -1
  20. package/dist/admin/App.js +5 -1
  21. package/dist/admin/App.js.map +1 -1
  22. package/dist/admin/apps/api-keys.d.ts +70 -70
  23. package/dist/admin/apps/api-keys.d.ts.map +1 -1
  24. package/dist/admin/apps/api-keys.js +8 -3
  25. package/dist/admin/apps/api-keys.js.map +1 -1
  26. package/dist/admin/apps/earn-vaults.d.ts +66 -27
  27. package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
  28. package/dist/admin/apps/earn-vaults.js +36 -7
  29. package/dist/admin/apps/earn-vaults.js.map +1 -1
  30. package/dist/admin/apps/organizations.d.ts +25 -25
  31. package/dist/admin/apps/organizations.d.ts.map +1 -1
  32. package/dist/admin/apps/organizations.js +5 -4
  33. package/dist/admin/apps/organizations.js.map +1 -1
  34. package/dist/admin/apps/route-policies.d.ts +632 -0
  35. package/dist/admin/apps/route-policies.d.ts.map +1 -0
  36. package/dist/admin/apps/route-policies.js +257 -0
  37. package/dist/admin/apps/route-policies.js.map +1 -0
  38. package/dist/admin/apps/routes-support.js +39 -3
  39. package/dist/admin/apps/routes-support.js.map +1 -1
  40. package/dist/admin/apps/routes.d.ts +529 -76
  41. package/dist/admin/apps/routes.d.ts.map +1 -1
  42. package/dist/admin/apps/routes.js +82 -1
  43. package/dist/admin/apps/routes.js.map +1 -1
  44. package/dist/admin/apps/verified-tokens.d.ts +157 -157
  45. package/dist/admin/index.d.ts +0 -1
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +0 -1
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/admin/ui.generated.d.ts +1 -1
  50. package/dist/admin/ui.generated.d.ts.map +1 -1
  51. package/dist/admin/ui.generated.js +205 -201
  52. package/dist/admin/ui.generated.js.map +1 -1
  53. package/dist/analytics/Analytics.d.ts.map +1 -1
  54. package/dist/analytics/Analytics.js +65 -1
  55. package/dist/analytics/Analytics.js.map +1 -1
  56. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  57. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  58. package/dist/analytics/tables/requestEvents.js +58 -59
  59. package/dist/analytics/tables/requestEvents.js.map +1 -1
  60. package/dist/apps/data/App.d.ts +2709 -2670
  61. package/dist/apps/data/App.d.ts.map +1 -1
  62. package/dist/apps/data/routes/activities.d.ts +357 -357
  63. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  64. package/dist/apps/data/routes/activities.js +50 -0
  65. package/dist/apps/data/routes/activities.js.map +1 -1
  66. package/dist/apps/data/routes/addresses.d.ts +248 -248
  67. package/dist/apps/data/routes/balances.d.ts +22 -22
  68. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  69. package/dist/apps/data/routes/balances.js +5 -7
  70. package/dist/apps/data/routes/balances.js.map +1 -1
  71. package/dist/apps/data/routes/blocks.d.ts +125 -125
  72. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  73. package/dist/apps/data/routes/earn.d.ts +103 -12
  74. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  75. package/dist/apps/data/routes/earn.js +456 -220
  76. package/dist/apps/data/routes/earn.js.map +1 -1
  77. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  78. package/dist/apps/data/routes/exchanges.js +267 -97
  79. package/dist/apps/data/routes/exchanges.js.map +1 -1
  80. package/dist/apps/data/routes/fee-amm.d.ts +109 -127
  81. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.js +83 -54
  83. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  84. package/dist/apps/data/routes/indexer.d.ts +43 -43
  85. package/dist/apps/data/routes/receipts.d.ts +235 -235
  86. package/dist/apps/data/routes/rpc.d.ts +30 -30
  87. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  88. package/dist/apps/data/routes/tokens.js +11 -6
  89. package/dist/apps/data/routes/tokens.js.map +1 -1
  90. package/dist/apps/data/routes/transactions.d.ts +2 -0
  91. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  92. package/dist/apps/data/routes/transactions.js +30 -22
  93. package/dist/apps/data/routes/transactions.js.map +1 -1
  94. package/dist/apps/data/routes/transfers.d.ts +77 -77
  95. package/dist/apps/data/routes/valuation.d.ts +32 -32
  96. package/dist/apps/data/routes/verified-tokens.d.ts +86 -86
  97. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  98. package/dist/apps/data/routes/webhooks.js +1 -1
  99. package/dist/apps/data/routes/webhooks.js.map +1 -1
  100. package/dist/apps/data/routes/zones.d.ts +31 -31
  101. package/dist/apps/management/App.d.ts +2909 -2064
  102. package/dist/apps/management/App.d.ts.map +1 -1
  103. package/dist/apps/management/App.js +2 -0
  104. package/dist/apps/management/App.js.map +1 -1
  105. package/dist/apps/management/Billing.d.ts +2 -4
  106. package/dist/apps/management/Billing.d.ts.map +1 -1
  107. package/dist/apps/management/Billing.js +65 -26
  108. package/dist/apps/management/Billing.js.map +1 -1
  109. package/dist/apps/management/routes/api-keys.d.ts +257 -245
  110. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  111. package/dist/apps/management/routes/api-keys.js +70 -11
  112. package/dist/apps/management/routes/api-keys.js.map +1 -1
  113. package/dist/apps/management/routes/billing.d.ts +84 -84
  114. package/dist/apps/management/routes/cli.d.ts +912 -0
  115. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  116. package/dist/apps/management/routes/cli.js +416 -0
  117. package/dist/apps/management/routes/cli.js.map +1 -0
  118. package/dist/apps/management/routes/faucet.d.ts +8 -8
  119. package/dist/apps/management/routes/invitations.d.ts +138 -138
  120. package/dist/apps/management/routes/invite-links.d.ts +172 -172
  121. package/dist/apps/management/routes/members.d.ts +16 -16
  122. package/dist/apps/management/routes/orgs.d.ts +104 -104
  123. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  124. package/dist/apps/management/routes/orgs.js +8 -2
  125. package/dist/apps/management/routes/orgs.js.map +1 -1
  126. package/dist/apps/management/routes/projects.d.ts +125 -125
  127. package/dist/apps/management/routes/usage.d.ts +8 -8
  128. package/dist/apps/management/routes/verified-token-requests.d.ts +86 -86
  129. package/dist/apps/management/routes/webhooks.d.ts +485 -485
  130. package/dist/apps/mpp/App.d.ts +44 -44
  131. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  132. package/dist/apps/mpp/internal/Policy.js +4 -2
  133. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  134. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  135. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  136. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  137. package/dist/apps/relay/App.d.ts +8 -0
  138. package/dist/apps/relay/App.d.ts.map +1 -1
  139. package/dist/apps/relay/App.js +16 -4
  140. package/dist/apps/relay/App.js.map +1 -1
  141. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  142. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  143. package/dist/apps/relay/Sponsorships.js +71 -60
  144. package/dist/apps/relay/Sponsorships.js.map +1 -1
  145. package/dist/apps/routes/Access.d.ts +53 -0
  146. package/dist/apps/routes/Access.d.ts.map +1 -1
  147. package/dist/apps/routes/Access.js +121 -0
  148. package/dist/apps/routes/Access.js.map +1 -1
  149. package/dist/apps/routes/App.d.ts +397 -158
  150. package/dist/apps/routes/App.d.ts.map +1 -1
  151. package/dist/apps/routes/App.js.map +1 -1
  152. package/dist/apps/routes/routes/chains.d.ts +25 -25
  153. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  154. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  155. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  156. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  157. package/dist/apps/routes/routes/quotes.d.ts +171 -81
  158. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  159. package/dist/apps/routes/routes/quotes.js +101 -27
  160. package/dist/apps/routes/routes/quotes.js.map +1 -1
  161. package/dist/apps/routes/routes/transfers.d.ts +532 -480
  162. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/transfers.js +182 -37
  164. package/dist/apps/routes/routes/transfers.js.map +1 -1
  165. package/dist/cli/ApiKeys.d.ts +120 -0
  166. package/dist/cli/ApiKeys.d.ts.map +1 -0
  167. package/dist/cli/ApiKeys.js +138 -0
  168. package/dist/cli/ApiKeys.js.map +1 -0
  169. package/dist/cli/Cli.d.ts +92 -34
  170. package/dist/cli/Cli.d.ts.map +1 -1
  171. package/dist/cli/Cli.js +188 -11
  172. package/dist/cli/Cli.js.map +1 -1
  173. package/dist/cli/Credentials.d.ts +95 -0
  174. package/dist/cli/Credentials.d.ts.map +1 -0
  175. package/dist/cli/Credentials.js +110 -0
  176. package/dist/cli/Credentials.js.map +1 -0
  177. package/dist/cli/Spec.d.ts +59 -0
  178. package/dist/cli/Spec.d.ts.map +1 -0
  179. package/dist/cli/Spec.js +77 -0
  180. package/dist/cli/Spec.js.map +1 -0
  181. package/dist/cli/bin.js +5 -1
  182. package/dist/cli/bin.js.map +1 -1
  183. package/dist/cli/commands/admin.d.ts +5 -5
  184. package/dist/cli/commands/admin.d.ts.map +1 -1
  185. package/dist/cli/commands/auth.d.ts +73 -0
  186. package/dist/cli/commands/auth.d.ts.map +1 -0
  187. package/dist/cli/commands/auth.js +204 -0
  188. package/dist/cli/commands/auth.js.map +1 -0
  189. package/dist/cli/commands/keys.d.ts +17 -0
  190. package/dist/cli/commands/keys.d.ts.map +1 -0
  191. package/dist/cli/commands/keys.js +109 -0
  192. package/dist/cli/commands/keys.js.map +1 -0
  193. package/dist/cloudflare.d.ts +27 -2
  194. package/dist/cloudflare.d.ts.map +1 -1
  195. package/dist/cloudflare.js +144 -17
  196. package/dist/cloudflare.js.map +1 -1
  197. package/dist/db/Db.d.ts +23 -0
  198. package/dist/db/Db.d.ts.map +1 -1
  199. package/dist/db/Db.js +413 -1
  200. package/dist/db/Db.js.map +1 -1
  201. package/dist/db/Schema.d.ts +44 -1
  202. package/dist/db/Schema.d.ts.map +1 -1
  203. package/dist/db/Schema.js +56 -3
  204. package/dist/db/Schema.js.map +1 -1
  205. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  206. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  207. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  208. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  209. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  210. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  211. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  212. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  213. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  214. package/dist/db/tables/authAccounts.js +1 -0
  215. package/dist/db/tables/authAccounts.js.map +1 -1
  216. package/dist/db/tables/earnVaults.d.ts +5 -1
  217. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  218. package/dist/db/tables/earnVaults.js +12 -1
  219. package/dist/db/tables/earnVaults.js.map +1 -1
  220. package/dist/db/tables/organizations.d.ts +4 -2
  221. package/dist/db/tables/organizations.d.ts.map +1 -1
  222. package/dist/db/tables/organizations.js +8 -34
  223. package/dist/db/tables/organizations.js.map +1 -1
  224. package/dist/db/tables/requestUsage.d.ts +5 -1
  225. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  226. package/dist/db/tables/requestUsage.js +10 -2
  227. package/dist/db/tables/requestUsage.js.map +1 -1
  228. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  229. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  230. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  231. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  232. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  233. package/dist/db/tables/rewardRuns.js +4 -0
  234. package/dist/db/tables/rewardRuns.js.map +1 -1
  235. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  236. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  237. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  238. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  239. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  240. package/dist/db/tables/routesDepositAddresses.js +84 -31
  241. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  242. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  243. package/dist/db/tables/routesDeposits.js +31 -21
  244. package/dist/db/tables/routesDeposits.js.map +1 -1
  245. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  246. package/dist/db/tables/routesIdempotency.js +2 -0
  247. package/dist/db/tables/routesIdempotency.js.map +1 -1
  248. package/dist/db/tables/routesPolicies.d.ts +58 -0
  249. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  250. package/dist/db/tables/routesPolicies.js +198 -0
  251. package/dist/db/tables/routesPolicies.js.map +1 -0
  252. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  253. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  254. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  255. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  256. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  257. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  258. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  259. package/dist/db/tables/routesTransfers.d.ts +26 -1
  260. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  261. package/dist/db/tables/routesTransfers.js +36 -6
  262. package/dist/db/tables/routesTransfers.js.map +1 -1
  263. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  264. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  265. package/dist/db/tables/sponsoredTransactions.js +144 -33
  266. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  267. package/dist/db/tables/users.d.ts +2 -0
  268. package/dist/db/tables/users.d.ts.map +1 -1
  269. package/dist/db/tables/users.js +11 -0
  270. package/dist/db/tables/users.js.map +1 -1
  271. package/dist/handlers/internal/multisig.d.ts +1 -1
  272. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  273. package/dist/handlers/internal/multisig.js +3 -2
  274. package/dist/handlers/internal/multisig.js.map +1 -1
  275. package/dist/handlers/relay.d.ts +2 -0
  276. package/dist/handlers/relay.d.ts.map +1 -1
  277. package/dist/handlers/relay.js +34 -15
  278. package/dist/handlers/relay.js.map +1 -1
  279. package/dist/internal/Auth.d.ts +57 -6
  280. package/dist/internal/Auth.d.ts.map +1 -1
  281. package/dist/internal/Auth.js +182 -78
  282. package/dist/internal/Auth.js.map +1 -1
  283. package/dist/internal/BetterAuth.d.ts +22 -0
  284. package/dist/internal/BetterAuth.d.ts.map +1 -1
  285. package/dist/internal/BetterAuth.js +17 -14
  286. package/dist/internal/BetterAuth.js.map +1 -1
  287. package/dist/internal/Cache.d.ts +5 -0
  288. package/dist/internal/Cache.d.ts.map +1 -1
  289. package/dist/internal/Cache.js +3 -1
  290. package/dist/internal/Cache.js.map +1 -1
  291. package/dist/internal/CliAuth.d.ts +243 -0
  292. package/dist/internal/CliAuth.d.ts.map +1 -0
  293. package/dist/internal/CliAuth.js +249 -0
  294. package/dist/internal/CliAuth.js.map +1 -0
  295. package/dist/internal/EarnSharePrices.d.ts +1 -1
  296. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  297. package/dist/internal/EarnSharePrices.js +7 -3
  298. package/dist/internal/EarnSharePrices.js.map +1 -1
  299. package/dist/internal/EarnVaults.d.ts +47 -0
  300. package/dist/internal/EarnVaults.d.ts.map +1 -1
  301. package/dist/internal/EarnVaults.js +188 -4
  302. package/dist/internal/EarnVaults.js.map +1 -1
  303. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  304. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  305. package/dist/internal/EarnWithdrawals.js +189 -0
  306. package/dist/internal/EarnWithdrawals.js.map +1 -0
  307. package/dist/internal/ExecutionContext.d.ts +21 -0
  308. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  309. package/dist/internal/ExecutionContext.js +16 -0
  310. package/dist/internal/ExecutionContext.js.map +1 -0
  311. package/dist/internal/Log.d.ts +7 -3
  312. package/dist/internal/Log.d.ts.map +1 -1
  313. package/dist/internal/Log.js +163 -130
  314. package/dist/internal/Log.js.map +1 -1
  315. package/dist/internal/MetricSink.d.ts.map +1 -1
  316. package/dist/internal/MetricSink.js +26 -1
  317. package/dist/internal/MetricSink.js.map +1 -1
  318. package/dist/internal/RateLimit.d.ts +67 -0
  319. package/dist/internal/RateLimit.d.ts.map +1 -1
  320. package/dist/internal/RateLimit.js +174 -27
  321. package/dist/internal/RateLimit.js.map +1 -1
  322. package/dist/internal/Store.d.ts +6 -0
  323. package/dist/internal/Store.d.ts.map +1 -1
  324. package/dist/internal/Store.js +4 -5
  325. package/dist/internal/Store.js.map +1 -1
  326. package/dist/internal/Timing.d.ts +6 -0
  327. package/dist/internal/Timing.d.ts.map +1 -1
  328. package/dist/internal/Timing.js +21 -1
  329. package/dist/internal/Timing.js.map +1 -1
  330. package/dist/internal/Tron.d.ts +124 -0
  331. package/dist/internal/Tron.d.ts.map +1 -0
  332. package/dist/internal/Tron.js +202 -0
  333. package/dist/internal/Tron.js.map +1 -0
  334. package/dist/internal/Viem.d.ts +4 -0
  335. package/dist/internal/Viem.d.ts.map +1 -1
  336. package/dist/internal/Viem.js +25 -6
  337. package/dist/internal/Viem.js.map +1 -1
  338. package/dist/internal/rewards/Read.d.ts +2 -2
  339. package/dist/internal/rewards/Read.d.ts.map +1 -1
  340. package/dist/internal/rewards/Read.js +11 -2
  341. package/dist/internal/rewards/Read.js.map +1 -1
  342. package/dist/internal/routes/Action.d.ts +27 -0
  343. package/dist/internal/routes/Action.d.ts.map +1 -1
  344. package/dist/internal/routes/Action.js +49 -1
  345. package/dist/internal/routes/Action.js.map +1 -1
  346. package/dist/internal/routes/Chain.d.ts +2 -0
  347. package/dist/internal/routes/Chain.d.ts.map +1 -1
  348. package/dist/internal/routes/Chain.js +4 -0
  349. package/dist/internal/routes/Chain.js.map +1 -1
  350. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  351. package/dist/internal/routes/DepositAddress.js +5 -0
  352. package/dist/internal/routes/DepositAddress.js.map +1 -1
  353. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  354. package/dist/internal/routes/Evidence.js +6 -2
  355. package/dist/internal/routes/Evidence.js.map +1 -1
  356. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  357. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  358. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  359. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  360. package/dist/internal/routes/Policy.d.ts +161 -0
  361. package/dist/internal/routes/Policy.d.ts.map +1 -0
  362. package/dist/internal/routes/Policy.js +249 -0
  363. package/dist/internal/routes/Policy.js.map +1 -0
  364. package/dist/internal/routes/Provider.d.ts +66 -3
  365. package/dist/internal/routes/Provider.d.ts.map +1 -1
  366. package/dist/internal/routes/Provider.js +106 -27
  367. package/dist/internal/routes/Provider.js.map +1 -1
  368. package/dist/internal/routes/Quota.d.ts +57 -0
  369. package/dist/internal/routes/Quota.d.ts.map +1 -0
  370. package/dist/internal/routes/Quota.js +144 -0
  371. package/dist/internal/routes/Quota.js.map +1 -0
  372. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  373. package/dist/internal/routes/Reconciliation.js +163 -47
  374. package/dist/internal/routes/Reconciliation.js.map +1 -1
  375. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  376. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  377. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  378. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  379. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  380. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  381. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  382. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  383. package/dist/internal/routes/Subsidy.d.ts +2 -2
  384. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  385. package/dist/internal/routes/Subsidy.js +2 -2
  386. package/dist/internal/routes/Subsidy.js.map +1 -1
  387. package/dist/internal/routes/Transfer.d.ts +229 -1
  388. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  389. package/dist/internal/routes/Transfer.js +644 -7
  390. package/dist/internal/routes/Transfer.js.map +1 -1
  391. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  392. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  393. package/dist/internal/routes/TransferReconciliation.js +83 -159
  394. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  395. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  396. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  397. package/dist/internal/routes/TransferSettlement.js +2 -0
  398. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  399. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  400. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  401. package/dist/internal/routes/TransferSubsidy.js +64 -5
  402. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  403. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  404. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  405. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  406. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  407. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  408. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  409. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  410. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  411. package/dist/internal/routes/index.d.ts +3 -0
  412. package/dist/internal/routes/index.d.ts.map +1 -1
  413. package/dist/internal/routes/index.js +3 -0
  414. package/dist/internal/routes/index.js.map +1 -1
  415. package/dist/internal/routes/providers/across.d.ts +3 -0
  416. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  417. package/dist/internal/routes/providers/across.js +11 -0
  418. package/dist/internal/routes/providers/across.js.map +1 -1
  419. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  420. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  421. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  422. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  423. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  424. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  425. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  426. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  427. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  428. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  429. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  430. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  431. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  432. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  434. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  435. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  436. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/propAmm.js +524 -0
  438. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  439. package/dist/internal/routes/providers/relay.d.ts +3 -0
  440. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  441. package/dist/internal/routes/providers/relay.js +352 -41
  442. package/dist/internal/routes/providers/relay.js.map +1 -1
  443. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  444. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  445. package/dist/internal/routes/providers/rhino.js +11 -0
  446. package/dist/internal/routes/providers/rhino.js.map +1 -1
  447. package/dist/internal/routes/providers/squid.d.ts +3 -0
  448. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  449. package/dist/internal/routes/providers/squid.js +19 -0
  450. package/dist/internal/routes/providers/squid.js.map +1 -1
  451. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  452. package/dist/internal/routes/providers/stargate.js +22 -9
  453. package/dist/internal/routes/providers/stargate.js.map +1 -1
  454. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  455. package/dist/internal/routes/providers/symbiosis.js +13 -17
  456. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  457. package/dist/providers/index.d.ts +14 -0
  458. package/dist/providers/index.d.ts.map +1 -1
  459. package/dist/providers/index.js +6 -0
  460. package/dist/providers/index.js.map +1 -1
  461. package/package.json +16 -6
  462. package/src/ApiKey.ts +7 -3
  463. package/src/ApiKeys.test.ts +652 -8
  464. package/src/ApiKeys.ts +191 -11
  465. package/src/App.test.ts +405 -18
  466. package/src/App.ts +51 -15
  467. package/src/Client.test-d.ts +157 -10
  468. package/src/Client.test.ts +4 -4
  469. package/src/Scope.ts +1 -2
  470. package/src/admin/App.ts +11 -5
  471. package/src/admin/apps/api-keys.test.ts +98 -2
  472. package/src/admin/apps/api-keys.ts +21 -12
  473. package/src/admin/apps/earn-vaults.test.ts +76 -7
  474. package/src/admin/apps/earn-vaults.ts +47 -8
  475. package/src/admin/apps/organizations.test.ts +147 -31
  476. package/src/admin/apps/organizations.ts +5 -4
  477. package/src/admin/apps/route-policies.test.ts +220 -0
  478. package/src/admin/apps/route-policies.ts +322 -0
  479. package/src/admin/apps/routes-support.test.ts +107 -2
  480. package/src/admin/apps/routes-support.ts +43 -3
  481. package/src/admin/apps/routes.test.ts +150 -0
  482. package/src/admin/apps/routes.ts +97 -1
  483. package/src/admin/apps/scopes.test.ts +1 -1
  484. package/src/admin/index.ts +0 -1
  485. package/src/admin/ui/plugin.ts +2 -1
  486. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  487. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  488. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  489. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  490. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  491. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  492. package/src/admin/ui/src/lib/routes.ts +34 -0
  493. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  494. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  495. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  496. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  497. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  498. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  499. package/src/admin/ui/src/routes/organizations.tsx +1 -0
  500. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  501. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  502. package/src/admin/ui/src/routes/routes.tsx +85 -2
  503. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  504. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  505. package/src/admin/ui/src/routes/verified-tokens.tsx +1 -0
  506. package/src/admin/ui.generated.ts +258 -202
  507. package/src/analytics/Analytics.test.ts +4 -50
  508. package/src/analytics/Analytics.ts +65 -1
  509. package/src/analytics/tables/requestEvents.test.ts +402 -1
  510. package/src/analytics/tables/requestEvents.ts +62 -93
  511. package/src/apps/data/routes/activities.test.ts +315 -14
  512. package/src/apps/data/routes/activities.ts +60 -0
  513. package/src/apps/data/routes/balances.ts +5 -7
  514. package/src/apps/data/routes/earn.bench.ts +18 -0
  515. package/src/apps/data/routes/earn.local.test.ts +507 -0
  516. package/src/apps/data/routes/earn.test.ts +405 -127
  517. package/src/apps/data/routes/earn.ts +660 -270
  518. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  519. package/src/apps/data/routes/exchanges.test.ts +166 -2
  520. package/src/apps/data/routes/exchanges.ts +308 -101
  521. package/src/apps/data/routes/fee-amm.test.ts +134 -2
  522. package/src/apps/data/routes/fee-amm.ts +122 -60
  523. package/src/apps/data/routes/receipts.test.ts +21 -18
  524. package/src/apps/data/routes/rpc.test.ts +2 -2
  525. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  526. package/src/apps/data/routes/tokens.test.ts +4 -4
  527. package/src/apps/data/routes/tokens.ts +11 -6
  528. package/src/apps/data/routes/transactions.test.ts +29 -0
  529. package/src/apps/data/routes/transactions.ts +33 -22
  530. package/src/apps/data/routes/webhooks.test.ts +12 -3
  531. package/src/apps/data/routes/webhooks.ts +2 -1
  532. package/src/apps/management/App.ts +4 -0
  533. package/src/apps/management/Billing.test.ts +253 -27
  534. package/src/apps/management/Billing.ts +83 -29
  535. package/src/apps/management/routes/api-keys.test.ts +1 -1
  536. package/src/apps/management/routes/api-keys.ts +85 -11
  537. package/src/apps/management/routes/billing.test.ts +68 -4
  538. package/src/apps/management/routes/cli.test.ts +370 -0
  539. package/src/apps/management/routes/cli.ts +533 -0
  540. package/src/apps/management/routes/me.test.ts +14 -4
  541. package/src/apps/management/routes/orgs.test.ts +108 -4
  542. package/src/apps/management/routes/orgs.ts +7 -2
  543. package/src/apps/management/routes/usage.test.ts +2 -2
  544. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  545. package/src/apps/mpp/internal/Policy.ts +6 -2
  546. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  547. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  548. package/src/apps/relay/App.test.ts +85 -1
  549. package/src/apps/relay/App.ts +28 -4
  550. package/src/apps/relay/Sponsorships.test.ts +97 -1
  551. package/src/apps/relay/Sponsorships.ts +77 -66
  552. package/src/apps/routes/Access.test.ts +319 -0
  553. package/src/apps/routes/Access.ts +147 -0
  554. package/src/apps/routes/App.ts +10 -0
  555. package/src/apps/routes/routes/chains.test.ts +3 -2
  556. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  557. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  558. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  559. package/src/apps/routes/routes/quotes.test.ts +81 -8
  560. package/src/apps/routes/routes/quotes.ts +109 -27
  561. package/src/apps/routes/routes/transfers.test.ts +252 -15
  562. package/src/apps/routes/routes/transfers.ts +212 -33
  563. package/src/cli/ApiKeys.test.ts +265 -0
  564. package/src/cli/ApiKeys.ts +189 -0
  565. package/src/cli/Cli.test.ts +188 -0
  566. package/src/cli/Cli.ts +280 -12
  567. package/src/cli/Credentials.test.ts +122 -0
  568. package/src/cli/Credentials.ts +144 -0
  569. package/src/cli/Spec.test.ts +133 -0
  570. package/src/cli/Spec.ts +132 -0
  571. package/src/cli/bin.test.ts +49 -0
  572. package/src/cli/bin.ts +5 -1
  573. package/src/cli/commands/auth.test.ts +138 -0
  574. package/src/cli/commands/auth.ts +254 -0
  575. package/src/cli/commands/keys.test.ts +68 -0
  576. package/src/cli/commands/keys.ts +125 -0
  577. package/src/cloudflare.ts +184 -36
  578. package/src/db/Db.test.ts +877 -0
  579. package/src/db/Db.ts +498 -1
  580. package/src/db/Schema.ts +75 -4
  581. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  582. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  583. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  584. package/src/db/tables/authAccounts.test.ts +30 -0
  585. package/src/db/tables/authAccounts.ts +1 -0
  586. package/src/db/tables/earnVaults.test.ts +34 -0
  587. package/src/db/tables/earnVaults.ts +17 -2
  588. package/src/db/tables/organizations.test.ts +148 -84
  589. package/src/db/tables/organizations.ts +11 -43
  590. package/src/db/tables/requestUsage.ts +13 -2
  591. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  592. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  593. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  594. package/src/db/tables/rewardRuns.ts +4 -0
  595. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  596. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  597. package/src/db/tables/routesDepositAddresses.ts +118 -34
  598. package/src/db/tables/routesDeposits.test.ts +66 -5
  599. package/src/db/tables/routesDeposits.ts +47 -26
  600. package/src/db/tables/routesIdempotency.test.ts +80 -0
  601. package/src/db/tables/routesIdempotency.ts +2 -0
  602. package/src/db/tables/routesPolicies.test.ts +143 -0
  603. package/src/db/tables/routesPolicies.ts +251 -0
  604. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  605. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  606. package/src/db/tables/routesTransfers.test.ts +183 -2
  607. package/src/db/tables/routesTransfers.ts +65 -6
  608. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  609. package/src/db/tables/sponsoredTransactions.ts +182 -38
  610. package/src/db/tables/users.test.ts +51 -0
  611. package/src/db/tables/users.ts +12 -0
  612. package/src/handlers/internal/multisig.store.test.ts +120 -0
  613. package/src/handlers/internal/multisig.test.ts +389 -0
  614. package/src/handlers/internal/multisig.ts +13 -10
  615. package/src/handlers/relay.test.ts +259 -83
  616. package/src/handlers/relay.ts +36 -17
  617. package/src/internal/Auth.test.ts +291 -8
  618. package/src/internal/Auth.ts +227 -96
  619. package/src/internal/BetterAuth.test.ts +58 -22
  620. package/src/internal/BetterAuth.ts +23 -17
  621. package/src/internal/Cache.ts +3 -1
  622. package/src/internal/CliAuth.test.ts +279 -0
  623. package/src/internal/CliAuth.ts +319 -0
  624. package/src/internal/EarnSharePrices.test.ts +25 -0
  625. package/src/internal/EarnSharePrices.ts +9 -2
  626. package/src/internal/EarnVaults.test.ts +67 -0
  627. package/src/internal/EarnVaults.ts +299 -4
  628. package/src/internal/EarnWithdrawals.test.ts +315 -0
  629. package/src/internal/EarnWithdrawals.ts +266 -0
  630. package/src/internal/ExecutionContext.ts +31 -0
  631. package/src/internal/Log.test.ts +210 -0
  632. package/src/internal/Log.ts +180 -142
  633. package/src/internal/MetricSink.test.ts +190 -15
  634. package/src/internal/MetricSink.ts +27 -1
  635. package/src/internal/RateLimit.test.ts +144 -8
  636. package/src/internal/RateLimit.ts +254 -26
  637. package/src/internal/Store.ts +4 -5
  638. package/src/internal/Timing.test.ts +32 -0
  639. package/src/internal/Timing.ts +20 -1
  640. package/src/internal/Tron.test-d.ts +22 -0
  641. package/src/internal/Tron.test.ts +94 -0
  642. package/src/internal/Tron.ts +289 -0
  643. package/src/internal/Viem.rpc.test.ts +76 -0
  644. package/src/internal/Viem.ts +29 -6
  645. package/src/internal/rewards/Read.test.ts +109 -0
  646. package/src/internal/rewards/Read.ts +13 -4
  647. package/src/internal/routes/Action.test.ts +70 -0
  648. package/src/internal/routes/Action.ts +76 -1
  649. package/src/internal/routes/Chain.test.ts +18 -0
  650. package/src/internal/routes/Chain.ts +5 -0
  651. package/src/internal/routes/DepositAddress.ts +5 -0
  652. package/src/internal/routes/Evidence.test.ts +64 -0
  653. package/src/internal/routes/Evidence.ts +11 -3
  654. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  655. package/src/internal/routes/Policy.test.ts +316 -0
  656. package/src/internal/routes/Policy.ts +399 -0
  657. package/src/internal/routes/Provider.test.ts +103 -2
  658. package/src/internal/routes/Provider.ts +149 -27
  659. package/src/internal/routes/Quota.test.ts +149 -0
  660. package/src/internal/routes/Quota.ts +226 -0
  661. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  662. package/src/internal/routes/Reconciliation.test.ts +371 -13
  663. package/src/internal/routes/Reconciliation.ts +193 -42
  664. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  665. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  666. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  667. package/src/internal/routes/SourceObservation.test.ts +221 -0
  668. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  669. package/src/internal/routes/Subsidy.ts +4 -2
  670. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  671. package/src/internal/routes/Transfer.test.ts +130 -1
  672. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  673. package/src/internal/routes/Transfer.ts +866 -8
  674. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  675. package/src/internal/routes/TransferReconciliation.ts +91 -166
  676. package/src/internal/routes/TransferSettlement.ts +48 -0
  677. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  678. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  679. package/src/internal/routes/TransferSubsidy.ts +87 -12
  680. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  681. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  682. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  683. package/src/internal/routes/index.test.ts +3 -0
  684. package/src/internal/routes/index.ts +3 -0
  685. package/src/internal/routes/providers/across.ts +13 -0
  686. package/src/internal/routes/providers/index.test.ts +141 -0
  687. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  688. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  689. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  690. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  691. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  692. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  693. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  694. package/src/internal/routes/providers/propAmm.ts +640 -0
  695. package/src/internal/routes/providers/relay.test.ts +1263 -41
  696. package/src/internal/routes/providers/relay.ts +423 -38
  697. package/src/internal/routes/providers/rhino.ts +14 -1
  698. package/src/internal/routes/providers/squid.ts +21 -0
  699. package/src/internal/routes/providers/stargate.test.ts +105 -1
  700. package/src/internal/routes/providers/stargate.ts +22 -9
  701. package/src/internal/routes/providers/symbiosis.ts +13 -47
  702. package/src/providers/index.test.ts +2 -0
  703. package/src/providers/index.ts +18 -0
  704. package/dist/admin/Access.d.ts +0 -39
  705. package/dist/admin/Access.d.ts.map +0 -1
  706. package/dist/admin/Access.js +0 -73
  707. package/dist/admin/Access.js.map +0 -1
  708. package/src/admin/Access.test.ts +0 -130
  709. package/src/admin/Access.ts +0 -85
@@ -20,11 +20,11 @@ import * as z from 'zod/mini'
20
20
  import type * as App from '../App.js'
21
21
  import * as ApiKey from '../ApiKey.js'
22
22
  import * as ApiKeys from '../ApiKeys.js'
23
- import * as ApiKeyAdmissions from '../db/tables/apiKeyAdmissions.js'
24
- import * as ApiKeyOwnerTombstones from '../db/tables/apiKeyOwnerTombstones.js'
25
23
  import * as AuthAccounts from '../db/tables/authAccounts.js'
26
24
  import * as BetterAuth from './BetterAuth.js'
25
+ import * as CliAuth from './CliAuth.js'
27
26
  import * as Db from '../db/Db.js'
27
+ import * as ExecutionContext from './ExecutionContext.js'
28
28
  import type * as Email from './Email.js'
29
29
  import * as Memberships from '../db/tables/memberships.js'
30
30
  import * as IpAllowlist from './IpAllowlist.js'
@@ -50,24 +50,26 @@ const defaultIdentitySessionTtl = 24 * 60 * 60
50
50
  const defaultMppRateLimit = { limit: 100, period: 'minute' } satisfies RateLimit.Limit
51
51
  const defaultPublicRateLimit = { limit: 60, period: 'minute' } satisfies RateLimit.Limit
52
52
  const identityCookieName = 'tempo_identity'
53
+ const privacyUrl = 'https://tempo.xyz/privacy-policy/'
54
+ const termsUrl = 'https://console.tempo.xyz/legal/terms'
53
55
  const walletIdentityIssuer = 'https://wallet.tempo.xyz/api/oidc'
54
56
 
55
- type IdentitySession = {
56
- /** Wallet address asserted by the identity token. */
57
- address: string
58
- /** Verified email asserted by the identity token. */
59
- email?: string | undefined
57
+ type IdentitySession = WalletSession & {
60
58
  /** Unix timestamp when the session expires. */
61
59
  expiresAt: number
62
60
  /** Unix timestamp when the session was issued. */
63
61
  issuedAt: number
62
+ /** Immutable user bound when the session was issued. */
63
+ userId: string
64
64
  }
65
65
 
66
66
  type WalletSession = {
67
67
  /** Wallet address used to resolve the canonical user. */
68
68
  address: string
69
- /** Verified email used to reconcile the canonical user. */
69
+ /** Verified email asserted when the session was issued. */
70
70
  email?: string | undefined
71
+ /** Immutable user binding, absent only in legacy sessions. */
72
+ userId?: string | undefined
71
73
  }
72
74
 
73
75
  function isIdentityTokenError(error: unknown) {
@@ -145,7 +147,18 @@ export type Payment = {
145
147
  }
146
148
 
147
149
  /** Host-provided request backstop that returns a rejection response when over quota. */
148
- export type EdgeRateLimit = (request: Request) => Promise<Response | undefined>
150
+ export type EdgeRateLimit = (
151
+ request: Request,
152
+ options: EdgeRateLimit.Options,
153
+ ) => Promise<Response | undefined>
154
+
155
+ export namespace EdgeRateLimit {
156
+ /** Request-specific edge backstop options. */
157
+ export type Options = {
158
+ /** Resolves a confirmed credential partition when the shared network limit rejects the request. */
159
+ resolvePartition?: (() => Promise<string | undefined>) | undefined
160
+ }
161
+ }
149
162
 
150
163
  /** MPP route-policy types. Distinct from the authentication {@link Session} capability. */
151
164
  export declare namespace Mpp {
@@ -222,6 +235,9 @@ export type PolicyOverride = {
222
235
  session?: boolean | undefined
223
236
  }
224
237
 
238
+ /** Credential kind a request presented, recorded before it is resolved. */
239
+ export type CredentialKind = 'api_key' | 'payment'
240
+
225
241
  /** Authenticated or anonymous caller. */
226
242
  export type Principal =
227
243
  | {
@@ -249,15 +265,17 @@ export type Principal =
249
265
  type: 'public'
250
266
  }
251
267
  | {
268
+ /** Approved API-key scopes and expiry for a console-authorized CLI device. */
269
+ cli?: { expiresAt: string; scopes: readonly string[] } | undefined
252
270
  /** Verified email bound to the session, when present. */
253
271
  email?: string | undefined
254
272
  /** Principal id: the user id (`usr_…`). */
255
273
  id: string
256
274
  /** Identity that established the session, as a provider/subject pair (OIDC `iss`/`sub` semantics). */
257
275
  identity: {
258
- /** Identity provider: `email`, `wallet`, or an OIDC issuer. */
276
+ /** Identity provider: `email`, `wallet`, `cli` (a console-approved CLI session), or an OIDC issuer. */
259
277
  provider: string
260
- /** Provider-scoped subject — the wallet address for `wallet`. */
278
+ /** Provider-scoped subject: the wallet address for `wallet`, the CLI session id (`cli_…`) for `cli`. */
261
279
  subject: string
262
280
  }
263
281
  /** Payment metadata for paid overflow requests. */
@@ -280,6 +298,8 @@ export type Principal =
280
298
  export type Variables = {
281
299
  /** Auth context consumed by protected handlers. */
282
300
  auth: Context
301
+ /** Credential kind the request presented, set before resolution so stalled requests stay attributable. */
302
+ credential?: CredentialKind | undefined
283
303
  /** Caller's membership resolved by {@link ensureOrg} or {@link ensureProject}; absent for API keys and `super_admin`. */
284
304
  membership?: Memberships.Record | undefined
285
305
  /** Organization resolved by {@link ensureOrg} or {@link ensureProject} for the current request. */
@@ -645,7 +665,7 @@ function createAuthMiddleware<
645
665
  ...(sessionChainIds ? { sessionChainIds: new Set(sessionChainIds) } : {}),
646
666
  },
647
667
  }),
648
- rateLimit: RateLimit.memory(options.rateLimit),
668
+ rateLimit: rateLimitStore(options.rateLimit),
649
669
  ...(options.session ? { session: options.session } : {}),
650
670
  ...(options.superAdmin?.secret
651
671
  ? { superAdmin: { tokenHash: ApiKey.hash(options.superAdmin.secret) } }
@@ -653,6 +673,8 @@ function createAuthMiddleware<
653
673
  }
654
674
 
655
675
  return createMiddleware<environment>((c, next) => {
676
+ // Every route records its credential, including unprotected and unmatched paths.
677
+ recordCredential(c, getApiKeyCredential(c))
656
678
  const resolved = resolveRequestPolicy(c, { base, defaults, options })
657
679
  if (!resolved) return next()
658
680
 
@@ -711,8 +733,6 @@ declare namespace resolveRequestPolicy {
711
733
  type ApiKeyResolverOptions = {
712
734
  /** API-key authentication and cache configuration. */
713
735
  apiKey: middleware.Options['apiKey']
714
- /** Authoritative owner store used to reject orphaned API keys. */
715
- db?: Db.Source | undefined
716
736
  /** Scope catalog accepted while resolving records. */
717
737
  scopeCatalog: Scope.Catalog | undefined
718
738
  }
@@ -726,16 +746,27 @@ type RequestApiKeyResolution = {
726
746
 
727
747
  function createApiKeyResolver(options: ApiKeyResolverOptions) {
728
748
  const requests = new WeakMap<hono_Context, RequestApiKeyResolution>()
729
- const uncached = (c: hono_Context, token: string) => {
749
+ // Requests whose key came from KV in this request: `ApiKeys.resolve` already
750
+ // read the fences, so reading them again adds a round trip and nothing else.
751
+ const fenced = new WeakMap<hono_Context, string>()
752
+ const uncached = async (c: hono_Context, token: string) => {
730
753
  const kv = contextKv(c)
731
- return kv
732
- ? ApiKeys.resolve(kv.store, token, { scopeCatalog: options.scopeCatalog })
733
- : Promise.resolve(null)
754
+ if (!kv) return null
755
+ const apiKey = await ApiKeys.resolve(kv.store, token, { scopeCatalog: options.scopeCatalog })
756
+ fenced.set(c, ApiKey.hash(token))
757
+ return apiKey
734
758
  }
735
759
  const cache =
736
760
  options.apiKey === false || options.apiKey?.cache === false
737
761
  ? { invalidate: () => {}, peek: () => undefined, resolve: uncached }
738
762
  : cachedResolve(uncached, options.apiKey?.cache ?? {})
763
+ // A cached record still checks its fences every request, so revocation and
764
+ // owner deletion never wait for the isolate cache to expire.
765
+ const active = async (c: hono_Context, token: string, apiKey: ApiKey.ApiKey | null) => {
766
+ const kv = contextKv(c)
767
+ if (!apiKey || !kv || fenced.get(c) === ApiKey.hash(token)) return apiKey
768
+ return (await ApiKeys.isFenced(kv.store, apiKey)) ? null : apiKey
769
+ }
739
770
 
740
771
  return {
741
772
  peek: (c: hono_Context, token: string) => {
@@ -744,18 +775,16 @@ function createApiKeyResolver(options: ApiKeyResolverOptions) {
744
775
  if (existing?.tokenHash === tokenHash) return existing.apiKey
745
776
  return cache.peek(token)
746
777
  },
778
+ probe: async (c: hono_Context, token: string) => {
779
+ // Probes must not warm the resolution cache before rate-limit admission.
780
+ return active(c, token, await uncached(c, token))
781
+ },
747
782
  resolve: async (c: hono_Context, token: string) => {
748
783
  const tokenHash = ApiKey.hash(token)
749
784
  const existing = requests.get(c)
750
785
  if (existing?.tokenHash === tokenHash) return existing.apiKey
751
786
  const cached = await cache.resolve(c, token)
752
- const kv = contextKv(c)
753
- const apiKey =
754
- cached &&
755
- ((kv && (await ApiKeys.isOwnerDeleted(kv.store, cached))) ||
756
- !(await apiKeyOwnerExists(cached, options.db)))
757
- ? null
758
- : cached
787
+ const apiKey = await active(c, token, cached)
759
788
  if (cached && !apiKey) cache.invalidate(token)
760
789
  requests.set(c, { apiKey, tokenHash })
761
790
  return apiKey
@@ -763,15 +792,6 @@ function createApiKeyResolver(options: ApiKeyResolverOptions) {
763
792
  }
764
793
  }
765
794
 
766
- /** Rejects attributed keys fenced by a committed owner deletion. */
767
- async function apiKeyOwnerExists(apiKey: ApiKey.ApiKey, source: Db.Source | undefined) {
768
- if (!source) return true
769
- const db = Db.get(source)
770
- if (!(await ApiKeyAdmissions.matches(db, apiKey))) return false
771
- if (await ApiKeyOwnerTombstones.isDeleted(db, apiKey)) return false
772
- return true
773
- }
774
-
775
795
  export declare namespace middleware {
776
796
  /** Per-route policy overrides keyed by HTTP endpoint. */
777
797
  type Overrides<endpoint extends string = string> = Partial<
@@ -811,8 +831,8 @@ export declare namespace middleware {
811
831
  }
812
832
  | false
813
833
  | undefined
814
- /** Rate-limit store options. */
815
- rateLimit?: RateLimit.memory.Options | undefined
834
+ /** Rate-limit store, or options for the counter-backed default. */
835
+ rateLimit?: RateLimit.memory.Options | RateLimit.Store | undefined
816
836
  /** Scope catalog accepted while resolving API-key records. */
817
837
  scopeCatalog?: Scope.Catalog | undefined
818
838
  /** Session lane resolution — the session surface's capability; omit to leave the session lane closed. */
@@ -992,7 +1012,7 @@ export function install(options: install.Options) {
992
1012
  get email() {
993
1013
  return options.email()
994
1014
  },
995
- rateLimit: RateLimit.memory(options_middleware.rateLimit),
1015
+ rateLimit: rateLimitStore(options_middleware.rateLimit),
996
1016
  secret: options_session.secret,
997
1017
  ...(options_session.google ? { google: options_session.google } : {}),
998
1018
  ...(options_session.trustedOrigins
@@ -1038,9 +1058,12 @@ export function install(options: install.Options) {
1038
1058
  return value === null ? undefined : (JSON.parse(value) as never)
1039
1059
  },
1040
1060
  async set(key, value, options) {
1061
+ const payload = key.startsWith('session:')
1062
+ ? { ...(value as WalletSession), ...(await bindWalletSession(value as WalletSession)) }
1063
+ : value
1041
1064
  await kv.store.put(
1042
1065
  `auth:${key}`,
1043
- JSON.stringify(value),
1066
+ JSON.stringify(payload),
1044
1067
  options?.ttl ? { ttl: options.ttl * 1_000 } : {},
1045
1068
  )
1046
1069
  },
@@ -1083,8 +1106,46 @@ export function install(options: install.Options) {
1083
1106
  })
1084
1107
  }
1085
1108
 
1109
+ async function bindWalletSession(payload: WalletSession) {
1110
+ const user = await resolveWallet(payload)
1111
+ if (!user) throw new Error('Authenticated wallet user was not found')
1112
+ if (!user.user.termsSharedAt) await Users.recordTermsShared(Db.get(db), user.user.id)
1113
+ return { email: user.email, userId: user.user.id }
1114
+ }
1115
+
1116
+ async function resolveWalletSession(payload: WalletSession) {
1117
+ // Legacy sessions cannot be safely rebound after an email or wallet reassignment.
1118
+ if (!payload.userId) return null
1119
+ const database = Db.get(db)
1120
+ const [user, linkedUserId] = await Promise.all([
1121
+ Users.get(database, payload.userId),
1122
+ AuthAccounts.getWalletUserId(database, payload.address),
1123
+ ])
1124
+ if (!user || linkedUserId !== payload.userId) return null
1125
+ if (payload.email && (user.email !== payload.email || !user.emailVerified)) return null
1126
+ return { email: user.emailVerified ? user.email : undefined, user }
1127
+ }
1128
+
1129
+ // CLI sessions act as the approving user; the principal's identity names the
1130
+ // CLI session so handlers never mistake it for a wallet sign-in.
1131
+ const resolveCli = async (token: string): Promise<SessionPrincipal | null> => {
1132
+ const record = await CliAuth.resolve(kv.store, token)
1133
+ if (!record) return null
1134
+ const user = await Users.get(Db.get(db), record.userId)
1135
+ if (!user) return null
1136
+ return {
1137
+ cli: { expiresAt: record.expiresAt, scopes: record.scopes ?? [] },
1138
+ ...(user.emailVerified && user.email ? { email: user.email } : {}),
1139
+ id: user.id,
1140
+ identity: { provider: 'cli', subject: record.id },
1141
+ type: 'session',
1142
+ }
1143
+ }
1144
+
1086
1145
  const session: Session = {
1087
1146
  resolve: async (c) => {
1147
+ const bearer = /^Bearer\s+(.+)$/i.exec(c.req.header('authorization') ?? '')?.[1]
1148
+ if (bearer && CliAuth.isToken(bearer)) return resolveCli(bearer)
1088
1149
  const [betterAuth, identitySession, wallet] = await Promise.all([
1089
1150
  (async () => {
1090
1151
  const auth = BetterAuth.fromContext(c, options_betterAuth)
@@ -1116,7 +1177,7 @@ export function install(options: install.Options) {
1116
1177
  if (value === null) return null
1117
1178
  const payload = JSON.parse(value) as IdentitySession
1118
1179
  if (payload.expiresAt <= Math.floor(Date.now() / 1_000)) return null
1119
- const user = await resolveWallet(payload)
1180
+ const user = await resolveWalletSession(payload)
1120
1181
  if (!user) return null
1121
1182
  return {
1122
1183
  ...(user.email ? { email: user.email } : {}),
@@ -1128,7 +1189,7 @@ export function install(options: install.Options) {
1128
1189
  (async () => {
1129
1190
  const payload = await handler.getSession(c.req.raw)
1130
1191
  if (!payload) return null
1131
- const user = await resolveWallet(payload)
1192
+ const user = await resolveWalletSession(payload)
1132
1193
  if (!user) return null
1133
1194
  return {
1134
1195
  ...(user.email ? { email: user.email } : {}),
@@ -1149,6 +1210,11 @@ export function install(options: install.Options) {
1149
1210
  const describe = OpenApi.describeRoute({ hide: true })
1150
1211
 
1151
1212
  const app = new Hono<App.Environment>()
1213
+ .use('*', async (c, next) => {
1214
+ await next()
1215
+ c.header('Tempo-Terms-URL', termsUrl)
1216
+ c.header('Tempo-Privacy-URL', privacyUrl)
1217
+ })
1152
1218
  .use('/v1/auth/siwe', policy_public, describe)
1153
1219
  .use('/v1/auth/siwe/*', policy_public, describe)
1154
1220
  // Documented operations: pre-routes carrying the OpenAPI metadata and the
@@ -1264,13 +1330,14 @@ export function install(options: install.Options) {
1264
1330
 
1265
1331
  const address = Address.checksum(claims.subject)
1266
1332
  await Users.upsertByAddress(Db.get(db), { address })
1333
+ const binding = await bindWalletSession({ address, email: claims.email })
1267
1334
  const issuedAt = Math.floor(Date.now() / 1_000)
1268
1335
  const token = Hex.fromBytes(crypto.getRandomValues(new Uint8Array(32))).slice(2)
1269
1336
  await kv.store.put(
1270
1337
  identitySessionKey(token),
1271
1338
  JSON.stringify({
1272
1339
  address,
1273
- ...(claims.email ? { email: claims.email } : {}),
1340
+ ...binding,
1274
1341
  expiresAt: issuedAt + identitySessionTtl,
1275
1342
  issuedAt,
1276
1343
  } satisfies IdentitySession),
@@ -1292,10 +1359,14 @@ export function install(options: install.Options) {
1292
1359
  createMiddleware<App.Environment>(async (c, next) => {
1293
1360
  const auth = c.get('auth')
1294
1361
  const principal = principalFromPublic(c, auth)
1295
- const result = await consumeRateLimit(auth, {
1296
- key: `public:${principal.id}`,
1297
- limit: auth.publicRateLimit ?? defaultPublicRateLimit,
1298
- })
1362
+ const result = await Timing.time(c as never, 'rate_limit', () =>
1363
+ consumeRateLimit(auth, {
1364
+ key: `public:${principal.id}`,
1365
+ limit: auth.publicRateLimit ?? defaultPublicRateLimit,
1366
+ principal: `public:${principal.id}`,
1367
+ waitUntil: ExecutionContext.waitUntil(c),
1368
+ }),
1369
+ )
1299
1370
  if (result) {
1300
1371
  setRateLimitHeaders(c, result)
1301
1372
  if (!result.allowed) return rateLimitExceeded(c, result)
@@ -1305,7 +1376,8 @@ export function install(options: install.Options) {
1305
1376
  return undefined
1306
1377
  }),
1307
1378
  OpenApi.describeRoute({
1308
- description: 'Revokes auth sessions and clears their cookies.',
1379
+ description:
1380
+ 'Revokes auth sessions and clears their cookies. A CLI session sent as `Authorization: Bearer` is revoked on its own.',
1309
1381
  hide: false,
1310
1382
  operationId: 'logout',
1311
1383
  responses: {
@@ -1317,6 +1389,21 @@ export function install(options: install.Options) {
1317
1389
  tags: ['Authentication'],
1318
1390
  }),
1319
1391
  async (c) => {
1392
+ // A CLI session carries only its bearer token; revoke it and leave browser sessions alone.
1393
+ const bearer = /^Bearer\s+(.+)$/i.exec(c.req.header('authorization') ?? '')?.[1]
1394
+ if (bearer && CliAuth.isToken(bearer)) {
1395
+ try {
1396
+ await CliAuth.revoke(kv.store, bearer)
1397
+ } catch (cause) {
1398
+ c.error = cause instanceof Error ? cause : new Error('CLI logout failed', { cause })
1399
+ return Response.error(c, {
1400
+ code: 'session_logout_failed',
1401
+ message: 'Session logout failed',
1402
+ status: 500,
1403
+ })
1404
+ }
1405
+ return c.body(null, 204)
1406
+ }
1320
1407
  const walletHeaders = (() => {
1321
1408
  const authorization = c.req.header('authorization')
1322
1409
  const cookie = c.req.header('cookie')
@@ -1413,7 +1500,7 @@ export function install(options: install.Options) {
1413
1500
  Metadata.attach(app, {
1414
1501
  securitySchemes: {
1415
1502
  session: {
1416
- description: 'Session cookie established by email OTP, Wallet identity, or SIWE sign-in. Browsers send `tempo_auth.session_token`, `tempo_identity`, or `accounts_auth`; Accounts sessions may also use `Authorization: Bearer <token>`.', // prettier-ignore
1503
+ description: 'Session cookie established by email OTP, Wallet identity, or SIWE sign-in. Browsers send `tempo_auth.session_token`, `tempo_identity`, or `accounts_auth`; Accounts sessions may also use `Authorization: Bearer <token>`, and CLI sessions always use `Authorization: Bearer tempo:cli:…`.', // prettier-ignore
1417
1504
  in: 'header',
1418
1505
  name: 'Cookie',
1419
1506
  type: 'apiKey',
@@ -1427,7 +1514,6 @@ export function install(options: install.Options) {
1427
1514
 
1428
1515
  const resolve = createApiKeyResolver({
1429
1516
  apiKey: options_middleware.apiKey,
1430
- db: options.db,
1431
1517
  scopeCatalog,
1432
1518
  })
1433
1519
  const defaults = laneDefaults(options_middleware)
@@ -1440,14 +1526,17 @@ export function install(options: install.Options) {
1440
1526
 
1441
1527
  return createMiddleware(async (c, next) => {
1442
1528
  const credential = getApiKeyCredential(c)
1529
+ recordCredential(c, credential)
1443
1530
  const resolved = resolveRequestPolicy(c, { base, defaults, options: options_middleware })
1444
1531
  const isSuperAdmin =
1445
1532
  credential &&
1446
1533
  superAdminTokenHash !== undefined &&
1447
1534
  ApiKey.hash(credential.token) === superAdminTokenHash
1535
+ // CLI session tokens are never API keys, so they skip key resolution here too.
1448
1536
  const canUseApiKeyQuota =
1449
1537
  credential &&
1450
1538
  !isSuperAdmin &&
1539
+ !CliAuth.isToken(credential.token) &&
1451
1540
  !hasPaymentCredential(c) &&
1452
1541
  options_middleware.apiKey !== false &&
1453
1542
  resolved?.policy?.apiKey &&
@@ -1456,10 +1545,24 @@ export function install(options: install.Options) {
1456
1545
  if (cached) return next()
1457
1546
 
1458
1547
  const response = await Timing.time(c, 'edge_rate_limit', () =>
1459
- options_edgeRateLimit(c.req.raw),
1548
+ options_edgeRateLimit(
1549
+ c.req.raw,
1550
+ canUseApiKeyQuota
1551
+ ? {
1552
+ resolvePartition: async () => {
1553
+ const apiKey =
1554
+ cached === undefined ? await resolve.probe(c, credential.token) : cached
1555
+ // Rotating invalid credentials stays in the anonymous transport bucket.
1556
+ return apiKey ? `api-key:${ApiKey.hash(credential.token)}` : undefined
1557
+ },
1558
+ }
1559
+ : {},
1560
+ ),
1460
1561
  )
1461
1562
  if (response) return response
1462
- if (canUseApiKeyQuota && cached === undefined) await resolve.resolve(c, credential.token)
1563
+ // Cold keys resolve here, ahead of the auth lane, so time both under one name.
1564
+ if (canUseApiKeyQuota && cached === undefined)
1565
+ await Timing.sum(c as never, 'auth_key', () => resolve.resolve(c, credential.token))
1463
1566
  return next()
1464
1567
  })
1465
1568
  })()
@@ -2000,6 +2103,7 @@ export function require<environment extends Environment = Environment>(
2000
2103
  return createMiddleware<environment>(async (c, next) => {
2001
2104
  const auth = c.get('auth')
2002
2105
  const credential = getApiKeyCredential(c)
2106
+ recordCredential(c, credential)
2003
2107
  const hasQueryApiKey = new URL(c.req.url).searchParams.has('key')
2004
2108
  // Auth owns `key`; strict route schemas must not validate it.
2005
2109
  stripApiKeyQuery(c)
@@ -2053,7 +2157,11 @@ export function require<environment extends Environment = Environment>(
2053
2157
  return proceed()
2054
2158
  }
2055
2159
 
2056
- const apiKey_resolved = await auth.apiKey?.resolve(c, credential.token)
2160
+ // CLI session tokens are prefixed, so they skip the API-key lookup.
2161
+ const cliToken = CliAuth.isToken(credential.token)
2162
+ const apiKey_resolved = cliToken
2163
+ ? null
2164
+ : await Timing.sum(c as never, 'auth_key', () => auth.apiKey?.resolve(c, credential.token))
2057
2165
  if (!apiKey_resolved) {
2058
2166
  if (unsupportedChain)
2059
2167
  return Response.unsupportedChainId(
@@ -2071,6 +2179,21 @@ export function require<environment extends Environment = Environment>(
2071
2179
  return proceed()
2072
2180
  }
2073
2181
  }
2182
+ if (cliToken)
2183
+ return jsonError(
2184
+ c,
2185
+ policy.session
2186
+ ? {
2187
+ code: 'session_invalid',
2188
+ message: 'CLI session is invalid or expired. Sign in again.',
2189
+ status: 401,
2190
+ }
2191
+ : {
2192
+ code: 'forbidden',
2193
+ message: 'CLI sessions cannot call this route. Use an API key.',
2194
+ status: 403,
2195
+ },
2196
+ )
2074
2197
  return jsonError(c, {
2075
2198
  code: 'api_key_invalid',
2076
2199
  message: 'Invalid API key',
@@ -2111,12 +2234,17 @@ export function require<environment extends Environment = Environment>(
2111
2234
  ? (policy.public?.rateLimit ?? auth.publicRateLimit ?? { limit: 60, period: 'minute' })
2112
2235
  : resolveApiKeyLimit({ apiKey, auth, policy: policy.apiKey, scope })
2113
2236
  const paid = hasPayment && !throttled
2237
+ const bucket = policy.apiKey.bucket
2114
2238
  const result = paid
2115
2239
  ? null
2116
- : await consumeRateLimit(auth, {
2117
- key: rateLimitKey(`api_key:${apiKey.id}:scope:${scope}`, policy.apiKey.bucket),
2118
- limit,
2119
- })
2240
+ : await Timing.time(c as never, 'rate_limit', () =>
2241
+ consumeRateLimit(auth, {
2242
+ key: rateLimitKey(`api_key:${apiKey.id}:scope:${scope}`, bucket),
2243
+ limit,
2244
+ principal: `api_key:${apiKey.id}`,
2245
+ waitUntil: ExecutionContext.waitUntil(c),
2246
+ }),
2247
+ )
2120
2248
  if (result) {
2121
2249
  setRateLimitHeaders(c, result)
2122
2250
  // Surface the bucket so callers can correlate a 429 with the exhausted
@@ -2161,7 +2289,7 @@ export function require<environment extends Environment = Environment>(
2161
2289
  if (missing.length > 0)
2162
2290
  return jsonError(c, {
2163
2291
  code: 'api_key_forbidden',
2164
- message: 'API key missing required scope',
2292
+ message: `API key is missing required permissions: ${missing.join(', ')}. Use an API key with these scopes.`,
2165
2293
  status: 403,
2166
2294
  })
2167
2295
 
@@ -2213,10 +2341,14 @@ export function require<environment extends Environment = Environment>(
2213
2341
 
2214
2342
  const limit = policy.public?.rateLimit
2215
2343
  if (limit) {
2216
- const result = await consumeRateLimit(auth, {
2217
- key: rateLimitKey(`public:${publicPrincipal.id}`, policy.public?.bucket),
2218
- limit,
2219
- })
2344
+ const result = await Timing.time(c as never, 'rate_limit', () =>
2345
+ consumeRateLimit(auth, {
2346
+ key: rateLimitKey(`public:${publicPrincipal.id}`, policy.public?.bucket),
2347
+ limit,
2348
+ principal: `public:${publicPrincipal.id}`,
2349
+ waitUntil: ExecutionContext.waitUntil(c),
2350
+ }),
2351
+ )
2220
2352
  if (result) setRateLimitHeaders(c, result)
2221
2353
  if (!result || result.allowed) {
2222
2354
  c.set('principal', publicPrincipal)
@@ -2319,6 +2451,11 @@ type RateLimitAccess = PaymentAccess & {
2319
2451
  */
2320
2452
  const rateLimitConsumeTimeout = 300
2321
2453
 
2454
+ /** Accepts a ready store or builds the counter-backed default from its options. */
2455
+ function rateLimitStore(options: RateLimit.memory.Options | RateLimit.Store | undefined) {
2456
+ return options && 'consume' in options ? options : RateLimit.memory(options)
2457
+ }
2458
+
2322
2459
  /** Consumes one quota and returns null when its counter is unavailable, allowing callers to fail open. */
2323
2460
  export function consumeRateLimit(
2324
2461
  auth: Context,
@@ -2428,6 +2565,13 @@ function getApiKeyCredential(c: hono_Context): ApiKeyCredential | false | null {
2428
2565
  return null
2429
2566
  }
2430
2567
 
2568
+ // Recorded before any lookup: requests that stall or are canceled during
2569
+ // resolution never receive a principal, but still need caller attribution.
2570
+ function recordCredential(c: hono_Context, credential: ApiKeyCredential | false | null) {
2571
+ if (credential) c.set('credential', 'api_key')
2572
+ else if (hasPaymentCredential(c)) c.set('credential', 'payment')
2573
+ }
2574
+
2431
2575
  function clientIp(c: hono_Context, auth: Context): string | undefined {
2432
2576
  return (
2433
2577
  trustedClientIps.get(c.req.raw) ??
@@ -2578,13 +2722,17 @@ async function requirePayment<environment extends Environment>(
2578
2722
  options: PaymentAccess,
2579
2723
  ) {
2580
2724
  if (hasPaymentCredential(c)) {
2581
- const result = await consumeRateLimit(options.auth, {
2582
- key: rateLimitKey(
2583
- `mpp:${options.principal.type}:${options.principal.id}`,
2584
- options.policy.mpp?.bucket,
2585
- ),
2586
- limit: options.policy.mpp?.rateLimit ?? options.auth.mpp?.rateLimit ?? defaultMppRateLimit,
2587
- })
2725
+ const result = await Timing.time(c as never, 'rate_limit', () =>
2726
+ consumeRateLimit(options.auth, {
2727
+ key: rateLimitKey(
2728
+ `mpp:${options.principal.type}:${options.principal.id}`,
2729
+ options.policy.mpp?.bucket,
2730
+ ),
2731
+ limit: options.policy.mpp?.rateLimit ?? options.auth.mpp?.rateLimit ?? defaultMppRateLimit,
2732
+ principal: `mpp:${options.principal.type}:${options.principal.id}`,
2733
+ waitUntil: ExecutionContext.waitUntil(c),
2734
+ }),
2735
+ )
2588
2736
  if (result) {
2589
2737
  setRateLimitHeaders(c, result)
2590
2738
  c.header('RateLimit-Scope', 'mpp')
@@ -2690,22 +2838,16 @@ async function resolveSession(c: hono_Context, auth: Context): Promise<SessionPr
2690
2838
  const cachedMaxEntries = 10_000
2691
2839
 
2692
2840
  /**
2693
- * Wraps token resolution with a short-TTL per-isolate cache so hot keys skip
2694
- * the backend read on every request. Positive results cache for `ttl`
2695
- * (default 60s), negative for `negativeTtl` (default 10s) so a freshly minted
2696
- * key is usable quickly; concurrent misses for one token are single-flighted.
2697
- * Entries are keyed by the token's sha256 (`ApiKey.hash`) — never the
2698
- * plaintext. Key updates may remain stale for up to `ttl`, the accepted
2699
- * trade-off for removing a backend read from the auth path.
2841
+ * Caches completed resolutions per isolate by token hash, with positive and negative TTLs.
2842
+ * Each miss resolves independently so callers never await another request's pending I/O.
2700
2843
  */
2701
- function cachedResolve(
2844
+ export function cachedResolve(
2702
2845
  resolve: (c: hono_Context, token: string) => Promise<ApiKey.ApiKey | null>,
2703
2846
  options: middleware.Cache,
2704
2847
  ) {
2705
2848
  const { negativeTtl = 10_000, now = Date.now, ttl = 60_000 } = options
2706
2849
  type Cell = { expiresAt: number; value: ApiKey.ApiKey | null }
2707
2850
  const cells = new Map<string, Cell>()
2708
- const flights = new Map<string, Promise<ApiKey.ApiKey | null>>()
2709
2851
 
2710
2852
  return {
2711
2853
  invalidate(token: string) {
@@ -2726,27 +2868,16 @@ function cachedResolve(
2726
2868
  if (cell && cell.expiresAt > now()) return cell.value
2727
2869
  if (cell) cells.delete(key)
2728
2870
 
2729
- const existing = flights.get(key)
2730
- if (existing) return existing
2731
-
2732
- const flight = (async () => {
2733
- const value = await resolve(c, token)
2734
- // Bound the cache: random invalid tokens each add a (negative) entry,
2735
- // so sweep expired cells at the cap and then drop the oldest.
2736
- if (cells.size >= cachedMaxEntries) {
2737
- const time = now()
2738
- for (const [name, entry] of cells) if (entry.expiresAt <= time) cells.delete(name)
2739
- while (cells.size >= cachedMaxEntries) cells.delete(cells.keys().next().value as string)
2740
- }
2741
- cells.set(key, { expiresAt: now() + (value ? ttl : negativeTtl), value })
2742
- return value
2743
- })()
2744
- flights.set(key, flight)
2745
- try {
2746
- return await flight
2747
- } finally {
2748
- flights.delete(key)
2871
+ const value = await resolve(c, token)
2872
+ // Bound the cache: random invalid tokens each add a (negative) entry,
2873
+ // so sweep expired cells at the cap and then drop the oldest.
2874
+ if (cells.size >= cachedMaxEntries) {
2875
+ const time = now()
2876
+ for (const [name, entry] of cells) if (entry.expiresAt <= time) cells.delete(name)
2877
+ while (cells.size >= cachedMaxEntries) cells.delete(cells.keys().next().value as string)
2749
2878
  }
2879
+ cells.set(key, { expiresAt: now() + (value ? ttl : negativeTtl), value })
2880
+ return value
2750
2881
  },
2751
2882
  }
2752
2883
  }