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
@@ -7,6 +7,7 @@ import * as ApiKey from '../../../ApiKey.js'
7
7
  import * as ApiKeys from '../../../ApiKeys.js'
8
8
  import type * as App from '../../../App.js'
9
9
  import * as Db from '../../../db/Db.js'
10
+ import * as RoutesPolicies from '../../../db/tables/routesPolicies.js'
10
11
  import * as Auth from '../../../internal/Auth.js'
11
12
  import * as Billing from '../Billing.js'
12
13
  import * as OpenApi from '../../../internal/OpenApi.js'
@@ -84,7 +85,7 @@ export namespace schema {
84
85
  .array(z.string().check(z.minLength(1)))
85
86
  .check(
86
87
  z.describe(
87
- "Granted scopes. '*' and non-self-serve scopes appear only on keys minted by the super admin.",
88
+ "Granted scopes. '*' requires the super admin; a CLI can derive Routes writes from a provisioned project key.",
88
89
  ),
89
90
  z.meta({ examples: [['data:read']] }),
90
91
  ),
@@ -205,6 +206,14 @@ export namespace schema {
205
206
  z.describe('Unique scopes to grant.'),
206
207
  z.meta({ examples: [['data:read']] }),
207
208
  ),
209
+ sourceKeyId: z.optional(
210
+ z
211
+ .string()
212
+ .check(
213
+ z.describe('Approved project key to derive a scoped CLI credential from.'),
214
+ z.meta({ examples: ['key_1a2b3c4d5e6f7g8h9j0k1m2n'] }),
215
+ ),
216
+ ),
208
217
  })
209
218
  .check(z.describe('Fields for minting an API key.')),
210
219
  'CreateApiKeyRequest',
@@ -384,6 +393,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
384
393
  if (!kv) return notEnabled(c)
385
394
  const createdBy = mintedBy(c)
386
395
  if (!createdBy) return ManagementError.sessionRequired(c)
396
+ const principal = Auth.getPrincipal(c)
387
397
 
388
398
  const body = c.req.valid('json')
389
399
 
@@ -395,7 +405,23 @@ export function apiKeys(options: apiKeys.Options = {}) {
395
405
  })
396
406
 
397
407
  // Session issuers are limited to the finite self-serve catalog, so uniqueness bounds the vector without a new policy cap.
398
- if (!canIssue(c, body.scopes))
408
+ const source =
409
+ body.sourceKeyId && principal?.type === 'session' && principal.cli
410
+ ? await ApiKeys.get(kv.store, body.sourceKeyId, { scopeCatalog: c.get('scopeCatalog') })
411
+ : undefined
412
+ if (
413
+ body.sourceKeyId &&
414
+ (!source ||
415
+ source.orgId !== Auth.org(c).id ||
416
+ source.projectId !== Auth.project(c).id ||
417
+ source.environment !== body.environment)
418
+ )
419
+ return Response.error(c, {
420
+ code: 'scope_not_issuable',
421
+ message: 'Select an approved API key from this project and environment.',
422
+ status: 403,
423
+ })
424
+ if (!canIssue(c, body.scopes, source ?? undefined))
399
425
  return Response.error(c, {
400
426
  code: 'scope_not_issuable',
401
427
  message: 'The requested scopes are not issuable.',
@@ -416,14 +442,27 @@ export function apiKeys(options: apiKeys.Options = {}) {
416
442
  {
417
443
  createdBy,
418
444
  environment: body.environment,
419
- ...(body.allowedIps === undefined ? {} : { allowedIps: body.allowedIps }),
445
+ ...(principal?.type === 'session' && principal.cli
446
+ ? { expiresAt: principal.cli.expiresAt }
447
+ : {}),
448
+ ...(!source && body.allowedIps !== undefined ? { allowedIps: body.allowedIps } : {}),
420
449
  ...(billingActive === undefined ? {} : { billingActive }),
421
450
  ...(body.name === undefined ? {} : { name: body.name }),
422
451
  orgId,
423
452
  projectId: Auth.project(c).id,
424
453
  scopes: body.scopes,
425
454
  },
426
- { scopeCatalog: c.get('scopeCatalog') },
455
+ {
456
+ ...(source
457
+ ? {
458
+ policySourceApiKeyId: source.id,
459
+ sourceScopes: body.scopes.filter(
460
+ (scope) => !Scope.selfServeFrom(c.get('scopeCatalog')).includes(scope),
461
+ ),
462
+ }
463
+ : {}),
464
+ scopeCatalog: c.get('scopeCatalog'),
465
+ },
427
466
  )
428
467
  return c.json(
429
468
  Response.validated(schema.createApiKey.Response, { ...serializeKey(record), token }),
@@ -432,6 +471,12 @@ export function apiKeys(options: apiKeys.Options = {}) {
432
471
  } catch (cause) {
433
472
  if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureProjectError(c)
434
473
  if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
474
+ if (cause instanceof RoutesPolicies.InvalidScopeError)
475
+ return Response.error(c, {
476
+ code: 'scope_not_issuable',
477
+ message: 'The approved source key is no longer available.',
478
+ status: 403,
479
+ })
435
480
  return Response.upstream(c, cause)
436
481
  }
437
482
  },
@@ -637,6 +682,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
637
682
  })
