tapimo 0.15.0 → 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 (734) 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 +896 -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 +33 -33
  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 +454 -1
  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 +10 -4
  45. package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
  46. package/dist/admin/apps/verified-tokens.js +24 -4
  47. package/dist/admin/apps/verified-tokens.js.map +1 -1
  48. package/dist/admin/index.d.ts +0 -1
  49. package/dist/admin/index.d.ts.map +1 -1
  50. package/dist/admin/index.js +0 -1
  51. package/dist/admin/index.js.map +1 -1
  52. package/dist/admin/ui.generated.d.ts +1 -1
  53. package/dist/admin/ui.generated.d.ts.map +1 -1
  54. package/dist/admin/ui.generated.js +99 -103
  55. package/dist/admin/ui.generated.js.map +1 -1
  56. package/dist/analytics/Analytics.d.ts.map +1 -1
  57. package/dist/analytics/Analytics.js +65 -1
  58. package/dist/analytics/Analytics.js.map +1 -1
  59. package/dist/analytics/tables/requestEvents.d.ts +1 -1
  60. package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
  61. package/dist/analytics/tables/requestEvents.js +58 -59
  62. package/dist/analytics/tables/requestEvents.js.map +1 -1
  63. package/dist/apps/data/App.d.ts +2709 -2670
  64. package/dist/apps/data/App.d.ts.map +1 -1
  65. package/dist/apps/data/routes/activities.d.ts +5 -5
  66. package/dist/apps/data/routes/activities.d.ts.map +1 -1
  67. package/dist/apps/data/routes/activities.js +50 -0
  68. package/dist/apps/data/routes/activities.js.map +1 -1
  69. package/dist/apps/data/routes/addresses.d.ts +248 -248
  70. package/dist/apps/data/routes/balances.d.ts +22 -22
  71. package/dist/apps/data/routes/balances.d.ts.map +1 -1
  72. package/dist/apps/data/routes/balances.js +5 -7
  73. package/dist/apps/data/routes/balances.js.map +1 -1
  74. package/dist/apps/data/routes/coingecko.d.ts +54 -54
  75. package/dist/apps/data/routes/earn.d.ts +103 -12
  76. package/dist/apps/data/routes/earn.d.ts.map +1 -1
  77. package/dist/apps/data/routes/earn.js +456 -220
  78. package/dist/apps/data/routes/earn.js.map +1 -1
  79. package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
  80. package/dist/apps/data/routes/exchanges.js +267 -97
  81. package/dist/apps/data/routes/exchanges.js.map +1 -1
  82. package/dist/apps/data/routes/fee-amm.d.ts +1 -19
  83. package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
  84. package/dist/apps/data/routes/fee-amm.js +93 -56
  85. package/dist/apps/data/routes/fee-amm.js.map +1 -1
  86. package/dist/apps/data/routes/indexer.d.ts +10 -10
  87. package/dist/apps/data/routes/rpc.d.ts +30 -30
  88. package/dist/apps/data/routes/rpc.js +45 -11
  89. package/dist/apps/data/routes/rpc.js.map +1 -1
  90. package/dist/apps/data/routes/tokens.d.ts.map +1 -1
  91. package/dist/apps/data/routes/tokens.js +11 -6
  92. package/dist/apps/data/routes/tokens.js.map +1 -1
  93. package/dist/apps/data/routes/transactions.d.ts +2 -0
  94. package/dist/apps/data/routes/transactions.d.ts.map +1 -1
  95. package/dist/apps/data/routes/transactions.js +30 -22
  96. package/dist/apps/data/routes/transactions.js.map +1 -1
  97. package/dist/apps/data/routes/transfers.d.ts +12 -12
  98. package/dist/apps/data/routes/valuation.d.ts +30 -30
  99. package/dist/apps/data/routes/verified-tokens.d.ts +5 -5
  100. package/dist/apps/data/routes/webhooks.d.ts +1 -1
  101. package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
  102. package/dist/apps/data/routes/webhooks.js +18 -11
  103. package/dist/apps/data/routes/webhooks.js.map +1 -1
  104. package/dist/apps/data/routes/zones.d.ts +3 -3
  105. package/dist/apps/management/App.d.ts +3043 -2198
  106. package/dist/apps/management/App.d.ts.map +1 -1
  107. package/dist/apps/management/App.js +2 -0
  108. package/dist/apps/management/App.js.map +1 -1
  109. package/dist/apps/management/Billing.d.ts +2 -4
  110. package/dist/apps/management/Billing.d.ts.map +1 -1
  111. package/dist/apps/management/Billing.js +65 -26
  112. package/dist/apps/management/Billing.js.map +1 -1
  113. package/dist/apps/management/routes/api-keys.d.ts +16 -4
  114. package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
  115. package/dist/apps/management/routes/api-keys.js +70 -11
  116. package/dist/apps/management/routes/api-keys.js.map +1 -1
  117. package/dist/apps/management/routes/billing.d.ts +84 -84
  118. package/dist/apps/management/routes/cli.d.ts +912 -0
  119. package/dist/apps/management/routes/cli.d.ts.map +1 -0
  120. package/dist/apps/management/routes/cli.js +416 -0
  121. package/dist/apps/management/routes/cli.js.map +1 -0
  122. package/dist/apps/management/routes/faucet.d.ts +8 -8
  123. package/dist/apps/management/routes/invitations.d.ts +24 -24
  124. package/dist/apps/management/routes/invite-links.d.ts +66 -66
  125. package/dist/apps/management/routes/members.d.ts +16 -16
  126. package/dist/apps/management/routes/orgs.d.ts +20 -20
  127. package/dist/apps/management/routes/orgs.d.ts.map +1 -1
  128. package/dist/apps/management/routes/orgs.js +8 -2
  129. package/dist/apps/management/routes/orgs.js.map +1 -1
  130. package/dist/apps/management/routes/projects.d.ts +76 -76
  131. package/dist/apps/management/routes/usage.d.ts +8 -8
  132. package/dist/apps/management/routes/verified-token-requests.d.ts +42 -42
  133. package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
  134. package/dist/apps/management/routes/verified-token-requests.js +7 -9
  135. package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
  136. package/dist/apps/management/routes/webhooks.d.ts +119 -119
  137. package/dist/apps/mcp.d.ts.map +1 -1
  138. package/dist/apps/mcp.js +16 -3
  139. package/dist/apps/mcp.js.map +1 -1
  140. package/dist/apps/mpp/internal/Policy.d.ts.map +1 -1
  141. package/dist/apps/mpp/internal/Policy.js +4 -2
  142. package/dist/apps/mpp/internal/Policy.js.map +1 -1
  143. package/dist/apps/mpp/internal/Sponsorship.d.ts.map +1 -1
  144. package/dist/apps/mpp/internal/Sponsorship.js +6 -4
  145. package/dist/apps/mpp/internal/Sponsorship.js.map +1 -1
  146. package/dist/apps/relay/App.d.ts +8 -0
  147. package/dist/apps/relay/App.d.ts.map +1 -1
  148. package/dist/apps/relay/App.js +16 -4
  149. package/dist/apps/relay/App.js.map +1 -1
  150. package/dist/apps/relay/Sponsorships.d.ts +4 -6
  151. package/dist/apps/relay/Sponsorships.d.ts.map +1 -1
  152. package/dist/apps/relay/Sponsorships.js +71 -60
  153. package/dist/apps/relay/Sponsorships.js.map +1 -1
  154. package/dist/apps/routes/Access.d.ts +53 -0
  155. package/dist/apps/routes/Access.d.ts.map +1 -1
  156. package/dist/apps/routes/Access.js +121 -0
  157. package/dist/apps/routes/Access.js.map +1 -1
  158. package/dist/apps/routes/App.d.ts +397 -158
  159. package/dist/apps/routes/App.d.ts.map +1 -1
  160. package/dist/apps/routes/App.js.map +1 -1
  161. package/dist/apps/routes/routes/deposit-addresses.d.ts +169 -61
  162. package/dist/apps/routes/routes/deposit-addresses.d.ts.map +1 -1
  163. package/dist/apps/routes/routes/deposit-addresses.js +217 -32
  164. package/dist/apps/routes/routes/deposit-addresses.js.map +1 -1
  165. package/dist/apps/routes/routes/quotes.d.ts +90 -0
  166. package/dist/apps/routes/routes/quotes.d.ts.map +1 -1
  167. package/dist/apps/routes/routes/quotes.js +101 -27
  168. package/dist/apps/routes/routes/quotes.js.map +1 -1
  169. package/dist/apps/routes/routes/transfers.d.ts +187 -135
  170. package/dist/apps/routes/routes/transfers.d.ts.map +1 -1
  171. package/dist/apps/routes/routes/transfers.js +182 -37
  172. package/dist/apps/routes/routes/transfers.js.map +1 -1
  173. package/dist/cli/ApiKeys.d.ts +120 -0
  174. package/dist/cli/ApiKeys.d.ts.map +1 -0
  175. package/dist/cli/ApiKeys.js +138 -0
  176. package/dist/cli/ApiKeys.js.map +1 -0
  177. package/dist/cli/Cli.d.ts +92 -34
  178. package/dist/cli/Cli.d.ts.map +1 -1
  179. package/dist/cli/Cli.js +188 -11
  180. package/dist/cli/Cli.js.map +1 -1
  181. package/dist/cli/Credentials.d.ts +95 -0
  182. package/dist/cli/Credentials.d.ts.map +1 -0
  183. package/dist/cli/Credentials.js +110 -0
  184. package/dist/cli/Credentials.js.map +1 -0
  185. package/dist/cli/Spec.d.ts +59 -0
  186. package/dist/cli/Spec.d.ts.map +1 -0
  187. package/dist/cli/Spec.js +77 -0
  188. package/dist/cli/Spec.js.map +1 -0
  189. package/dist/cli/bin.js +5 -1
  190. package/dist/cli/bin.js.map +1 -1
  191. package/dist/cli/commands/admin.d.ts +5 -5
  192. package/dist/cli/commands/admin.d.ts.map +1 -1
  193. package/dist/cli/commands/auth.d.ts +73 -0
  194. package/dist/cli/commands/auth.d.ts.map +1 -0
  195. package/dist/cli/commands/auth.js +204 -0
  196. package/dist/cli/commands/auth.js.map +1 -0
  197. package/dist/cli/commands/keys.d.ts +17 -0
  198. package/dist/cli/commands/keys.d.ts.map +1 -0
  199. package/dist/cli/commands/keys.js +109 -0
  200. package/dist/cli/commands/keys.js.map +1 -0
  201. package/dist/cloudflare.d.ts +27 -2
  202. package/dist/cloudflare.d.ts.map +1 -1
  203. package/dist/cloudflare.js +144 -17
  204. package/dist/cloudflare.js.map +1 -1
  205. package/dist/db/Db.d.ts +23 -0
  206. package/dist/db/Db.d.ts.map +1 -1
  207. package/dist/db/Db.js +418 -1
  208. package/dist/db/Db.js.map +1 -1
  209. package/dist/db/Schema.d.ts +44 -1
  210. package/dist/db/Schema.d.ts.map +1 -1
  211. package/dist/db/Schema.js +56 -3
  212. package/dist/db/Schema.js.map +1 -1
  213. package/dist/db/tables/apiKeyAdmissions.d.ts +28 -2
  214. package/dist/db/tables/apiKeyAdmissions.d.ts.map +1 -1
  215. package/dist/db/tables/apiKeyAdmissions.js +65 -9
  216. package/dist/db/tables/apiKeyAdmissions.js.map +1 -1
  217. package/dist/db/tables/apiKeyOwnerTombstones.d.ts +2 -0
  218. package/dist/db/tables/apiKeyOwnerTombstones.d.ts.map +1 -1
  219. package/dist/db/tables/apiKeyOwnerTombstones.js +2 -2
  220. package/dist/db/tables/apiKeyOwnerTombstones.js.map +1 -1
  221. package/dist/db/tables/authAccounts.d.ts.map +1 -1
  222. package/dist/db/tables/authAccounts.js +1 -0
  223. package/dist/db/tables/authAccounts.js.map +1 -1
  224. package/dist/db/tables/earnVaults.d.ts +5 -1
  225. package/dist/db/tables/earnVaults.d.ts.map +1 -1
  226. package/dist/db/tables/earnVaults.js +12 -1
  227. package/dist/db/tables/earnVaults.js.map +1 -1
  228. package/dist/db/tables/organizations.d.ts +4 -2
  229. package/dist/db/tables/organizations.d.ts.map +1 -1
  230. package/dist/db/tables/organizations.js +8 -34
  231. package/dist/db/tables/organizations.js.map +1 -1
  232. package/dist/db/tables/requestUsage.d.ts +5 -1
  233. package/dist/db/tables/requestUsage.d.ts.map +1 -1
  234. package/dist/db/tables/requestUsage.js +10 -2
  235. package/dist/db/tables/requestUsage.js.map +1 -1
  236. package/dist/db/tables/rewardEligibilityAssociations.d.ts +13 -0
  237. package/dist/db/tables/rewardEligibilityAssociations.d.ts.map +1 -1
  238. package/dist/db/tables/rewardEligibilityAssociations.js +11 -0
  239. package/dist/db/tables/rewardEligibilityAssociations.js.map +1 -1
  240. package/dist/db/tables/rewardRuns.d.ts.map +1 -1
  241. package/dist/db/tables/rewardRuns.js +4 -0
  242. package/dist/db/tables/rewardRuns.js.map +1 -1
  243. package/dist/db/tables/rewardTransactionAttempts.d.ts.map +1 -1
  244. package/dist/db/tables/rewardTransactionAttempts.js +2 -0
  245. package/dist/db/tables/rewardTransactionAttempts.js.map +1 -1
  246. package/dist/db/tables/routesDepositAddresses.d.ts +29 -0
  247. package/dist/db/tables/routesDepositAddresses.d.ts.map +1 -1
  248. package/dist/db/tables/routesDepositAddresses.js +84 -31
  249. package/dist/db/tables/routesDepositAddresses.js.map +1 -1
  250. package/dist/db/tables/routesDeposits.d.ts.map +1 -1
  251. package/dist/db/tables/routesDeposits.js +31 -21
  252. package/dist/db/tables/routesDeposits.js.map +1 -1
  253. package/dist/db/tables/routesIdempotency.d.ts.map +1 -1
  254. package/dist/db/tables/routesIdempotency.js +2 -0
  255. package/dist/db/tables/routesIdempotency.js.map +1 -1
  256. package/dist/db/tables/routesPolicies.d.ts +58 -0
  257. package/dist/db/tables/routesPolicies.d.ts.map +1 -0
  258. package/dist/db/tables/routesPolicies.js +198 -0
  259. package/dist/db/tables/routesPolicies.js.map +1 -0
  260. package/dist/db/tables/routesTransferSubsidies.d.ts +22 -0
  261. package/dist/db/tables/routesTransferSubsidies.d.ts.map +1 -1
  262. package/dist/db/tables/routesTransferSubsidies.js +41 -0
  263. package/dist/db/tables/routesTransferSubsidies.js.map +1 -1
  264. package/dist/db/tables/routesTransferSubsidyNonces.d.ts.map +1 -1
  265. package/dist/db/tables/routesTransferSubsidyNonces.js +12 -4
  266. package/dist/db/tables/routesTransferSubsidyNonces.js.map +1 -1
  267. package/dist/db/tables/routesTransfers.d.ts +26 -1
  268. package/dist/db/tables/routesTransfers.d.ts.map +1 -1
  269. package/dist/db/tables/routesTransfers.js +36 -6
  270. package/dist/db/tables/routesTransfers.js.map +1 -1
  271. package/dist/db/tables/sponsoredTransactions.d.ts +45 -13
  272. package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
  273. package/dist/db/tables/sponsoredTransactions.js +144 -33
  274. package/dist/db/tables/sponsoredTransactions.js.map +1 -1
  275. package/dist/db/tables/users.d.ts +2 -0
  276. package/dist/db/tables/users.d.ts.map +1 -1
  277. package/dist/db/tables/users.js +11 -0
  278. package/dist/db/tables/users.js.map +1 -1
  279. package/dist/db/tables/verifiedTokenRequests.d.ts +21 -4
  280. package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -1
  281. package/dist/db/tables/verifiedTokenRequests.js +65 -44
  282. package/dist/db/tables/verifiedTokenRequests.js.map +1 -1
  283. package/dist/handlers/internal/multisig.d.ts +1 -1
  284. package/dist/handlers/internal/multisig.d.ts.map +1 -1
  285. package/dist/handlers/internal/multisig.js +3 -2
  286. package/dist/handlers/internal/multisig.js.map +1 -1
  287. package/dist/handlers/relay.d.ts +2 -0
  288. package/dist/handlers/relay.d.ts.map +1 -1
  289. package/dist/handlers/relay.js +34 -15
  290. package/dist/handlers/relay.js.map +1 -1
  291. package/dist/internal/Auth.d.ts +73 -6
  292. package/dist/internal/Auth.d.ts.map +1 -1
  293. package/dist/internal/Auth.js +212 -85
  294. package/dist/internal/Auth.js.map +1 -1
  295. package/dist/internal/BetterAuth.d.ts +22 -0
  296. package/dist/internal/BetterAuth.d.ts.map +1 -1
  297. package/dist/internal/BetterAuth.js +17 -14
  298. package/dist/internal/BetterAuth.js.map +1 -1
  299. package/dist/internal/Cache.d.ts +5 -0
  300. package/dist/internal/Cache.d.ts.map +1 -1
  301. package/dist/internal/Cache.js +3 -1
  302. package/dist/internal/Cache.js.map +1 -1
  303. package/dist/internal/CliAuth.d.ts +243 -0
  304. package/dist/internal/CliAuth.d.ts.map +1 -0
  305. package/dist/internal/CliAuth.js +249 -0
  306. package/dist/internal/CliAuth.js.map +1 -0
  307. package/dist/internal/EarnSharePrices.d.ts +1 -1
  308. package/dist/internal/EarnSharePrices.d.ts.map +1 -1
  309. package/dist/internal/EarnSharePrices.js +7 -3
  310. package/dist/internal/EarnSharePrices.js.map +1 -1
  311. package/dist/internal/EarnVaults.d.ts +47 -0
  312. package/dist/internal/EarnVaults.d.ts.map +1 -1
  313. package/dist/internal/EarnVaults.js +188 -4
  314. package/dist/internal/EarnVaults.js.map +1 -1
  315. package/dist/internal/EarnWithdrawals.d.ts +73 -0
  316. package/dist/internal/EarnWithdrawals.d.ts.map +1 -0
  317. package/dist/internal/EarnWithdrawals.js +189 -0
  318. package/dist/internal/EarnWithdrawals.js.map +1 -0
  319. package/dist/internal/ExecutionContext.d.ts +21 -0
  320. package/dist/internal/ExecutionContext.d.ts.map +1 -0
  321. package/dist/internal/ExecutionContext.js +16 -0
  322. package/dist/internal/ExecutionContext.js.map +1 -0
  323. package/dist/internal/Log.d.ts +7 -3
  324. package/dist/internal/Log.d.ts.map +1 -1
  325. package/dist/internal/Log.js +163 -130
  326. package/dist/internal/Log.js.map +1 -1
  327. package/dist/internal/MetricSink.d.ts.map +1 -1
  328. package/dist/internal/MetricSink.js +26 -1
  329. package/dist/internal/MetricSink.js.map +1 -1
  330. package/dist/internal/RateLimit.d.ts +67 -0
  331. package/dist/internal/RateLimit.d.ts.map +1 -1
  332. package/dist/internal/RateLimit.js +174 -27
  333. package/dist/internal/RateLimit.js.map +1 -1
  334. package/dist/internal/Store.d.ts +6 -0
  335. package/dist/internal/Store.d.ts.map +1 -1
  336. package/dist/internal/Store.js +4 -5
  337. package/dist/internal/Store.js.map +1 -1
  338. package/dist/internal/Timing.d.ts +6 -0
  339. package/dist/internal/Timing.d.ts.map +1 -1
  340. package/dist/internal/Timing.js +21 -1
  341. package/dist/internal/Timing.js.map +1 -1
  342. package/dist/internal/Tron.d.ts +124 -0
  343. package/dist/internal/Tron.d.ts.map +1 -0
  344. package/dist/internal/Tron.js +202 -0
  345. package/dist/internal/Tron.js.map +1 -0
  346. package/dist/internal/Viem.d.ts +4 -0
  347. package/dist/internal/Viem.d.ts.map +1 -1
  348. package/dist/internal/Viem.js +25 -6
  349. package/dist/internal/Viem.js.map +1 -1
  350. package/dist/internal/rewards/Read.d.ts +2 -2
  351. package/dist/internal/rewards/Read.d.ts.map +1 -1
  352. package/dist/internal/rewards/Read.js +11 -2
  353. package/dist/internal/rewards/Read.js.map +1 -1
  354. package/dist/internal/routes/Action.d.ts +27 -0
  355. package/dist/internal/routes/Action.d.ts.map +1 -1
  356. package/dist/internal/routes/Action.js +49 -1
  357. package/dist/internal/routes/Action.js.map +1 -1
  358. package/dist/internal/routes/Chain.d.ts +2 -0
  359. package/dist/internal/routes/Chain.d.ts.map +1 -1
  360. package/dist/internal/routes/Chain.js +4 -0
  361. package/dist/internal/routes/Chain.js.map +1 -1
  362. package/dist/internal/routes/DepositAddress.d.ts.map +1 -1
  363. package/dist/internal/routes/DepositAddress.js +5 -0
  364. package/dist/internal/routes/DepositAddress.js.map +1 -1
  365. package/dist/internal/routes/Evidence.d.ts.map +1 -1
  366. package/dist/internal/routes/Evidence.js +6 -2
  367. package/dist/internal/routes/Evidence.js.map +1 -1
  368. package/dist/internal/routes/EvmTransferSettlement.d.ts +17 -0
  369. package/dist/internal/routes/EvmTransferSettlement.d.ts.map +1 -0
  370. package/dist/internal/routes/EvmTransferSettlement.js +196 -0
  371. package/dist/internal/routes/EvmTransferSettlement.js.map +1 -0
  372. package/dist/internal/routes/Policy.d.ts +161 -0
  373. package/dist/internal/routes/Policy.d.ts.map +1 -0
  374. package/dist/internal/routes/Policy.js +249 -0
  375. package/dist/internal/routes/Policy.js.map +1 -0
  376. package/dist/internal/routes/Provider.d.ts +66 -3
  377. package/dist/internal/routes/Provider.d.ts.map +1 -1
  378. package/dist/internal/routes/Provider.js +106 -27
  379. package/dist/internal/routes/Provider.js.map +1 -1
  380. package/dist/internal/routes/Quota.d.ts +57 -0
  381. package/dist/internal/routes/Quota.d.ts.map +1 -0
  382. package/dist/internal/routes/Quota.js +144 -0
  383. package/dist/internal/routes/Quota.js.map +1 -0
  384. package/dist/internal/routes/Reconciliation.d.ts.map +1 -1
  385. package/dist/internal/routes/Reconciliation.js +163 -47
  386. package/dist/internal/routes/Reconciliation.js.map +1 -1
  387. package/dist/internal/routes/SolanaTransferSettlement.d.ts +12 -0
  388. package/dist/internal/routes/SolanaTransferSettlement.d.ts.map +1 -0
  389. package/dist/internal/routes/SolanaTransferSettlement.js +220 -0
  390. package/dist/internal/routes/SolanaTransferSettlement.js.map +1 -0
  391. package/dist/internal/routes/SolanaTransferSubsidy.d.ts +172 -0
  392. package/dist/internal/routes/SolanaTransferSubsidy.d.ts.map +1 -0
  393. package/dist/internal/routes/SolanaTransferSubsidy.js +564 -0
  394. package/dist/internal/routes/SolanaTransferSubsidy.js.map +1 -0
  395. package/dist/internal/routes/Subsidy.d.ts +2 -2
  396. package/dist/internal/routes/Subsidy.d.ts.map +1 -1
  397. package/dist/internal/routes/Subsidy.js +2 -2
  398. package/dist/internal/routes/Subsidy.js.map +1 -1
  399. package/dist/internal/routes/Transfer.d.ts +229 -1
  400. package/dist/internal/routes/Transfer.d.ts.map +1 -1
  401. package/dist/internal/routes/Transfer.js +644 -7
  402. package/dist/internal/routes/Transfer.js.map +1 -1
  403. package/dist/internal/routes/TransferReconciliation.d.ts +6 -0
  404. package/dist/internal/routes/TransferReconciliation.d.ts.map +1 -1
  405. package/dist/internal/routes/TransferReconciliation.js +83 -159
  406. package/dist/internal/routes/TransferReconciliation.js.map +1 -1
  407. package/dist/internal/routes/TransferSettlement.d.ts +45 -0
  408. package/dist/internal/routes/TransferSettlement.d.ts.map +1 -0
  409. package/dist/internal/routes/TransferSettlement.js +2 -0
  410. package/dist/internal/routes/TransferSettlement.js.map +1 -0
  411. package/dist/internal/routes/TransferSubsidy.d.ts +23 -8
  412. package/dist/internal/routes/TransferSubsidy.d.ts.map +1 -1
  413. package/dist/internal/routes/TransferSubsidy.js +64 -5
  414. package/dist/internal/routes/TransferSubsidy.js.map +1 -1
  415. package/dist/internal/routes/TronTransferSettlement.d.ts +12 -0
  416. package/dist/internal/routes/TronTransferSettlement.d.ts.map +1 -0
  417. package/dist/internal/routes/TronTransferSettlement.js +201 -0
  418. package/dist/internal/routes/TronTransferSettlement.js.map +1 -0
  419. package/dist/internal/routes/TronTransferSubsidy.d.ts +174 -0
  420. package/dist/internal/routes/TronTransferSubsidy.d.ts.map +1 -0
  421. package/dist/internal/routes/TronTransferSubsidy.js +439 -0
  422. package/dist/internal/routes/TronTransferSubsidy.js.map +1 -0
  423. package/dist/internal/routes/index.d.ts +3 -0
  424. package/dist/internal/routes/index.d.ts.map +1 -1
  425. package/dist/internal/routes/index.js +3 -0
  426. package/dist/internal/routes/index.js.map +1 -1
  427. package/dist/internal/routes/providers/across.d.ts +3 -0
  428. package/dist/internal/routes/providers/across.d.ts.map +1 -1
  429. package/dist/internal/routes/providers/across.js +11 -0
  430. package/dist/internal/routes/providers/across.js.map +1 -1
  431. package/dist/internal/routes/providers/legacyMesh.d.ts +29 -0
  432. package/dist/internal/routes/providers/legacyMesh.d.ts.map +1 -0
  433. package/dist/internal/routes/providers/legacyMesh.js +474 -0
  434. package/dist/internal/routes/providers/legacyMesh.js.map +1 -0
  435. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts +59 -0
  436. package/dist/internal/routes/providers/legacyMeshDelivery.d.ts.map +1 -0
  437. package/dist/internal/routes/providers/legacyMeshDelivery.js +229 -0
  438. package/dist/internal/routes/providers/legacyMeshDelivery.js.map +1 -0
  439. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts +19 -0
  440. package/dist/internal/routes/providers/legacyMeshOutbound.d.ts.map +1 -0
  441. package/dist/internal/routes/providers/legacyMeshOutbound.js +457 -0
  442. package/dist/internal/routes/providers/legacyMeshOutbound.js.map +1 -0
  443. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts +123 -0
  444. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.d.ts.map +1 -0
  445. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js +333 -0
  446. package/dist/internal/routes/providers/legacyMeshOutboundDelivery.js.map +1 -0
  447. package/dist/internal/routes/providers/propAmm.d.ts +70 -0
  448. package/dist/internal/routes/providers/propAmm.d.ts.map +1 -0
  449. package/dist/internal/routes/providers/propAmm.js +524 -0
  450. package/dist/internal/routes/providers/propAmm.js.map +1 -0
  451. package/dist/internal/routes/providers/relay.d.ts +4 -1
  452. package/dist/internal/routes/providers/relay.d.ts.map +1 -1
  453. package/dist/internal/routes/providers/relay.js +353 -42
  454. package/dist/internal/routes/providers/relay.js.map +1 -1
  455. package/dist/internal/routes/providers/rhino.d.ts +3 -0
  456. package/dist/internal/routes/providers/rhino.d.ts.map +1 -1
  457. package/dist/internal/routes/providers/rhino.js +11 -0
  458. package/dist/internal/routes/providers/rhino.js.map +1 -1
  459. package/dist/internal/routes/providers/squid.d.ts +3 -0
  460. package/dist/internal/routes/providers/squid.d.ts.map +1 -1
  461. package/dist/internal/routes/providers/squid.js +19 -0
  462. package/dist/internal/routes/providers/squid.js.map +1 -1
  463. package/dist/internal/routes/providers/stargate.d.ts.map +1 -1
  464. package/dist/internal/routes/providers/stargate.js +22 -9
  465. package/dist/internal/routes/providers/stargate.js.map +1 -1
  466. package/dist/internal/routes/providers/symbiosis.d.ts.map +1 -1
  467. package/dist/internal/routes/providers/symbiosis.js +13 -17
  468. package/dist/internal/routes/providers/symbiosis.js.map +1 -1
  469. package/dist/providers/index.d.ts +14 -0
  470. package/dist/providers/index.d.ts.map +1 -1
  471. package/dist/providers/index.js +6 -0
  472. package/dist/providers/index.js.map +1 -1
  473. package/package.json +16 -6
  474. package/src/ApiKey.ts +7 -3
  475. package/src/ApiKeys.test.ts +652 -8
  476. package/src/ApiKeys.ts +191 -11
  477. package/src/App.test.ts +405 -18
  478. package/src/App.ts +51 -15
  479. package/src/Client.test-d.ts +157 -10
  480. package/src/Client.test.ts +4 -4
  481. package/src/Scope.ts +1 -2
  482. package/src/admin/App.ts +11 -5
  483. package/src/admin/apps/api-keys.test.ts +98 -2
  484. package/src/admin/apps/api-keys.ts +21 -12
  485. package/src/admin/apps/earn-vaults.test.ts +76 -7
  486. package/src/admin/apps/earn-vaults.ts +47 -8
  487. package/src/admin/apps/organizations.test.ts +147 -31
  488. package/src/admin/apps/organizations.ts +5 -4
  489. package/src/admin/apps/route-policies.test.ts +220 -0
  490. package/src/admin/apps/route-policies.ts +322 -0
  491. package/src/admin/apps/routes-support.test.ts +107 -2
  492. package/src/admin/apps/routes-support.ts +43 -3
  493. package/src/admin/apps/routes.test.ts +150 -0
  494. package/src/admin/apps/routes.ts +97 -1
  495. package/src/admin/apps/scopes.test.ts +1 -1
  496. package/src/admin/apps/verified-tokens.test.ts +32 -0
  497. package/src/admin/apps/verified-tokens.ts +30 -4
  498. package/src/admin/index.ts +0 -1
  499. package/src/admin/ui/plugin.ts +2 -1
  500. package/src/admin/ui/src/components/Dialog.tsx +1 -1
  501. package/src/admin/ui/src/components/EarnVaultForm.tsx +45 -0
  502. package/src/admin/ui/src/components/RoutePicker.tsx +79 -0
  503. package/src/admin/ui/src/lib/earn-vaults.ts +1 -1
  504. package/src/admin/ui/src/lib/route-policies.test.ts +452 -0
  505. package/src/admin/ui/src/lib/route-policies.ts +232 -0
  506. package/src/admin/ui/src/lib/routes.ts +34 -0
  507. package/src/admin/ui/src/lib/verified-tokens.ts +24 -9
  508. package/src/admin/ui/src/routeTree.gen.ts +21 -0
  509. package/src/admin/ui/src/routes/__root.tsx +1 -1
  510. package/src/admin/ui/src/routes/api-keys.tsx +21 -2
  511. package/src/admin/ui/src/routes/early-access.tsx +1 -0
  512. package/src/admin/ui/src/routes/earn.vaults.tsx +1 -0
  513. package/src/admin/ui/src/routes/earn.vaults_.$vaultId.edit.tsx +22 -0
  514. package/src/admin/ui/src/routes/earn.vaults_.new.tsx +10 -0
  515. package/src/admin/ui/src/routes/organizations.tsx +35 -4
  516. package/src/admin/ui/src/routes/organizations_.$orgId.tsx +18 -3
  517. package/src/admin/ui/src/routes/route-policies.tsx +678 -0
  518. package/src/admin/ui/src/routes/routes.tsx +85 -2
  519. package/src/admin/ui/src/routes/routes_.support.tsx +6 -22
  520. package/src/admin/ui/src/routes/subsidies.tsx +1 -0
  521. package/src/admin/ui/src/routes/verified-tokens.tsx +65 -20
  522. package/src/admin/ui.generated.ts +99 -104
  523. package/src/analytics/Analytics.test.ts +4 -50
  524. package/src/analytics/Analytics.ts +65 -1
  525. package/src/analytics/tables/requestEvents.test.ts +402 -1
  526. package/src/analytics/tables/requestEvents.ts +62 -93
  527. package/src/apps/data/App.test.ts +26 -0
  528. package/src/apps/data/routes/activities.test.ts +315 -14
  529. package/src/apps/data/routes/activities.ts +60 -0
  530. package/src/apps/data/routes/balances.ts +5 -7
  531. package/src/apps/data/routes/earn.bench.ts +18 -0
  532. package/src/apps/data/routes/earn.local.test.ts +507 -0
  533. package/src/apps/data/routes/earn.test.ts +405 -127
  534. package/src/apps/data/routes/earn.ts +660 -270
  535. package/src/apps/data/routes/exchanges.bench.ts +3 -1
  536. package/src/apps/data/routes/exchanges.test.ts +166 -2
  537. package/src/apps/data/routes/exchanges.ts +308 -101
  538. package/src/apps/data/routes/fee-amm.test.ts +153 -2
  539. package/src/apps/data/routes/fee-amm.ts +132 -62
  540. package/src/apps/data/routes/receipts.test.ts +21 -18
  541. package/src/apps/data/routes/rpc.test.ts +34 -2
  542. package/src/apps/data/routes/rpc.ts +47 -10
  543. package/src/apps/data/routes/tokens.provenance.test.ts +157 -0
  544. package/src/apps/data/routes/tokens.test.ts +4 -4
  545. package/src/apps/data/routes/tokens.ts +11 -6
  546. package/src/apps/data/routes/transactions.test.ts +29 -0
  547. package/src/apps/data/routes/transactions.ts +33 -22
  548. package/src/apps/data/routes/webhooks.scan.test.ts +29 -0
  549. package/src/apps/data/routes/webhooks.test.ts +18 -3
  550. package/src/apps/data/routes/webhooks.ts +27 -13
  551. package/src/apps/management/App.ts +4 -0
  552. package/src/apps/management/Billing.test.ts +253 -27
  553. package/src/apps/management/Billing.ts +83 -29
  554. package/src/apps/management/routes/api-keys.test.ts +1 -1
  555. package/src/apps/management/routes/api-keys.ts +85 -11
  556. package/src/apps/management/routes/billing.test.ts +68 -4
  557. package/src/apps/management/routes/cli.test.ts +370 -0
  558. package/src/apps/management/routes/cli.ts +533 -0
  559. package/src/apps/management/routes/me.test.ts +14 -4
  560. package/src/apps/management/routes/orgs.test.ts +108 -4
  561. package/src/apps/management/routes/orgs.ts +7 -2
  562. package/src/apps/management/routes/usage.test.ts +2 -2
  563. package/src/apps/management/routes/verified-token-requests.test.ts +16 -2
  564. package/src/apps/management/routes/verified-token-requests.ts +7 -10
  565. package/src/apps/mcp.test.ts +108 -25
  566. package/src/apps/mcp.ts +15 -3
  567. package/src/apps/mpp/internal/Policy.test.ts +51 -4
  568. package/src/apps/mpp/internal/Policy.ts +6 -2
  569. package/src/apps/mpp/internal/Sponsorship.test.ts +29 -0
  570. package/src/apps/mpp/internal/Sponsorship.ts +6 -4
  571. package/src/apps/relay/App.test.ts +85 -1
  572. package/src/apps/relay/App.ts +28 -4
  573. package/src/apps/relay/Sponsorships.test.ts +97 -1
  574. package/src/apps/relay/Sponsorships.ts +77 -66
  575. package/src/apps/routes/Access.test.ts +319 -0
  576. package/src/apps/routes/Access.ts +147 -0
  577. package/src/apps/routes/App.ts +10 -0
  578. package/src/apps/routes/routes/chains.test.ts +3 -2
  579. package/src/apps/routes/routes/deposit-addresses.test.ts +978 -34
  580. package/src/apps/routes/routes/deposit-addresses.ts +243 -32
  581. package/src/apps/routes/routes/propAmm.local.test.ts +951 -0
  582. package/src/apps/routes/routes/quotes.test.ts +81 -8
  583. package/src/apps/routes/routes/quotes.ts +109 -27
  584. package/src/apps/routes/routes/transfers.test.ts +252 -15
  585. package/src/apps/routes/routes/transfers.ts +212 -33
  586. package/src/cli/ApiKeys.test.ts +265 -0
  587. package/src/cli/ApiKeys.ts +189 -0
  588. package/src/cli/Cli.test.ts +188 -0
  589. package/src/cli/Cli.ts +280 -12
  590. package/src/cli/Credentials.test.ts +122 -0
  591. package/src/cli/Credentials.ts +144 -0
  592. package/src/cli/Spec.test.ts +133 -0
  593. package/src/cli/Spec.ts +132 -0
  594. package/src/cli/bin.test.ts +49 -0
  595. package/src/cli/bin.ts +5 -1
  596. package/src/cli/commands/auth.test.ts +138 -0
  597. package/src/cli/commands/auth.ts +254 -0
  598. package/src/cli/commands/keys.test.ts +68 -0
  599. package/src/cli/commands/keys.ts +125 -0
  600. package/src/cloudflare.ts +184 -36
  601. package/src/db/Db.test.ts +877 -0
  602. package/src/db/Db.ts +507 -1
  603. package/src/db/Schema.ts +75 -4
  604. package/src/db/tables/apiKeyAdmissions.test.ts +57 -0
  605. package/src/db/tables/apiKeyAdmissions.ts +101 -11
  606. package/src/db/tables/apiKeyOwnerTombstones.ts +2 -2
  607. package/src/db/tables/authAccounts.test.ts +30 -0
  608. package/src/db/tables/authAccounts.ts +1 -0
  609. package/src/db/tables/earnVaults.test.ts +34 -0
  610. package/src/db/tables/earnVaults.ts +17 -2
  611. package/src/db/tables/organizations.test.ts +148 -84
  612. package/src/db/tables/organizations.ts +11 -43
  613. package/src/db/tables/requestUsage.ts +13 -2
  614. package/src/db/tables/rewardCampaigns.test.ts +163 -0
  615. package/src/db/tables/rewardEligibilityAssociations.test.ts +14 -0
  616. package/src/db/tables/rewardEligibilityAssociations.ts +24 -0
  617. package/src/db/tables/rewardRuns.ts +4 -0
  618. package/src/db/tables/rewardTransactionAttempts.ts +2 -0
  619. package/src/db/tables/routesDepositAddresses.test.ts +263 -0
  620. package/src/db/tables/routesDepositAddresses.ts +118 -34
  621. package/src/db/tables/routesDeposits.test.ts +133 -0
  622. package/src/db/tables/routesDeposits.ts +47 -26
  623. package/src/db/tables/routesIdempotency.test.ts +80 -0
  624. package/src/db/tables/routesIdempotency.ts +2 -0
  625. package/src/db/tables/routesPolicies.test.ts +143 -0
  626. package/src/db/tables/routesPolicies.ts +251 -0
  627. package/src/db/tables/routesTransferSubsidies.ts +64 -0
  628. package/src/db/tables/routesTransferSubsidyNonces.ts +16 -4
  629. package/src/db/tables/routesTransfers.test.ts +183 -2
  630. package/src/db/tables/routesTransfers.ts +65 -6
  631. package/src/db/tables/sponsoredTransactions.test.ts +351 -76
  632. package/src/db/tables/sponsoredTransactions.ts +182 -38
  633. package/src/db/tables/users.test.ts +51 -0
  634. package/src/db/tables/users.ts +12 -0
  635. package/src/db/tables/verifiedTokenRequests.test.ts +39 -20
  636. package/src/db/tables/verifiedTokenRequests.ts +80 -44
  637. package/src/handlers/internal/multisig.store.test.ts +120 -0
  638. package/src/handlers/internal/multisig.test.ts +389 -0
  639. package/src/handlers/internal/multisig.ts +13 -10
  640. package/src/handlers/relay.test.ts +259 -83
  641. package/src/handlers/relay.ts +36 -17
  642. package/src/internal/Auth.test.ts +383 -8
  643. package/src/internal/Auth.ts +272 -99
  644. package/src/internal/BetterAuth.test.ts +58 -22
  645. package/src/internal/BetterAuth.ts +23 -17
  646. package/src/internal/Cache.ts +3 -1
  647. package/src/internal/CliAuth.test.ts +279 -0
  648. package/src/internal/CliAuth.ts +319 -0
  649. package/src/internal/EarnSharePrices.test.ts +25 -0
  650. package/src/internal/EarnSharePrices.ts +9 -2
  651. package/src/internal/EarnVaults.test.ts +67 -0
  652. package/src/internal/EarnVaults.ts +299 -4
  653. package/src/internal/EarnWithdrawals.test.ts +315 -0
  654. package/src/internal/EarnWithdrawals.ts +266 -0
  655. package/src/internal/ExecutionContext.ts +31 -0
  656. package/src/internal/Log.test.ts +210 -0
  657. package/src/internal/Log.ts +180 -142
  658. package/src/internal/MetricSink.test.ts +190 -15
  659. package/src/internal/MetricSink.ts +27 -1
  660. package/src/internal/RateLimit.test.ts +144 -8
  661. package/src/internal/RateLimit.ts +254 -26
  662. package/src/internal/Store.ts +4 -5
  663. package/src/internal/Timing.test.ts +32 -0
  664. package/src/internal/Timing.ts +20 -1
  665. package/src/internal/Tron.test-d.ts +22 -0
  666. package/src/internal/Tron.test.ts +94 -0
  667. package/src/internal/Tron.ts +289 -0
  668. package/src/internal/Viem.rpc.test.ts +76 -0
  669. package/src/internal/Viem.ts +29 -6
  670. package/src/internal/rewards/Read.test.ts +109 -0
  671. package/src/internal/rewards/Read.ts +13 -4
  672. package/src/internal/routes/Action.test.ts +70 -0
  673. package/src/internal/routes/Action.ts +76 -1
  674. package/src/internal/routes/Chain.test.ts +18 -0
  675. package/src/internal/routes/Chain.ts +5 -0
  676. package/src/internal/routes/DepositAddress.ts +5 -0
  677. package/src/internal/routes/Evidence.test.ts +64 -0
  678. package/src/internal/routes/Evidence.ts +11 -3
  679. package/src/internal/routes/EvmTransferSettlement.ts +213 -0
  680. package/src/internal/routes/Policy.test.ts +316 -0
  681. package/src/internal/routes/Policy.ts +399 -0
  682. package/src/internal/routes/Provider.test.ts +103 -2
  683. package/src/internal/routes/Provider.ts +149 -27
  684. package/src/internal/routes/Quota.test.ts +149 -0
  685. package/src/internal/routes/Quota.ts +226 -0
  686. package/src/internal/routes/Reconciliation.local.test.ts +285 -0
  687. package/src/internal/routes/Reconciliation.test.ts +371 -13
  688. package/src/internal/routes/Reconciliation.ts +193 -42
  689. package/src/internal/routes/SolanaTransferSettlement.ts +232 -0
  690. package/src/internal/routes/SolanaTransferSubsidy.test.ts +471 -0
  691. package/src/internal/routes/SolanaTransferSubsidy.ts +760 -0
  692. package/src/internal/routes/SourceObservation.test.ts +221 -0
  693. package/src/internal/routes/Subsidy.local.test.ts +46 -0
  694. package/src/internal/routes/Subsidy.ts +4 -2
  695. package/src/internal/routes/Transfer.solana.test.ts +389 -0
  696. package/src/internal/routes/Transfer.test.ts +130 -1
  697. package/src/internal/routes/Transfer.tron.test.ts +172 -0
  698. package/src/internal/routes/Transfer.ts +866 -8
  699. package/src/internal/routes/TransferReconciliation.test.ts +26 -4
  700. package/src/internal/routes/TransferReconciliation.ts +91 -166
  701. package/src/internal/routes/TransferSettlement.ts +48 -0
  702. package/src/internal/routes/TransferSubsidy.local.test.ts +143 -0
  703. package/src/internal/routes/TransferSubsidy.test.ts +34 -4
  704. package/src/internal/routes/TransferSubsidy.ts +87 -12
  705. package/src/internal/routes/TronTransferSettlement.ts +212 -0
  706. package/src/internal/routes/TronTransferSubsidy.test.ts +109 -0
  707. package/src/internal/routes/TronTransferSubsidy.ts +619 -0
  708. package/src/internal/routes/index.test.ts +3 -0
  709. package/src/internal/routes/index.ts +3 -0
  710. package/src/internal/routes/providers/across.ts +13 -0
  711. package/src/internal/routes/providers/index.test.ts +141 -0
  712. package/src/internal/routes/providers/legacyMesh.test.ts +484 -0
  713. package/src/internal/routes/providers/legacyMesh.ts +633 -0
  714. package/src/internal/routes/providers/legacyMeshDelivery.test.ts +306 -0
  715. package/src/internal/routes/providers/legacyMeshDelivery.ts +320 -0
  716. package/src/internal/routes/providers/legacyMeshOutbound.test.ts +401 -0
  717. package/src/internal/routes/providers/legacyMeshOutbound.ts +566 -0
  718. package/src/internal/routes/providers/legacyMeshOutboundDelivery.ts +473 -0
  719. package/src/internal/routes/providers/propAmm.ts +640 -0
  720. package/src/internal/routes/providers/relay.test.ts +1299 -18
  721. package/src/internal/routes/providers/relay.ts +424 -39
  722. package/src/internal/routes/providers/rhino.ts +14 -1
  723. package/src/internal/routes/providers/squid.ts +21 -0
  724. package/src/internal/routes/providers/stargate.test.ts +105 -1
  725. package/src/internal/routes/providers/stargate.ts +22 -9
  726. package/src/internal/routes/providers/symbiosis.ts +13 -47
  727. package/src/providers/index.test.ts +2 -0
  728. package/src/providers/index.ts +18 -0
  729. package/dist/admin/Access.d.ts +0 -39
  730. package/dist/admin/Access.d.ts.map +0 -1
  731. package/dist/admin/Access.js +0 -73
  732. package/dist/admin/Access.js.map +0 -1
  733. package/src/admin/Access.test.ts +0 -130
  734. package/src/admin/Access.ts +0 -85