638
683
  return await rotate(c, kv.store, source, createdBy)
639
684
  } catch (cause) {
685
+ if (cause instanceof RoutesPolicies.InvalidScopeError) return keyNotFound(c)
640
686
  if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureOrgError(c)
641
687
  if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
642
688
  return Response.upstream(c, cause)
@@ -848,6 +894,7 @@ export function apiKeys(options: apiKeys.Options = {}) {
848
894
  })
849
895
  return await rotate(c, kv.store, source, createdBy)
850
896
  } catch (cause) {
897
+ if (cause instanceof RoutesPolicies.InvalidScopeError) return keyNotFound(c)
851
898
  if (cause instanceof ApiKeys.OwnerDeletedError) return Auth.ensureProjectError(c)
852
899
  if (cause instanceof ApiKeys.LiveKeyLimitError) return keyLimitReached(c)
853
900
  return Response.upstream(c, cause)
@@ -967,14 +1014,27 @@ function mintedBy(c: Context<App.Environment>) {
967
1014
  }
968
1015
 
969
1016
  /** Checks whether the caller may grant every requested scope. */
970
- function canIssue(c: Context<App.Environment>, scopes: readonly Scope.Id[]) {
1017
+ function canIssue(
1018
+ c: Context<App.Environment>,
1019
+ scopes: readonly Scope.Id[],
1020
+ source?: ApiKeys.Record,
1021
+ ) {
971
1022
  const principal = Auth.getPrincipal(c)
972
1023
  if (principal?.type === 'super_admin') return true
973
1024
  if (principal?.type === 'session') {
974
1025
  const selfServe = Scope.selfServeFrom(c.get('scopeCatalog'))
975
1026
  return (
976
- scopes.every((scope) => selfServe.includes(scope)) &&
977
- (!scopes.includes('management:write') || Auth.membership(c)?.role === 'owner')
1027
+ scopes.every(
1028
+ (scope) =>
1029
+ selfServe.includes(scope) ||
1030
+ (principal.cli &&
1031
+ source &&
1032
+ scope === 'routes:write' &&
1033
+ (source.scopes.includes(scope) || source.scopes.includes(Scope.wildcard))),
1034
+ ) &&
1035
+ (!principal.cli || scopes.every((scope) => principal.cli!.scopes.includes(scope))) &&
1036
+ ((!scopes.includes('management:write') && !scopes.includes('routes:write')) ||
1037
+ Auth.membership(c)?.role === 'owner')
978
1038
  )
979
1039
  }
980
1040
  return false
@@ -986,8 +1046,11 @@ function canRotate(c: Context<App.Environment>, scopes: readonly Scope.Id[]) {
986
1046
  if (principal?.type === 'super_admin') return true
987
1047
  if (principal?.type !== 'session') return false
988
1048
  return (
989
- (!scopes.includes('management:write') && !scopes.includes(Scope.wildcard)) ||
990
- Auth.membership(c)?.role === 'owner'
1049
+ (!principal.cli || scopes.every((scope) => principal.cli!.scopes.includes(scope))) &&
1050
+ ((!scopes.includes('management:write') &&
1051
+ !scopes.includes('routes:write') &&
1052
+ !scopes.includes(Scope.wildcard)) ||
1053
+ Auth.membership(c)?.role === 'owner')
991
1054
  )
992
1055
  }
993
1056
 
@@ -998,6 +1061,8 @@ async function rotate(
998
1061
  source: ApiKeys.Record,
999
1062
  createdBy: string,
1000
1063
  ) {
1064
+ const principal = Auth.getPrincipal(c)
1065
+ const expiresAt = principal?.type === 'session' ? principal.cli?.expiresAt : undefined
1001
1066
  const billingActive =
1002
1067
  source.environment === 'sandbox'
1003
1068
  ? await Billing.active(Db.get(c.get('db')), source.orgId, 'sandbox')
@@ -1013,11 +1078,20 @@ async function rotate(
1013
1078
  ...(source.projectId === undefined ? {} : { projectId: source.projectId }),
1014
1079
  scopes: [...new Set(source.scopes)],
1015
1080
  ...(billingActive === undefined ? {} : { billingActive }),
1016
- ...(source.expiresAt === undefined ? {} : { expiresAt: source.expiresAt }),
1081
+ ...(expiresAt || source.expiresAt
1082
+ ? {
1083
+ expiresAt: [expiresAt, source.expiresAt]
1084
+ .filter(Boolean)
1085
+ .sort((a, b) => Date.parse(a!) - Date.parse(b!))[0]!,
1086
+ }
1087
+ : {}),
1017
1088
  ...(source.name === undefined ? {} : { name: source.name }),
1018
1089
  ...(source.rateLimits === undefined ? {} : { rateLimits: source.rateLimits }),
1019
1090
  },
1020
- { scopeCatalog: c.get('scopeCatalog') },
1091
+ {
1092
+ policySourceApiKeyId: source.id,
1093
+ scopeCatalog: c.get('scopeCatalog'),
1094
+ },
1021
1095
  )
1022
1096
  return c.json(
1023
1097
  Response.validated(schema.rotateApiKey.Response, { ...serializeKey(record), token }),
@@ -1636,16 +1636,18 @@ describe.runIf(TestStripe.secretKey)('stripe sandbox (metering)', () => {
1636
1636
  const finalize = async (input: { feeAmount: string; orgId: string; seed: string }) => {
1637
1637
  const row = await SponsoredTransactions.upsert(db, { ...meterable(input.orgId), signPayload: `0x${input.seed.repeat(32)}` }) // prettier-ignore
1638
1638
  await SponsoredTransactions.finalize(db, row.id, { feeAmount: input.feeAmount, finalizedAt: new Date().toISOString() }) // prettier-ignore
1639
+ return row
1639
1640
  }
1640
1641
  await finalize({ feeAmount: '100000', orgId: 'org_1', seed: '41' })
1641
1642
  await finalize({ feeAmount: '250000', orgId: 'org_1', seed: '42' })
1642
- // A deleted org's row marks without a meter event; a pending row waits.
1643
- await finalize({ feeAmount: '900000', orgId: 'org_ghost', seed: '43' })
1643
+ // A missing customer's liability stays unreported for retry; a pending row waits.
1644
+ const ghost = await finalize({ feeAmount: '900000', orgId: 'org_ghost', seed: '43' })
1644
1645
  await SponsoredTransactions.upsert(db, { ...meterable('org_1'), signPayload: `0x${'44'.repeat(32)}` }) // prettier-ignore
1645
1646
 
1646
1647
  const reporter = core_Billing.createReporter({ db, stripe })
1647
- expect(await reporter.tick()).toStrictEqual({ failed: 0, reported: 2, skipped: 1 })
1648
- expect(await reporter.tick()).toStrictEqual({ failed: 0, reported: 0, skipped: 0 })
1648
+ expect(await reporter.tick()).toStrictEqual({ failed: 1, reported: 2, skipped: 0 })
1649
+ expect(await reporter.tick()).toStrictEqual({ failed: 1, reported: 0, skipped: 0 })
1650
+ expect((await SponsoredTransactions.get(db, ghost.id))?.meterReportedAt).toBeNull()
1649
1651
  })
1650
1652
 
1651
1653
  test('the metered invoice preview matches reported spend', { timeout: 240_000 }, async () => {
@@ -1689,6 +1691,68 @@ describe.runIf(TestStripe.secretKey)('stripe sandbox (metering)', () => {
1689
1691
  expect(line?.amount).toBe(35)
1690
1692
  })
1691
1693
 
1694
+ test.each(['request-first', 'sponsorship-first'] as const)(
1695
+ 'request backlog reaches the invoice when the %s reporter provisions meters',
1696
+ { timeout: 240_000 },
1697
+ async (ordering) => {
1698
+ const db = TestApp.database()
1699
+ const stripe = TestStripe.client()
1700
+ const orgId = `org_${nanoid(10)}`
1701
+ const customer = await stripe.customers.create({
1702
+ metadata: { orgId },
1703
+ name: `Test Org ${nanoid(10)}`,
1704
+ })
1705
+ TestStripe.track(customer.id)
1706
+ await StripeCustomers.create(db, { orgId, stripeCustomerId: customer.id })
1707
+ const bucket = new Date(Date.now() - 2 * 60 * 60 * 1_000)
1708
+ bucket.setUTCMinutes(0, 0, 0)
1709
+ const bucketStart = bucket.toISOString()
1710
+ const reportRequests = () =>
1711
+ core_Billing
1712
+ .createRequestUsageReporter({
1713
+ db,
1714
+ readCounts: async () => [{ bucketStart, count: 100, orgId }],
1715
+ stripe,
1716
+ })
1717
+ .tick()
1718
+ const reportSponsorship = async () => {
1719
+ const seed = ordering === 'request-first' ? '61' : '62'
1720
+ const row = await SponsoredTransactions.upsert(db, {
1721
+ ...meterable(orgId),
1722
+ signPayload: `0x${seed.repeat(32)}`,
1723
+ })
1724
+ await SponsoredTransactions.finalize(db, row.id, {
1725
+ feeAmount: '100000',
1726
+ finalizedAt: new Date().toISOString(),
1727
+ })
1728
+ return core_Billing.createReporter({ db, stripe }).tick()
1729
+ }
1730
+
1731
+ if (ordering === 'request-first') {
1732
+ expect(await reportRequests()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
1733
+ expect(await reportSponsorship()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
1734
+ } else {
1735
+ expect(await reportSponsorship()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
1736
+ expect(await reportRequests()).toStrictEqual({ failed: 0, reported: 1, skipped: 0 })
1737
+ }
1738
+
1739
+ const { priceId } = await core_Billing.ensureFixtures(stripe, 'apiRequests')
1740
+ const [subscription] = (
1741
+ await stripe.subscriptions.list({ customer: customer.id, limit: 1, price: priceId })
1742
+ ).data
1743
+ let line: { amount: number; quantity: number | null } | undefined
1744
+ await until(async () => {
1745
+ const preview = await stripe.invoices.createPreview({
1746
+ customer: customer.id,
1747
+ subscription: subscription!.id,
1748
+ })
1749
+ line = preview.lines.data.find((item) => item.pricing?.price_details?.price === priceId)
1750
+ return line?.quantity === 100
1751
+ }, 180_000)
1752
+ expect(line).toMatchObject({ amount: 1, quantity: 100 })
1753
+ },
1754
+ )
1755
+
1692
1756
  test.each(['past_due', 'canceled'] as const)(
1693
1757
  'a failed metered invoice blocks a %s subscription until payment',
1694
1758
  { timeout: 600_000 },
@@ -0,0 +1,370 @@
1
+ import { testClient } from 'hono/testing'
2
+ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
3
+
4
+ import * as TestApp from '../../../../test/App.js'
5
+ import * as CliAuth from '../../../internal/CliAuth.js'
6
+
7
+ /** Origin pinned for SIWE domain binding; Hono test requests use this host. */
8
+ const origin = 'http://localhost'
9
+
10
+ // RFC 7636 appendix B test vector.
11
+ const codeVerifier = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'
12
+ const codeChallenge = 'E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM'
13
+
14
+ function createApp(options: { consoleUrl?: string | undefined } = {}) {
15
+ const app = TestApp.create({ ...options, session: { wallet: { origin } } })
16
+ return { app, client: testClient(app) }
17
+ }
18
+
19
+ function as(cookie: string) {
20
+ return { headers: { cookie } } as const
21
+ }
22
+
23
+ function bearer(token: string) {
24
+ return { headers: { authorization: `Bearer ${token}` } } as const
25
+ }
26
+
27
+ /** Signs in a fresh scripted account through SIWE, returning its console cookie and user id. */
28
+ async function session({ app, client }: ReturnType<typeof createApp>) {
29
+ const { cookie } = await TestApp.signIn(app, privateKeyToAccount(generatePrivateKey()))
30
+ if (!cookie) throw new Error('Sign-in did not establish a session')
31
+ const me = await client.v1.me.$get(undefined, as(cookie))
32
+ if (me.status !== 200) throw new Error(`Failed to resolve session user: ${me.status}`)
33
+ return { cookie, userId: (await me.json()).id }
34
+ }
35
+
36
+ async function start({ client }: ReturnType<typeof createApp>) {
37
+ const response = await client.v1.cli.authorizations.$post({
38
+ json: { codeChallenge, device: 'build-box', name: 'tempo api 0.1.0' },
39
+ })
40
+ if (response.status !== 200) throw new Error(`Failed to start sign-in: ${response.status}`)
41
+ return response.json()
42
+ }
43
+
44
+ async function exchange({ client }: ReturnType<typeof createApp>, code: string) {
45
+ return client.v1.cli.authorizations[':code{[A-Za-z -]+}'].token.$post({
46
+ json: { codeVerifier },
47
+ param: { code },
48
+ })
49
+ }
50
+
51
+ /** Runs the whole sign-in flow and returns the CLI token plus the approving user. */
52
+ async function signInCli(context: ReturnType<typeof createApp>) {
53
+ const user = await session(context)
54
+ const { code } = await start(context)
55
+ const approve = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve.$post(
56
+ { json: {}, param: { code } },
57
+ as(user.cookie),
58
+ )
59
+ expect(approve.status).toBe(200)
60
+ const response = await exchange(context, code)
61
+ const body = await response.json()
62
+ if (!('status' in body) || body.status !== 'approved') throw new Error('Sign-in was not approved')
63
+ return { token: body.token, user }
64
+ }
65
+
66
+ describe('POST /v1/cli/authorizations', () => {
67
+ test('starts a sign-in with a console verification URL', async () => {
68
+ const response = await createApp().client.v1.cli.authorizations.$post({
69
+ json: { codeChallenge },
70
+ })
71
+ if (response.status !== 200) throw new Error(`Failed to start sign-in: ${response.status}`)
72
+ const { code, expiresAt, ...body } = await response.json()
73
+ expect(code).toMatch(/^[BCDFGHJKLMNPQRSTVWXZ]{4}-[BCDFGHJKLMNPQRSTVWXZ]{4}$/)
74
+ expect(Date.parse(expiresAt)).toBeGreaterThan(Date.now())
75
+ expect(body).toEqual({
76
+ interval: CliAuth.pollInterval,
77
+ verificationUrl: `https://console.tempo.xyz/cli?code=${code}`,
78
+ })
79
+ })
80
+
81
+ test('links to the configured console', async () => {
82
+ const response = await createApp({
83
+ consoleUrl: 'https://console.example.test/',
84
+ }).client.v1.cli.authorizations.$post({ json: { codeChallenge } })
85
+ if (response.status !== 200) throw new Error(`Failed to start sign-in: ${response.status}`)
86
+ const { code, verificationUrl } = await response.json()
87
+ expect(verificationUrl).toBe(`https://console.example.test/cli?code=${code}`)
88
+ })
89
+
90
+ test('rejects a malformed code challenge', async () => {
91
+ const response = await createApp().client.v1.cli.authorizations.$post({
92
+ json: { codeChallenge: 'too-short' },
93
+ })
94
+ expect(response.status).toBe(400)
95
+ })
96
+
97
+ test('stays out of the OpenAPI document', async () => {
98
+ const spec = await (await createApp().app.request('/openapi.json')).json()
99
+ expect(Object.keys(spec.paths).filter((path) => path.startsWith('/v1/cli'))).toEqual([])
100
+ })
101
+ })
102
+
103
+ describe('GET /v1/cli/authorizations/:code', () => {
104
+ test('shows the pending request to a console session', async () => {
105
+ const context = createApp()
106
+ const { cookie } = await session(context)
107
+ const { code } = await start(context)
108
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].$get(
109
+ // Codes are case- and separator-insensitive, as users may retype them.
110
+ { param: { code: code.toLowerCase().replace('-', '') } },
111
+ as(cookie),
112
+ )
113
+ if (response.status !== 200) throw new Error(`Failed to read sign-in: ${response.status}`)
114
+ const { createdAt, expiresAt, ...body } = await response.json()
115
+ expect(Date.parse(expiresAt) - Date.parse(createdAt)).toBe(CliAuth.authorizationTtl)
116
+ expect(body).toEqual({
117
+ client: { device: 'build-box', name: 'tempo api 0.1.0' },
118
+ code,
119
+ scopes: CliAuth.defaultScopes,
120
+ status: 'pending',
121
+ })
122
+ })
123
+
124
+ test('requires a session', async () => {
125
+ const context = createApp()
126
+ const { code } = await start(context)
127
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].$get({
128
+ param: { code },
129
+ })
130
+ expect(response.status).toBe(401)
131
+ })
132
+
133
+ test('reports unknown and malformed codes as not found', async () => {
134
+ const context = createApp()
135
+ const { cookie } = await session(context)
136
+ for (const code of ['BCDF-GHJK', 'ABCD-EFGH']) {
137
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].$get(
138
+ { param: { code } },
139
+ as(cookie),
140
+ )
141
+ expect(response.status).toBe(404)
142
+ expect(await response.json()).toMatchObject({
143
+ error: { code: 'cli_authorization_not_found' },
144
+ })
145
+ }
146
+ })
147
+ })
148
+
149
+ describe('POST /v1/cli/authorizations/:code/token', () => {
150
+ test('reports pending until a console session approves', async () => {
151
+ const context = createApp()
152
+ const { code } = await start(context)
153
+ const response = await exchange(context, code)
154
+ expect(response.status).toBe(200)
155
+ expect(response.headers.get('cache-control')).toBe('no-store')
156
+ expect(await response.json()).toEqual({ status: 'pending' })
157
+ })
158
+
159
+ test('issues a single-use CLI session token that acts as the approving user', async () => {
160
+ const context = createApp()
161
+ const { token, user } = await signInCli(context)
162
+ expect(CliAuth.isToken(token)).toBe(true)
163
+
164
+ const me = await context.client.v1.me.$get(undefined, bearer(token))
165
+ expect(me.status).toBe(200)
166
+ if (me.status !== 200) throw new Error('unreachable')
167
+ expect((await me.json()).id).toBe(user.userId)
168
+ })
169
+
170
+ test('reports denial once, then forgets the code', async () => {
171
+ const context = createApp()
172
+ const { cookie } = await session(context)
173
+ const { code } = await start(context)
174
+ const deny = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].deny.$post(
175
+ { param: { code } },
176
+ as(cookie),
177
+ )
178
+ expect(deny.status).toBe(200)
179
+ expect(await deny.json()).toEqual({ code, status: 'denied' })
180
+ expect(await (await exchange(context, code)).json()).toEqual({ status: 'denied' })
181
+ expect((await exchange(context, code)).status).toBe(404)
182
+ })
183
+
184
+ test('hides the code from callers without the verifier', async () => {
185
+ const context = createApp()
186
+ const { cookie } = await session(context)
187
+ const { code } = await start(context)
188
+ await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve.$post(
189
+ { json: {}, param: { code } },
190
+ as(cookie),
191
+ )
192
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].token.$post({
193
+ json: { codeVerifier: 'x'.repeat(43) },
194
+ param: { code },
195
+ })
196
+ expect(response.status).toBe(404)
197
+ // The verifier holder can still redeem.
198
+ expect((await (await exchange(context, code)).json()) as unknown).toMatchObject({
199
+ status: 'approved',
200
+ })
201
+ })
202
+ })
203
+
204
+ describe('POST /v1/cli/authorizations/:code/approve', () => {
205
+ test.each([
206
+ { body: undefined, contentType: undefined },
207
+ { body: undefined, contentType: 'application/json' },
208
+ { body: '', contentType: 'application/json' },
209
+ { body: '{}', contentType: 'application/json' },
210
+ ])(
211
+ 'uses default scopes for a legacy approval $body $contentType',
212
+ async ({ body, contentType }) => {
213
+ const context = createApp()
214
+ const user = await session(context)
215
+ const { code } = await start(context)
216
+ const response = await context.app.request(`/v1/cli/authorizations/${code}/approve`, {
217
+ ...(body === undefined ? {} : { body }),
218
+ headers: {
219
+ ...(contentType === undefined ? {} : { 'content-type': contentType }),
220
+ cookie: user.cookie,
221
+ },
222
+ method: 'POST',
223
+ })
224
+ expect(response.status).toBe(200)
225
+ expect(await (await exchange(context, code)).json()).toMatchObject({
226
+ scopes: CliAuth.defaultScopes,
227
+ status: 'approved',
228
+ })
229
+ },
230
+ )
231
+
232
+ test.each(['{', 'null', '{"scopes":null}'])(
233
+ 'still rejects invalid nonempty JSON %j',
234
+ async (body) => {
235
+ const context = createApp()
236
+ const user = await session(context)
237
+ const { code } = await start(context)
238
+ const response = await context.app.request(`/v1/cli/authorizations/${code}/approve`, {
239
+ body,
240
+ headers: { 'content-type': 'application/json', cookie: user.cookie },
241
+ method: 'POST',
242
+ })
243
+ expect(response.status).toBe(400)
244
+ expect(await (await exchange(context, code)).json()).toEqual({ status: 'pending' })
245
+ },
246
+ )
247
+
248
+ test('persists selected API scopes through token exchange', async () => {
249
+ const context = createApp()
250
+ const user = await session(context)
251
+ const { code } = await start(context)
252
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve.$post(
253
+ { json: { scopes: ['routes:read'] }, param: { code } },
254
+ as(user.cookie),
255
+ )
256
+ expect(response.status).toBe(200)
257
+ const token = await exchange(context, code)
258
+ expect(await token.json()).toMatchObject({ scopes: ['routes:read'], status: 'approved' })
259
+ })
260
+
261
+ test.each([
262
+ { scopes: ['*'] },
263
+ { scopes: ['unknown:write'] },
264
+ { scopes: ['routes:read', 'routes:read'] },
265
+ ])('rejects unsupported or duplicated scopes $scopes', async ({ scopes }) => {
266
+ const context = createApp()
267
+ const user = await session(context)
268
+ const { code } = await start(context)
269
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve.$post(
270
+ { json: { scopes }, param: { code } },
271
+ as(user.cookie),
272
+ )
273
+ expect(response.status).toBe(400)
274
+ expect(await response.json()).toMatchObject({ error: { code: 'body_invalid' } })
275
+ })
276
+
277
+ test('conflicts once another user decided the request', async () => {
278
+ const context = createApp()
279
+ const first = await session(context)
280
+ const second = await session(context)
281
+ const { code } = await start(context)
282
+ const approve = context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve
283
+ expect((await approve.$post({ json: {}, param: { code } }, as(first.cookie))).status).toBe(200)
284
+ // Repeating the approval is a no-op for the same user.
285
+ expect((await approve.$post({ json: {}, param: { code } }, as(first.cookie))).status).toBe(200)
286
+ const conflict = await approve.$post({ json: {}, param: { code } }, as(second.cookie))
287
+ expect(conflict.status).toBe(409)
288
+ expect(await conflict.json()).toMatchObject({ error: { code: 'cli_authorization_decided' } })
289
+ })
290
+
291
+ test('refuses CLI sessions so a CLI token cannot mint more CLI sessions', async () => {
292
+ const context = createApp()
293
+ const { token } = await signInCli(context)
294
+ const { code } = await start(context)
295
+ const response = await context.client.v1.cli.authorizations[':code{[A-Za-z -]+}'].approve.$post(
296
+ { json: {}, param: { code } },
297
+ bearer(token),
298
+ )
299
+ expect(response.status).toBe(403)
300
+ expect(await response.json()).toMatchObject({
301
+ error: { code: 'forbidden', message: 'Approve CLI sign-ins from the console' },
302
+ })
303
+ })
304
+ })
305
+
306
+ describe('CLI session tokens', () => {
307
+ test('manage organizations, projects, and API keys', async () => {
308
+ const context = createApp()
309
+ const { token } = await signInCli(context)
310
+ const org = await context.client.v1.orgs.$post({ json: { name: 'Acme' } }, bearer(token))
311
+ expect(org.status).toBe(200)
312
+ if (org.status !== 200) throw new Error('unreachable')
313
+ const { id: orgId } = await org.json()
314
+
315
+ const project = await context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects.$post(
316
+ { json: { name: 'Checkout' }, param: { orgId } },
317
+ bearer(token),
318
+ )
319
+ expect(project.status).toBe(200)
320
+ if (project.status !== 200) throw new Error('unreachable')
321
+ const { id: projectId } = await project.json()
322
+
323
+ const key = await context.client.v1.orgs[':orgId{org_[A-Za-z0-9_-]+}'].projects[
324
+ ':projectId{prj_[A-Za-z0-9_-]+}'
325
+ ]['api-keys'].$post(
326
+ { json: { name: 'CLI', scopes: ['data:read'] }, param: { orgId, projectId } },
327
+ bearer(token),
328
+ )
329
+ expect(key.status).toBe(200)
330
+ if (key.status !== 200) throw new Error('unreachable')
331
+ const { createdAt, id, token: apiKey, tokenLast4, ...record } = await key.json()
332
+ expect(apiKey).toMatch(/^tempo:sk:[a-f0-9]{48}$/)
333
+ expect(id).toMatch(/^key_/)
334
+ expect(tokenLast4).toBe(apiKey.slice(-4))
335
+ expect(Date.parse(createdAt)).not.toBeNaN()
336
+ expect(record).toMatchObject({ environment: 'production', name: 'CLI', scopes: ['data:read'] })
337
+ })
338
+
339
+ test('are refused on routes without a session lane', async () => {
340
+ const context = createApp()
341
+ const { token } = await signInCli(context)
342
+ const response = await context.app.request('/v1/tokenlist', bearer(token))
343
+ expect(response.status).toBe(403)
344
+ expect(await response.json()).toMatchObject({
345
+ error: { code: 'forbidden', message: 'CLI sessions cannot call this route. Use an API key.' },
346
+ })
347
+ })
348
+
349
+ test('report unknown tokens as an invalid session', async () => {
350
+ const response = await createApp().client.v1.me.$get(undefined, bearer(CliAuth.generateToken()))
351
+ expect(response.status).toBe(401)
352
+ expect(await response.json()).toMatchObject({
353
+ error: {
354
+ code: 'session_invalid',
355
+ message: 'CLI session is invalid or expired. Sign in again.',
356
+ },
357
+ })
358
+ })
359
+
360
+ test('are revoked by logout', async () => {
361
+ const context = createApp()
362
+ const { token } = await signInCli(context)
363
+ const logout = await context.app.request('/v1/auth/logout', {
364
+ ...bearer(token),
365
+ method: 'POST',
366
+ })
367
+ expect(logout.status).toBe(204)
368
+ expect((await context.client.v1.me.$get(undefined, bearer(token))).status).toBe(401)
369
+ })
370
+ })