package/src/App.test.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as http from 'node:http'
2
+ import { sql } from 'kysely'
2
3
  import { Challenge } from 'mppx'
3
4
  import * as Docs from 'tapimo/docs'
4
- import { ApiKeys, App, Metrics, RateLimit, Store } from 'tapimo/server'
5
+ import { ApiKeys, App, Db, Metrics, RateLimit, Store } from 'tapimo/server'
5
6
  import * as Tokenlist from './apps/data/routes/tokenlist.js'
6
7
  import * as Tokens from './apps/data/routes/tokens.js'
7
8
  import * as Organizations from './db/tables/organizations.js'
@@ -11,6 +12,82 @@ import * as Runtime from '../test/runtime.js'
11
12
  import * as Tempo from '../test/Tempo.js'
12
13
 
13
14
  describe('create', () => {
15
+ test('reuses a database factory within each concurrent request', async () => {
16
+ const databases: Db.Db[] = []
17
+ const source = () => {
18
+ const database = TestApp.database()
19
+ databases.push(database)
20
+ return database
21
+ }
22
+ type Row = { value: number }
23
+ const app = TestApp.create({ auth: false, db: { cached: source, source } }).get(
24
+ '/database-scope',
25
+ async (c) => {
26
+ const first = Db.get(c.get('db'))
27
+ const second = Db.get(c.get('db'))
28
+ const cached = Db.get(c.get('dbCached'))
29
+ const results = await Promise.all([
30
+ sql<Row>`SELECT pg_sleep(0.01), 1 AS value`.execute(first.kysely),
31
+ sql<Row>`SELECT 2 AS value`.execute(second.kysely),
32
+ sql<Row>`SELECT 3 AS value`.execute(cached.kysely),
33
+ ])
34
+ return c.json(results.map((result) => result.rows.map((row) => row.value)))
35
+ },
36
+ )
37
+ try {
38
+ const responses = await Promise.all([
39
+ app.request('/database-scope'),
40
+ app.request('/database-scope'),
41
+ ])
42
+ expect(await Promise.all(responses.map((response) => response.json())))
43
+ .toMatchInlineSnapshot(`
44
+ [
45
+ [
46
+ [
47
+ 1,
48
+ ],
49
+ [
50
+ 2,
51
+ ],
52
+ [
53
+ 3,
54
+ ],
55
+ ],
56
+ [
57
+ [
58
+ 1,
59
+ ],
60
+ [
61
+ 2,
62
+ ],
63
+ [
64
+ 3,
65
+ ],
66
+ ],
67
+ ]
68
+ `)
69
+ expect(databases).toHaveLength(2)
70
+ expect(databases[0]).not.toBe(databases[1])
71
+ expect(
72
+ responses.every((response) => response.headers.get('server-timing')?.includes('db;')),
73
+ ).toBe(true)
74
+ expect(
75
+ responses.every((response) =>
76
+ response.headers.get('server-timing')?.includes('db_cached;'),
77
+ ),
78
+ ).toBe(true)
79
+ expect(
80
+ responses.every((response) =>
81
+ ['db_acquire', 'db_query', 'db_cached_acquire', 'db_cached_query'].every((stage) =>
82
+ response.headers.get('server-timing')?.includes(`${stage};`),
83
+ ),
84
+ ),
85
+ ).toBe(true)
86
+ } finally {
87
+ await Promise.all(databases.map((database) => database.close()))
88
+ }
89
+ })
90
+
14
91
  test('rejects duplicate provider ids', () => {
15
92
  expect(() =>
16
93
  TestApp.create({
@@ -144,11 +221,11 @@ describe('create', () => {
144
221
  })
145
222
 
146
223
  test('bypasses an exhausted edge limit for cached API keys on protected routes', async () => {
147
- const limit = { limit: 1, period: 'minute' } satisfies RateLimit.Limit
148
- const rateLimit = RateLimit.memory()
224
+ let attempts = 0
149
225
  const global = {
150
- async limit({ key }) {
151
- return { success: (await rateLimit.consume({ key, limit })).allowed }
226
+ async limit() {
227
+ attempts++
228
+ return { success: attempts === 1 }
152
229
  },
153
230
  } satisfies RateLimit.Binding
154
231
  const app = TestApp.create({
@@ -184,11 +261,11 @@ describe('create', () => {
184
261
  })
185
262
 
186
263
  test('edge-limits repeated requests after a cached key becomes invalid', async () => {
187
- const limit = { limit: 1, period: 'minute' } satisfies RateLimit.Limit
188
- const rateLimit = RateLimit.memory()
264
+ let attempts = 0
189
265
  const global = {
190
- async limit({ key }) {
191
- return { success: (await rateLimit.consume({ key, limit })).allowed }
266
+ async limit() {
267
+ attempts++
268
+ return { success: attempts === 1 }
192
269
  },
193
270
  } satisfies RateLimit.Binding
194
271
  const store = Store.memory()
@@ -208,7 +285,295 @@ describe('create', () => {
208
285
  expect(throttled.headers.get('server-timing')).toContain('edge_rate_limit')
209
286
  })
210
287
 
211
- test('applies the edge limit before invalid-key lookup and CORS', async () => {
288
+ test('isolates cold API keys from anonymous edge limits', async () => {
289
+ const limit = { limit: 1, period: 'minute' } satisfies RateLimit.Limit
290
+ const rateLimit = RateLimit.memory()
291
+ const ip = {
292
+ async limit({ key }) {
293
+ return { success: (await rateLimit.consume({ key, limit })).allowed }
294
+ },
295
+ } satisfies RateLimit.Binding
296
+ const app = TestApp.create({
297
+ auth: {
298
+ edgeRateLimit: (request, options) =>
299
+ RateLimit.edge(request, { ip, resolvePartition: options.resolvePartition }),
300
+ },
301
+ })
302
+ const headers = { 'cf-connecting-ip': '203.0.113.7' }
303
+
304
+ const allowed = await app.request('/health', { headers })
305
+ const anonymous = await app.request('/health', { headers })
306
+ const authenticated = await app.request('/v1/tokens/not-an-address', {
307
+ headers: { ...headers, 'tempo-api-key': TestApp.key.token },
308
+ })
309
+
310
+ expect(allowed.status).toBe(200)
311
+ expect(anonymous.status).toBe(429)
312
+ expect(authenticated.status).toBe(400)
313
+ expect(authenticated.headers.get('server-timing')).toContain('edge_rate_limit')
314
+ })
315
+
316
+ test('resolves cold and cached API keys without Postgres queries', async () => {
317
+ const queries: number[] = []
318
+ const db = Db.observe(TestApp.database(), { onQuery: (ms) => queries.push(ms) })
319
+ const app = TestApp.create({ cache: { store: Store.memory() }, db })
320
+
321
+ for (let request = 0; request < 2; request++) {
322
+ const response = await app.request('/v1/tokens/not-an-address', {
323
+ headers: { 'tempo-api-key': TestApp.key.token },
324
+ })
325
+
326
+ expect(response.status).toBe(400)
327
+ const stages = response.headers
328
+ .get('server-timing')!
329
+ .split(',')
330
+ .map((stage) => stage.trim().split(';')[0])
331
+ expect(stages.filter((stage) => ['auth_key', 'rate_limit', 'db'].includes(stage!)))
332
+ .toMatchInlineSnapshot(`
333
+ [
334
+ "auth_key",
335
+ "rate_limit",
336
+ ]
337
+ `)
338
+ }
339
+ expect(queries).toMatchInlineSnapshot(`[]`)
340
+ })
341
+
342
+ test.each(['cold', 'cached', 'probe'])(
343
+ 'rejects a KV-fenced key during %s resolution',
344
+ async (mode) => {
345
+ const queries: number[] = []
346
+ const db = Db.observe(TestApp.database(), { onQuery: (ms) => queries.push(ms) })
347
+ const store = Store.memory()
348
+ const { record, token } = await ApiKeys.mintBounded(db, store, {
349
+ orgId: 'org_revocation',
350
+ scopes: ['data:read'],
351
+ })
352
+ const limit = { limit: 1, period: 'minute' } satisfies RateLimit.Limit
353
+ const rateLimit = RateLimit.memory()
354
+ const ip = {
355
+ async limit({ key }) {
356
+ return { success: (await rateLimit.consume({ key, limit })).allowed }
357
+ },
358
+ } satisfies RateLimit.Binding
359
+ const app = TestApp.create({
360
+ auth:
361
+ mode === 'probe'
362
+ ? {
363
+ edgeRateLimit: (request, options) =>
364
+ RateLimit.edge(request, { ip, resolvePartition: options.resolvePartition }),
365
+ }
366
+ : {},
367
+ db,
368
+ kv: { store },
369
+ })
370
+ const headers = { 'cf-connecting-ip': '203.0.113.7', 'tempo-api-key': token }
371
+ if (mode === 'cached')
372
+ expect((await app.request('/v1/tokens/not-an-address', { headers })).status).toBe(400)
373
+ if (mode === 'probe')
374
+ expect(
375
+ (await app.request('/health', { headers: { 'cf-connecting-ip': '203.0.113.7' } })).status,
376
+ ).toBe(200)
377
+ await store.delete(`apikey_id:${record.id}`)
378
+ await ApiKeys.revokeBounded(db, store, record.id)
379
+ queries.length = 0
380
+
381
+ const response = await app.request('/v1/tokens/not-an-address', { headers })
382
+
383
+ expect(response.status).toBe(mode === 'probe' ? 429 : 401)
384
+ expect(queries).toMatchInlineSnapshot(`[]`)
385
+ },
386
+ )
387
+
388
+ test('keeps rotating invalid API keys in the anonymous edge limit', async () => {
389
+ const limit = { limit: 2, period: 'minute' } satisfies RateLimit.Limit
390
+ const rateLimit = RateLimit.memory()
391
+ const ip = {
392
+ async limit({ key }) {
393
+ return { success: (await rateLimit.consume({ key, limit })).allowed }
394
+ },
395
+ } satisfies RateLimit.Binding
396
+ const app = TestApp.create({
397
+ auth: {
398
+ edgeRateLimit: (request, options) =>
399
+ RateLimit.edge(request, { ip, resolvePartition: options.resolvePartition }),
400
+ },
401
+ })
402
+ const headers = { 'cf-connecting-ip': '203.0.113.7' }
403
+
404
+ const invalid = await app.request('/v1/tokens/not-an-address', {
405
+ headers: { ...headers, 'tempo-api-key': 'invalid-one' },
406
+ })
407
+ const rotated = await app.request('/v1/tokens/not-an-address', {
408
+ headers: { ...headers, 'tempo-api-key': 'invalid-two' },
409
+ })
410
+ const blocked = await app.request('/v1/tokens/not-an-address', {
411
+ headers: { ...headers, 'tempo-api-key': 'invalid-three' },
412
+ })
413
+ const authenticated = await app.request('/v1/tokens/not-an-address', {
414
+ headers: { ...headers, 'tempo-api-key': TestApp.key.token },
415
+ })
416
+
417
+ expect(invalid.status).toBe(401)
418
+ expect(rotated.status).toBe(401)
419
+ expect(blocked.status).toBe(429)
420
+ expect(authenticated.status).toBe(400)
421
+ })
422
+
423
+ test('does not cache a key whose isolated edge limit rejects', async () => {
424
+ let attempts = 0
425
+ const ip = {
426
+ async limit() {
427
+ attempts++
428
+ // Shared and partition buckets reject; the credential-probe admission
429
+ // bucket allows so each request exercises the uncached probe path.
430
+ return { success: attempts % 3 === 2 }
431
+ },
432
+ } satisfies RateLimit.Binding
433
+ const app = TestApp.create({
434
+ auth: {
435
+ edgeRateLimit: (request, options) =>
436
+ RateLimit.edge(request, { ip, resolvePartition: options.resolvePartition }),
437
+ },
438
+ })
439
+ const headers = {
440
+ 'cf-connecting-ip': '203.0.113.7',
441
+ 'tempo-api-key': TestApp.key.token,
442
+ }
443
+
444
+ const first = await app.request('/v1/tokens/not-an-address', { headers })
445
+ const second = await app.request('/v1/tokens/not-an-address', { headers })
446
+
447
+ expect(first.status).toBe(429)
448
+ expect(second.status).toBe(429)
449
+ expect(attempts).toBe(6)
450
+ })
451
+
452
+ test('does not warm the resolution cache from concurrent credential probes', async () => {
453
+ const queries: number[] = []
454
+ const db = Db.observe(TestApp.database(), { onQuery: (ms) => queries.push(ms) })
455
+ const store = Store.memory()
456
+ const { record, token: apiKey } = await ApiKeys.mint(store, { scopes: ['data:read'] })
457
+ const release = Promise.withResolvers<void>()
458
+ const partitions: (string | undefined)[] = []
459
+ const app = TestApp.create({
460
+ auth: {
461
+ edgeRateLimit: async (_request, options) => {
462
+ partitions.push(await options.resolvePartition?.())
463
+ if (partitions.length === 2) {
464
+ // Revoke after both probes but before either request enters auth resolution.
465
+ await ApiKeys.revoke(store, record.id)
466
+ release.resolve()
467
+ }
468
+ await release.promise
469
+ },
470
+ },
471
+ db,
472
+ kv: { store },
473
+ })
474
+ const headers = { 'tempo-api-key': apiKey }
475
+
476
+ const responses = await Promise.all([
477
+ app.request('/v1/tokens/not-an-address', { headers }),
478
+ app.request('/v1/tokens/not-an-address', { headers }),
479
+ ])
480
+
481
+ expect(partitions).toHaveLength(2)
482
+ expect(partitions[0]).toBeTypeOf('string')
483
+ expect(partitions[1]).toBe(partitions[0])
484
+ expect(responses.map((response) => response.status)).toMatchInlineSnapshot(`
485
+ [
486
+ 401,
487
+ 401,
488
+ ]
489
+ `)
490
+ expect(queries).toMatchInlineSnapshot(`[]`)
491
+ })
492
+
493
+ test('keeps CLI session tokens out of API-key quota resolution', async () => {
494
+ const partitioned: boolean[] = []
495
+ const app = TestApp.create({
496
+ auth: {
497
+ edgeRateLimit: async (_request, options) => {
498
+ partitioned.push(options.resolvePartition !== undefined)
499
+ },
500
+ },
501
+ })
502
+
503
+ await app.request('/v1/orgs', { headers: { 'tempo-api-key': TestApp.key.token } })
504
+ const cli = await app.request('/v1/orgs', {
505
+ headers: { authorization: `Bearer tempo:cli:${'ab'.repeat(32)}` },
506
+ })
507
+
508
+ expect(partitioned).toEqual([true, false])
509
+ expect(cli.status).toBe(401)
510
+ })
511
+
512
+ test('records the presented credential without an edge limiter', async () => {
513
+ const entries: Log.Entry[] = []
514
+ const app = TestApp.create({ logger: (entry) => void entries.push(entry) })
515
+
516
+ const response = await app.request('/v1/not-a-route', {
517
+ headers: { 'tempo-api-key': TestApp.key.token },
518
+ })
519
+
520
+ expect({
521
+ credential: entries[0]?.credential,
522
+ status: response.status,
523
+ }).toMatchInlineSnapshot(`
524
+ {
525
+ "credential": "api_key",
526
+ "status": 404,
527
+ }
528
+ `)
529
+ })
530
+
531
+ test('attributes a request canceled during auth to its presented credential', async () => {
532
+ const entries: Log.Entry[] = []
533
+ const started = Promise.withResolvers<void>()
534
+ const release = Promise.withResolvers<void>()
535
+ const app = TestApp.create({
536
+ auth: {
537
+ edgeRateLimit: async () => {
538
+ started.resolve()
539
+ await release.promise
540
+ },
541
+ },
542
+ logger: (entry) => void entries.push(entry),
543
+ })
544
+ const controller = new AbortController()
545
+
546
+ const response = app.request('/v1/tokens/not-an-address', {
547
+ headers: { 'tempo-api-key': TestApp.key.token },
548
+ signal: controller.signal,
549
+ })
550
+ await started.promise
551
+ controller.abort()
552
+ const [canceled] = entries
553
+ release.resolve()
554
+ await response
555
+
556
+ expect(entries).toHaveLength(1)
557
+ expect({
558
+ credential: canceled?.credential,
559
+ errorCode: canceled?.errorCode,
560
+ pendingTimings: Object.keys(canceled?.pendingTimings ?? {}),
561
+ principal: canceled?.principal,
562
+ status: canceled?.status,
563
+ }).toMatchInlineSnapshot(`
564
+ {
565
+ "credential": "api_key",
566
+ "errorCode": "client_canceled",
567
+ "pendingTimings": [
568
+ "edge_rate_limit",
569
+ ],
570
+ "principal": undefined,
571
+ "status": 499,
572
+ }
573
+ `)
574
+ })
575
+
576
+ test('applies the edge limit to invalid keys and before CORS', async () => {
212
577
  const limit = { limit: 1, period: 'minute' } satisfies RateLimit.Limit
213
578
  const rateLimit = RateLimit.memory()
214
579
  const global = {
@@ -402,6 +767,27 @@ describe('create', () => {
402
767
  ])
403
768
  })
404
769
 
770
+ test('tags openapi.json and answers a matching If-None-Match with 304', async () => {
771
+ const app = TestApp.create()
772
+ const first = await app.request('/openapi.json')
773
+ const etag = first.headers.get('etag')
774
+ expect(etag).toMatch(/^"[0-9a-f]{32}"$/)
775
+ expect(first.headers.get('cache-control')).toBe('no-cache')
776
+ expect((await app.request('/openapi.json')).headers.get('etag')).toBe(etag)
777
+
778
+ // CDNs weaken strong tags when they compress, so weak validators must match too.
779
+ const revalidated = await app.request('/openapi.json', {
780
+ headers: { 'if-none-match': `W/${etag}` },
781
+ })
782
+ expect(revalidated.status).toBe(304)
783
+ expect(revalidated.headers.get('etag')).toBe(etag)
784
+ expect(await revalidated.text()).toBe('')
785
+
786
+ const stale = await app.request('/openapi.json', { headers: { 'if-none-match': '"stale"' } })
787
+ expect(stale.status).toBe(200)
788
+ expect((await stale.json()).openapi).toBeDefined()
789
+ })
790
+
405
791
  test('keeps standard and custom error component names distinct', async () => {
406
792
  const spec = await (await TestApp.create().request('/openapi.json')).json()
407
793
  const billing =
@@ -468,7 +854,7 @@ describe('create', () => {
468
854
  expect((await app.request('/v1/tokens/not-an-address', { headers })).status).toBe(401)
469
855
  })
470
856
 
471
- test('rejects an attributed key after its database owner is deleted', async () => {
857
+ test('rejects an attributed key after its owner deletion publishes the KV fence', async () => {
472
858
  const db = TestApp.database()
473
859
  const store = Store.memory()
474
860
  const organization = await Organizations.create(db, { name: 'Acme' })
@@ -480,7 +866,11 @@ describe('create', () => {
480
866
  const headers = { authorization: `Bearer ${token}` }
481
867
 
482
868
  expect((await app.request('/v1/tokens/not-an-address', { headers })).status).toBe(400)
483
- expect(await Organizations.deleteOrganization(db, organization.id)).toBe(true)
869
+ expect(
870
+ await Organizations.deleteOrganization(db, organization.id, {
871
+ beforeCommit: () => ApiKeys.markOwnerDeleting(store, { orgId: organization.id }),
872
+ }),
873
+ ).toBe(true)
484
874
  expect((await app.request('/v1/tokens/not-an-address', { headers })).status).toBe(401)
485
875
  })
486
876
 
@@ -510,7 +900,7 @@ describe('create', () => {
510
900
  expect(rejected.status).toMatchInlineSnapshot(`401`)
511
901
  })
512
902
 
513
- test('caches key resolution by default, so a revoke lags up to the TTL', async () => {
903
+ test('rejects a cached key after its KV revocation marker propagates', async () => {
514
904
  const store = Store.memory()
515
905
  const { record, token } = await ApiKeys.mint(store, {
516
906
  scopes: ['data:read'],
@@ -522,12 +912,9 @@ describe('create', () => {
522
912
  const authed = await app.request('/v1/tokens/not-an-address', { headers })
523
913
  expect(authed.status).toMatchInlineSnapshot(`400`)
524
914
 
525
- // The positive resolve is cached per isolate (60s by default), so the
526
- // revoked key keeps authenticating until the entry expires — the
527
- // documented trade-off for skipping a backend read per request.
528
915
  expect(await ApiKeys.revoke(store, record.id)).toMatchInlineSnapshot(`true`)
529
916
  const revoked = await app.request('/v1/tokens/not-an-address', { headers })
530
- expect(revoked.status).toMatchInlineSnapshot(`400`)
917
+ expect(revoked.status).toMatchInlineSnapshot(`401`)
531
918
  })
532
919
 
533
920
  test('applies endpoint auth overrides', async () => {
@@ -809,7 +1196,7 @@ describe('create', () => {
809
1196
  {
810
1197
  "cache": "hit",
811
1198
  "chainId": 42431,
812
- "route": "/*",
1199
+ "route": "/v1/tokenlist",
813
1200
  },
814
1201
  ]
815
1202
  `)
package/src/App.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as asyncHooks from 'node:async_hooks'
1
2
  import type { Context } from 'hono'
2
3
  import { Hono } from 'hono'
3
4
  import { matchedRoutes } from 'hono/route'
@@ -7,13 +8,16 @@ import { HTTPException } from 'hono/http-exception'
7
8
  import { requestId, type RequestIdVariables } from 'hono/request-id'
8
9
  import { timeout as hono_timeout } from 'hono/timeout'
9
10
  import { generateSpecs } from 'hono-openapi'
11
+ import { Hash, Hex } from 'ox'
10
12
  import type { Chain } from 'viem'
11
13
 
12
14
  import type * as Analytics from './analytics/Analytics.js'
13
15
  import * as ApiKey from './ApiKey.js'
14
16
  import * as Assets from './Assets.js'
15
17
  import * as Auth from './internal/Auth.js'
18
+ import * as Cache from './internal/Cache.js'
16
19
  import * as Db from './db/Db.js'
20
+ import * as ExecutionContext from './internal/ExecutionContext.js'
17
21
  import * as EdgeCache from './internal/EdgeCache.js'
18
22
  import * as core_Email from './internal/Email.js'
19
23
  import * as Log from './internal/Log.js'
@@ -41,6 +45,8 @@ import * as Management from './apps/management/App.js'
41
45
  import * as Mpp from './apps/mpp/App.js'
42
46
  import * as Relay from './apps/relay/App.js'
43
47
 
48
+ const databaseScopes = new asyncHooks.AsyncLocalStorage<Map<Db.Source, Db.Db>>()
49
+
44
50
  export import data = Data.data
45
51
  export import routes = Routes.routes
46
52
  export import management = Management.management
@@ -328,6 +334,13 @@ export function create<const path extends string = '/'>(options: create.Options<
328
334
  // Normalize the `db` option: the plain form is `{ source }` with no cached
329
335
  // side; `cached` falls back to `source` so consumers never branch.
330
336
  const db = 'source' in options.db ? options.db : { source: options.db }
337
+ // Postgres time, including Hyperdrive connect, lands in one stage per source.
338
+ // Wrapped once: snapshot caches key on source identity, so a per-request
339
+ // wrapper would defeat them. Built-in auth reads through the same source.
340
+ const db_observed = {
341
+ cached: observeSource(db.cached ?? db.source, 'db_cached'),
342
+ source: observeSource(db.source, 'db'),
343
+ }
331
344
 
332
345
  const providers = (() => {
333
346
  const values = options.providers ?? []
@@ -356,7 +369,7 @@ export function create<const path extends string = '/'>(options: create.Options<
356
369
  const auth = Auth.install({
357
370
  auth: options.auth,
358
371
  basePath,
359
- db: db.source,
372
+ db: db_observed.source,
360
373
  email: () => email,
361
374
  getClient,
362
375
  kv: options.kv,
@@ -364,12 +377,13 @@ export function create<const path extends string = '/'>(options: create.Options<
364
377
  })
365
378
 
366
379
  base.use('*', Timing.middleware())
380
+ base.use('*', (_c, next) => databaseScopes.run(new Map(), next))
367
381
  base.use('*', async (c, next) => {
368
382
  c.set('analytics', analytics)
369
383
  c.set('basePath', basePath)
370
384
  c.set('chainId', defaultChainId)
371
- c.set('db', db.source)
372
- c.set('dbCached', db.cached ?? db.source)
385
+ c.set('db', db_observed.source)
386
+ c.set('dbCached', db_observed.cached)
373
387
  c.set('email', email)
374
388
  c.set('getClient', (chainId) => getClient(chainId, Auth.getPrincipal(c)))
375
389
  c.set('kv', options.kv)
@@ -377,7 +391,7 @@ export function create<const path extends string = '/'>(options: create.Options<
377
391
  c.set('providers', providers)
378
392
  c.set('rpc', options.rpc)
379
393
  c.set('scopeCatalog', scopeCatalog)
380
- c.set('store', Store.withRequest(store, c.req, { waitUntil: getWaitUntil(c) }))
394
+ c.set('store', Store.withRequest(store, c.req, { waitUntil: ExecutionContext.waitUntil(c) }))
381
395
  c.set('supportedChainIds', supportedChainIds)
382
396
  c.set('vercelOidc', options.vercelOidc)
383
397
  c.set('zones', zones)
@@ -511,6 +525,15 @@ export function create<const path extends string = '/'>(options: create.Options<
511
525
  // while `/openapi.json` and the Vocs handler start the memoized build.
512
526
  let spec: ReturnType<typeof buildSpec> | undefined
513
527
  const getSpec = () => (spec ??= buildSpec())
528
+ // The document is fixed per isolate, so serialize and tag it once; revalidating
529
+ // clients (the CLI loads it on every run) then cost a 304 instead of 1.5 MB.
530
+ type SpecDocument = { body: string; etag: string }
531
+ let specDocument: Promise<SpecDocument> | undefined
532
+ const getSpecDocument = () =>
533
+ (specDocument ??= getSpec().then((value) => {
534
+ const body = JSON.stringify(value)
535
+ return { body, etag: `"${Hash.sha256(Hex.fromString(body)).slice(2, 34)}"` }
536
+ }))
514
537
  const buildSpec = async () => {
515
538
  // Merge each mounted group's contributed OpenAPI metadata (tags, security
516
539
  // schemes, webhooks block). Unused tags/schemes don't render, so a subset
@@ -634,7 +657,13 @@ export function create<const path extends string = '/'>(options: create.Options<
634
657
  })
635
658
  finalized = true
636
659
 
637
- app.get('/openapi.json', async (c) => c.json(await getSpec()))
660
+ app.get('/openapi.json', async (c) => {
661
+ const { body, etag } = await getSpecDocument()
662
+ c.header('Cache-Control', 'no-cache')
663
+ c.header('ETag', etag)
664
+ if (Cache.Etag.matches(etag, c.req.header('If-None-Match'))) return c.body(null, 304)
665
+ return c.body(body, 200, { 'Content-Type': 'application/json' })
666
+ })
638
667
 
639
668
  // The OpenRPC document is a committed build artifact (no runtime generator);
640
669
  // see scripts/openrpc/build.ts and `pnpm openrpc:build`.
@@ -669,6 +698,23 @@ export function listener(app: { fetch: NodeServer.Fetch }): Listener {
669
698
  return NodeServer.getRequestListener(app.fetch)
670
699
  }
671
700
 
701
+ /** Wraps a source so each query's duration lands in the current request's `name` stage. */
702
+ function observeSource(source: Db.Source, name: string): Db.Source {
703
+ return () => {
704
+ // Authentication and handlers share one pool without retaining Worker connections across requests.
705
+ const scope = databaseScopes.getStore()
706
+ const database = scope?.get(source) ?? Db.get(source)
707
+ scope?.set(source, database)
708
+ return Db.observe(database, {
709
+ onQuery: (ms, timing) => {
710
+ Timing.record(name, ms)
711
+ Timing.record(`${name}_acquire`, timing.acquire)
712
+ Timing.record(`${name}_query`, timing.query)
713
+ },
714
+ })
715
+ }
716
+ }
717
+
672
718
  export declare namespace create {
673
719
  /**
674
720
  * Options for creating the Tempo API Hono app: shared chain, RPC, database,
@@ -1228,16 +1274,6 @@ namespace ResponseBody {
1228
1274
  }
1229
1275
  }
1230
1276
 
1231
- function getWaitUntil(c: { executionCtx?: { waitUntil(promise: Promise<unknown>): void } }) {
1232
- // `c.executionCtx` throws in runtimes without one, so cache persistence falls back to an awaited write.
1233
- try {
1234
- const context = c.executionCtx
1235
- return context ? context.waitUntil.bind(context) : undefined
1236
- } catch {
1237
- return undefined
1238
- }
1239
- }
1240
-
1241
1277
  namespace NodeServer {
1242
1278
  type GetRequestListener = (typeof import('@hono/node-server'))['getRequestListener']
1243
1279
  export type Fetch = Parameters<GetRequestListener>[0]