@antseed/cli 0.1.179 → 0.1.180

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 (666) hide show
  1. package/README.md +2 -0
  2. package/dist/buyer-identities/store.d.ts +39 -2
  3. package/dist/buyer-identities/store.d.ts.map +1 -1
  4. package/dist/buyer-identities/store.js +99 -10
  5. package/dist/buyer-identities/store.js.map +1 -1
  6. package/dist/cli/commands/buyer/identity.d.ts +3 -1
  7. package/dist/cli/commands/buyer/identity.d.ts.map +1 -1
  8. package/dist/cli/commands/buyer/identity.js +55 -8
  9. package/dist/cli/commands/buyer/identity.js.map +1 -1
  10. package/dist/cli/commands/buyer/identity.test.d.ts +2 -0
  11. package/dist/cli/commands/buyer/identity.test.d.ts.map +1 -0
  12. package/dist/cli/commands/buyer/identity.test.js +168 -0
  13. package/dist/cli/commands/buyer/identity.test.js.map +1 -0
  14. package/dist/cli/commands/buyer/set-authorized-wallet.d.ts +10 -0
  15. package/dist/cli/commands/buyer/set-authorized-wallet.d.ts.map +1 -1
  16. package/dist/cli/commands/buyer/set-authorized-wallet.js +26 -4
  17. package/dist/cli/commands/buyer/set-authorized-wallet.js.map +1 -1
  18. package/dist/cli/commands/buyer/set-authorized-wallet.test.js +37 -2
  19. package/dist/cli/commands/buyer/set-authorized-wallet.test.js.map +1 -1
  20. package/dist/cli/commands/buyer/start.d.ts +15 -0
  21. package/dist/cli/commands/buyer/start.d.ts.map +1 -1
  22. package/dist/cli/commands/buyer/start.js +158 -48
  23. package/dist/cli/commands/buyer/start.js.map +1 -1
  24. package/dist/cli/commands/buyer/start.test.js +16 -1
  25. package/dist/cli/commands/buyer/start.test.js.map +1 -1
  26. package/dist/cli/commands/chat.d.ts +3 -0
  27. package/dist/cli/commands/chat.d.ts.map +1 -0
  28. package/dist/cli/commands/chat.js +189 -0
  29. package/dist/cli/commands/chat.js.map +1 -0
  30. package/dist/cli/commands/gateway/activity.d.ts +15 -0
  31. package/dist/cli/commands/gateway/activity.d.ts.map +1 -0
  32. package/dist/cli/commands/gateway/activity.js +233 -0
  33. package/dist/cli/commands/gateway/activity.js.map +1 -0
  34. package/dist/cli/commands/gateway/admin-token.d.ts +3 -0
  35. package/dist/cli/commands/gateway/admin-token.d.ts.map +1 -0
  36. package/dist/cli/commands/gateway/admin-token.js +90 -0
  37. package/dist/cli/commands/gateway/admin-token.js.map +1 -0
  38. package/dist/cli/commands/gateway/console-link.d.ts +20 -0
  39. package/dist/cli/commands/gateway/console-link.d.ts.map +1 -0
  40. package/dist/cli/commands/gateway/console-link.js +92 -0
  41. package/dist/cli/commands/gateway/console-link.js.map +1 -0
  42. package/dist/cli/commands/gateway/gateway-commands.test.d.ts +2 -0
  43. package/dist/cli/commands/gateway/gateway-commands.test.d.ts.map +1 -0
  44. package/dist/cli/commands/gateway/gateway-commands.test.js +230 -0
  45. package/dist/cli/commands/gateway/gateway-commands.test.js.map +1 -0
  46. package/dist/cli/commands/gateway/gateway-console-commands.test.d.ts +2 -0
  47. package/dist/cli/commands/gateway/gateway-console-commands.test.d.ts.map +1 -0
  48. package/dist/cli/commands/gateway/gateway-console-commands.test.js +373 -0
  49. package/dist/cli/commands/gateway/gateway-console-commands.test.js.map +1 -0
  50. package/dist/cli/commands/gateway/index.d.ts +8 -0
  51. package/dist/cli/commands/gateway/index.d.ts.map +1 -1
  52. package/dist/cli/commands/gateway/index.js +93 -14
  53. package/dist/cli/commands/gateway/index.js.map +1 -1
  54. package/dist/cli/commands/gateway/key.d.ts +4 -0
  55. package/dist/cli/commands/gateway/key.d.ts.map +1 -1
  56. package/dist/cli/commands/gateway/key.js +297 -182
  57. package/dist/cli/commands/gateway/key.js.map +1 -1
  58. package/dist/cli/commands/gateway/member.d.ts +3 -0
  59. package/dist/cli/commands/gateway/member.d.ts.map +1 -0
  60. package/dist/cli/commands/gateway/member.js +302 -0
  61. package/dist/cli/commands/gateway/member.js.map +1 -0
  62. package/dist/cli/commands/gateway/migrate.d.ts +18 -0
  63. package/dist/cli/commands/gateway/migrate.d.ts.map +1 -0
  64. package/dist/cli/commands/gateway/migrate.js +158 -0
  65. package/dist/cli/commands/gateway/migrate.js.map +1 -0
  66. package/dist/cli/commands/gateway/operator.d.ts +11 -0
  67. package/dist/cli/commands/gateway/operator.d.ts.map +1 -0
  68. package/dist/cli/commands/gateway/operator.js +199 -0
  69. package/dist/cli/commands/gateway/operator.js.map +1 -0
  70. package/dist/cli/commands/gateway/operator.test.d.ts +2 -0
  71. package/dist/cli/commands/gateway/operator.test.d.ts.map +1 -0
  72. package/dist/cli/commands/gateway/operator.test.js +151 -0
  73. package/dist/cli/commands/gateway/operator.test.js.map +1 -0
  74. package/dist/cli/commands/gateway/peer-list.d.ts +3 -0
  75. package/dist/cli/commands/gateway/peer-list.d.ts.map +1 -0
  76. package/dist/cli/commands/gateway/peer-list.js +107 -0
  77. package/dist/cli/commands/gateway/peer-list.js.map +1 -0
  78. package/dist/cli/commands/gateway/policy-options.d.ts +23 -0
  79. package/dist/cli/commands/gateway/policy-options.d.ts.map +1 -0
  80. package/dist/cli/commands/gateway/policy-options.js +156 -0
  81. package/dist/cli/commands/gateway/policy-options.js.map +1 -0
  82. package/dist/cli/commands/gateway/preset.d.ts +3 -0
  83. package/dist/cli/commands/gateway/preset.d.ts.map +1 -0
  84. package/dist/cli/commands/gateway/preset.js +181 -0
  85. package/dist/cli/commands/gateway/preset.js.map +1 -0
  86. package/dist/cli/commands/gateway/routing.d.ts +3 -0
  87. package/dist/cli/commands/gateway/routing.d.ts.map +1 -0
  88. package/dist/cli/commands/gateway/routing.js +110 -0
  89. package/dist/cli/commands/gateway/routing.js.map +1 -0
  90. package/dist/cli/commands/gateway/settings.d.ts +4 -0
  91. package/dist/cli/commands/gateway/settings.d.ts.map +1 -0
  92. package/dist/cli/commands/gateway/settings.js +314 -0
  93. package/dist/cli/commands/gateway/settings.js.map +1 -0
  94. package/dist/cli/commands/gateway/shared.d.ts +55 -6
  95. package/dist/cli/commands/gateway/shared.d.ts.map +1 -1
  96. package/dist/cli/commands/gateway/shared.js +206 -26
  97. package/dist/cli/commands/gateway/shared.js.map +1 -1
  98. package/dist/cli/commands/gateway/workspace.d.ts +3 -0
  99. package/dist/cli/commands/gateway/workspace.d.ts.map +1 -0
  100. package/dist/cli/commands/gateway/workspace.js +250 -0
  101. package/dist/cli/commands/gateway/workspace.js.map +1 -0
  102. package/dist/cli/commands/tunnel/start.d.ts.map +1 -1
  103. package/dist/cli/commands/tunnel/start.js +23 -5
  104. package/dist/cli/commands/tunnel/start.js.map +1 -1
  105. package/dist/cli/index.js +12 -44
  106. package/dist/cli/index.js.map +1 -1
  107. package/dist/cli/program.d.ts +4 -0
  108. package/dist/cli/program.d.ts.map +1 -0
  109. package/dist/cli/program.js +49 -0
  110. package/dist/cli/program.js.map +1 -0
  111. package/dist/cli/program.test.d.ts +2 -0
  112. package/dist/cli/program.test.d.ts.map +1 -0
  113. package/dist/cli/program.test.js +38 -0
  114. package/dist/cli/program.test.js.map +1 -0
  115. package/dist/cli/prompt-hidden.d.ts +3 -0
  116. package/dist/cli/prompt-hidden.d.ts.map +1 -0
  117. package/dist/cli/prompt-hidden.js +38 -0
  118. package/dist/cli/prompt-hidden.js.map +1 -0
  119. package/dist/cli/wallet-passphrase.d.ts +48 -0
  120. package/dist/cli/wallet-passphrase.d.ts.map +1 -0
  121. package/dist/cli/wallet-passphrase.js +119 -0
  122. package/dist/cli/wallet-passphrase.js.map +1 -0
  123. package/dist/cli/wallet-passphrase.test.d.ts +2 -0
  124. package/dist/cli/wallet-passphrase.test.d.ts.map +1 -0
  125. package/dist/cli/wallet-passphrase.test.js +79 -0
  126. package/dist/cli/wallet-passphrase.test.js.map +1 -0
  127. package/dist/config/effective.d.ts +12 -0
  128. package/dist/config/effective.d.ts.map +1 -1
  129. package/dist/config/effective.js +39 -6
  130. package/dist/config/effective.js.map +1 -1
  131. package/dist/config/effective.test.js +9 -1
  132. package/dist/config/effective.test.js.map +1 -1
  133. package/dist/config/loader.d.ts +6 -0
  134. package/dist/config/loader.d.ts.map +1 -1
  135. package/dist/config/loader.js +12 -0
  136. package/dist/config/loader.js.map +1 -1
  137. package/dist/config/loader.test.js +7 -1
  138. package/dist/config/loader.test.js.map +1 -1
  139. package/dist/config/types.d.ts +14 -0
  140. package/dist/config/types.d.ts.map +1 -1
  141. package/dist/config/validation.d.ts.map +1 -1
  142. package/dist/config/validation.js +19 -0
  143. package/dist/config/validation.js.map +1 -1
  144. package/dist/gateway/accounting.d.ts +33 -3
  145. package/dist/gateway/accounting.d.ts.map +1 -1
  146. package/dist/gateway/accounting.js +86 -7
  147. package/dist/gateway/accounting.js.map +1 -1
  148. package/dist/gateway/admission-benchmark.test.d.ts +2 -0
  149. package/dist/gateway/admission-benchmark.test.d.ts.map +1 -0
  150. package/dist/gateway/admission-benchmark.test.js +75 -0
  151. package/dist/gateway/admission-benchmark.test.js.map +1 -0
  152. package/dist/gateway/auth/auth.test.d.ts +4 -0
  153. package/dist/gateway/auth/auth.test.d.ts.map +1 -0
  154. package/dist/gateway/auth/auth.test.js +337 -0
  155. package/dist/gateway/auth/auth.test.js.map +1 -0
  156. package/dist/gateway/auth/credentials.test.d.ts +2 -0
  157. package/dist/gateway/auth/credentials.test.d.ts.map +1 -0
  158. package/dist/gateway/auth/credentials.test.js +132 -0
  159. package/dist/gateway/auth/credentials.test.js.map +1 -0
  160. package/dist/gateway/auth/db.d.ts +156 -0
  161. package/dist/gateway/auth/db.d.ts.map +1 -0
  162. package/dist/gateway/auth/db.js +390 -0
  163. package/dist/gateway/auth/db.js.map +1 -0
  164. package/dist/gateway/auth/hardening.test.d.ts +2 -0
  165. package/dist/gateway/auth/hardening.test.d.ts.map +1 -0
  166. package/dist/gateway/auth/hardening.test.js +155 -0
  167. package/dist/gateway/auth/hardening.test.js.map +1 -0
  168. package/dist/gateway/auth/http.d.ts +53 -0
  169. package/dist/gateway/auth/http.d.ts.map +1 -0
  170. package/dist/gateway/auth/http.js +165 -0
  171. package/dist/gateway/auth/http.js.map +1 -0
  172. package/dist/gateway/auth/index.d.ts +26 -0
  173. package/dist/gateway/auth/index.d.ts.map +1 -0
  174. package/dist/gateway/auth/index.js +1014 -0
  175. package/dist/gateway/auth/index.js.map +1 -0
  176. package/dist/gateway/auth/oidc.d.ts +57 -0
  177. package/dist/gateway/auth/oidc.d.ts.map +1 -0
  178. package/dist/gateway/auth/oidc.js +159 -0
  179. package/dist/gateway/auth/oidc.js.map +1 -0
  180. package/dist/gateway/auth/oidc.test.d.ts +2 -0
  181. package/dist/gateway/auth/oidc.test.d.ts.map +1 -0
  182. package/dist/gateway/auth/oidc.test.js +223 -0
  183. package/dist/gateway/auth/oidc.test.js.map +1 -0
  184. package/dist/gateway/auth/reauth.test.d.ts +2 -0
  185. package/dist/gateway/auth/reauth.test.d.ts.map +1 -0
  186. package/dist/gateway/auth/reauth.test.js +108 -0
  187. package/dist/gateway/auth/reauth.test.js.map +1 -0
  188. package/dist/gateway/auth/store-integration.test.d.ts +2 -0
  189. package/dist/gateway/auth/store-integration.test.d.ts.map +1 -0
  190. package/dist/gateway/auth/store-integration.test.js +100 -0
  191. package/dist/gateway/auth/store-integration.test.js.map +1 -0
  192. package/dist/gateway/auth/test-helpers.d.ts +167 -0
  193. package/dist/gateway/auth/test-helpers.d.ts.map +1 -0
  194. package/dist/gateway/auth/test-helpers.js +368 -0
  195. package/dist/gateway/auth/test-helpers.js.map +1 -0
  196. package/dist/gateway/auth/types.d.ts +145 -0
  197. package/dist/gateway/auth/types.d.ts.map +1 -0
  198. package/dist/gateway/auth/types.js +2 -0
  199. package/dist/gateway/auth/types.js.map +1 -0
  200. package/dist/gateway/auth/wallet.d.ts +15 -0
  201. package/dist/gateway/auth/wallet.d.ts.map +1 -0
  202. package/dist/gateway/auth/wallet.js +43 -0
  203. package/dist/gateway/auth/wallet.js.map +1 -0
  204. package/dist/gateway/bundle.d.ts +127 -0
  205. package/dist/gateway/bundle.d.ts.map +1 -0
  206. package/dist/gateway/bundle.js +604 -0
  207. package/dist/gateway/bundle.js.map +1 -0
  208. package/dist/gateway/bundle.test.d.ts +2 -0
  209. package/dist/gateway/bundle.test.d.ts.map +1 -0
  210. package/dist/gateway/bundle.test.js +277 -0
  211. package/dist/gateway/bundle.test.js.map +1 -0
  212. package/dist/gateway/buyer-control.d.ts +33 -0
  213. package/dist/gateway/buyer-control.d.ts.map +1 -0
  214. package/dist/gateway/buyer-control.js +93 -0
  215. package/dist/gateway/buyer-control.js.map +1 -0
  216. package/dist/gateway/buyer-policy-probe.d.ts +41 -0
  217. package/dist/gateway/buyer-policy-probe.d.ts.map +1 -0
  218. package/dist/gateway/buyer-policy-probe.js +99 -0
  219. package/dist/gateway/buyer-policy-probe.js.map +1 -0
  220. package/dist/gateway/buyer-policy-probe.test.d.ts +2 -0
  221. package/dist/gateway/buyer-policy-probe.test.d.ts.map +1 -0
  222. package/dist/gateway/buyer-policy-probe.test.js +128 -0
  223. package/dist/gateway/buyer-policy-probe.test.js.map +1 -0
  224. package/dist/gateway/buyer-process.d.ts +30 -0
  225. package/dist/gateway/buyer-process.d.ts.map +1 -0
  226. package/dist/gateway/buyer-process.js +101 -0
  227. package/dist/gateway/buyer-process.js.map +1 -0
  228. package/dist/gateway/buyer-process.test.d.ts +2 -0
  229. package/dist/gateway/buyer-process.test.d.ts.map +1 -0
  230. package/dist/gateway/buyer-process.test.js +112 -0
  231. package/dist/gateway/buyer-process.test.js.map +1 -0
  232. package/dist/gateway/chat/routes.d.ts +45 -0
  233. package/dist/gateway/chat/routes.d.ts.map +1 -0
  234. package/dist/gateway/chat/routes.js +439 -0
  235. package/dist/gateway/chat/routes.js.map +1 -0
  236. package/dist/gateway/chat/routes.test.d.ts +2 -0
  237. package/dist/gateway/chat/routes.test.d.ts.map +1 -0
  238. package/dist/gateway/chat/routes.test.js +304 -0
  239. package/dist/gateway/chat/routes.test.js.map +1 -0
  240. package/dist/gateway/chat/tools.d.ts +35 -0
  241. package/dist/gateway/chat/tools.d.ts.map +1 -0
  242. package/dist/gateway/chat/tools.js +347 -0
  243. package/dist/gateway/chat/tools.js.map +1 -0
  244. package/dist/gateway/chat/tools.test.d.ts +2 -0
  245. package/dist/gateway/chat/tools.test.d.ts.map +1 -0
  246. package/dist/gateway/chat/tools.test.js +136 -0
  247. package/dist/gateway/chat/tools.test.js.map +1 -0
  248. package/dist/gateway/console-api/access.d.ts +52 -0
  249. package/dist/gateway/console-api/access.d.ts.map +1 -0
  250. package/dist/gateway/console-api/access.js +171 -0
  251. package/dist/gateway/console-api/access.js.map +1 -0
  252. package/dist/gateway/console-api/deps.d.ts +52 -0
  253. package/dist/gateway/console-api/deps.d.ts.map +1 -0
  254. package/dist/gateway/console-api/deps.js +2 -0
  255. package/dist/gateway/console-api/deps.js.map +1 -0
  256. package/dist/gateway/console-api/handlers/admin-tokens.d.ts +8 -0
  257. package/dist/gateway/console-api/handlers/admin-tokens.d.ts.map +1 -0
  258. package/dist/gateway/console-api/handlers/admin-tokens.js +48 -0
  259. package/dist/gateway/console-api/handlers/admin-tokens.js.map +1 -0
  260. package/dist/gateway/console-api/handlers/audit.d.ts +8 -0
  261. package/dist/gateway/console-api/handlers/audit.d.ts.map +1 -0
  262. package/dist/gateway/console-api/handlers/audit.js +19 -0
  263. package/dist/gateway/console-api/handlers/audit.js.map +1 -0
  264. package/dist/gateway/console-api/handlers/audit.test.d.ts +2 -0
  265. package/dist/gateway/console-api/handlers/audit.test.d.ts.map +1 -0
  266. package/dist/gateway/console-api/handlers/audit.test.js +241 -0
  267. package/dist/gateway/console-api/handlers/audit.test.js.map +1 -0
  268. package/dist/gateway/console-api/handlers/data-settings.test.d.ts +2 -0
  269. package/dist/gateway/console-api/handlers/data-settings.test.d.ts.map +1 -0
  270. package/dist/gateway/console-api/handlers/data-settings.test.js +264 -0
  271. package/dist/gateway/console-api/handlers/data-settings.test.js.map +1 -0
  272. package/dist/gateway/console-api/handlers/index.d.ts +4 -0
  273. package/dist/gateway/console-api/handlers/index.d.ts.map +1 -0
  274. package/dist/gateway/console-api/handlers/index.js +24 -0
  275. package/dist/gateway/console-api/handlers/index.js.map +1 -0
  276. package/dist/gateway/console-api/handlers/keys.d.ts +13 -0
  277. package/dist/gateway/console-api/handlers/keys.d.ts.map +1 -0
  278. package/dist/gateway/console-api/handlers/keys.js +128 -0
  279. package/dist/gateway/console-api/handlers/keys.js.map +1 -0
  280. package/dist/gateway/console-api/handlers/keys.test.d.ts +2 -0
  281. package/dist/gateway/console-api/handlers/keys.test.d.ts.map +1 -0
  282. package/dist/gateway/console-api/handlers/keys.test.js +166 -0
  283. package/dist/gateway/console-api/handlers/keys.test.js.map +1 -0
  284. package/dist/gateway/console-api/handlers/network-buyer.d.ts +22 -0
  285. package/dist/gateway/console-api/handlers/network-buyer.d.ts.map +1 -0
  286. package/dist/gateway/console-api/handlers/network-buyer.js +39 -0
  287. package/dist/gateway/console-api/handlers/network-buyer.js.map +1 -0
  288. package/dist/gateway/console-api/handlers/network-mapping.d.ts +33 -0
  289. package/dist/gateway/console-api/handlers/network-mapping.d.ts.map +1 -0
  290. package/dist/gateway/console-api/handlers/network-mapping.js +219 -0
  291. package/dist/gateway/console-api/handlers/network-mapping.js.map +1 -0
  292. package/dist/gateway/console-api/handlers/network-test-helpers.d.ts +35 -0
  293. package/dist/gateway/console-api/handlers/network-test-helpers.d.ts.map +1 -0
  294. package/dist/gateway/console-api/handlers/network-test-helpers.js +121 -0
  295. package/dist/gateway/console-api/handlers/network-test-helpers.js.map +1 -0
  296. package/dist/gateway/console-api/handlers/network.d.ts +15 -0
  297. package/dist/gateway/console-api/handlers/network.d.ts.map +1 -0
  298. package/dist/gateway/console-api/handlers/network.js +57 -0
  299. package/dist/gateway/console-api/handlers/network.js.map +1 -0
  300. package/dist/gateway/console-api/handlers/network.test.d.ts +2 -0
  301. package/dist/gateway/console-api/handlers/network.test.d.ts.map +1 -0
  302. package/dist/gateway/console-api/handlers/network.test.js +383 -0
  303. package/dist/gateway/console-api/handlers/network.test.js.map +1 -0
  304. package/dist/gateway/console-api/handlers/org.d.ts +10 -0
  305. package/dist/gateway/console-api/handlers/org.d.ts.map +1 -0
  306. package/dist/gateway/console-api/handlers/org.js +150 -0
  307. package/dist/gateway/console-api/handlers/org.js.map +1 -0
  308. package/dist/gateway/console-api/handlers/peer-lists.d.ts +5 -0
  309. package/dist/gateway/console-api/handlers/peer-lists.d.ts.map +1 -0
  310. package/dist/gateway/console-api/handlers/peer-lists.js +43 -0
  311. package/dist/gateway/console-api/handlers/peer-lists.js.map +1 -0
  312. package/dist/gateway/console-api/handlers/presets.d.ts +9 -0
  313. package/dist/gateway/console-api/handlers/presets.d.ts.map +1 -0
  314. package/dist/gateway/console-api/handlers/presets.js +79 -0
  315. package/dist/gateway/console-api/handlers/presets.js.map +1 -0
  316. package/dist/gateway/console-api/handlers/routing.d.ts +5 -0
  317. package/dist/gateway/console-api/handlers/routing.d.ts.map +1 -0
  318. package/dist/gateway/console-api/handlers/routing.js +20 -0
  319. package/dist/gateway/console-api/handlers/routing.js.map +1 -0
  320. package/dist/gateway/console-api/handlers/settings.d.ts +10 -0
  321. package/dist/gateway/console-api/handlers/settings.d.ts.map +1 -0
  322. package/dist/gateway/console-api/handlers/settings.js +38 -0
  323. package/dist/gateway/console-api/handlers/settings.js.map +1 -0
  324. package/dist/gateway/console-api/handlers/status.d.ts +9 -0
  325. package/dist/gateway/console-api/handlers/status.d.ts.map +1 -0
  326. package/dist/gateway/console-api/handlers/status.js +47 -0
  327. package/dist/gateway/console-api/handlers/status.js.map +1 -0
  328. package/dist/gateway/console-api/handlers/status.test.d.ts +2 -0
  329. package/dist/gateway/console-api/handlers/status.test.d.ts.map +1 -0
  330. package/dist/gateway/console-api/handlers/status.test.js +82 -0
  331. package/dist/gateway/console-api/handlers/status.test.js.map +1 -0
  332. package/dist/gateway/console-api/handlers/usage.d.ts +10 -0
  333. package/dist/gateway/console-api/handlers/usage.d.ts.map +1 -0
  334. package/dist/gateway/console-api/handlers/usage.js +68 -0
  335. package/dist/gateway/console-api/handlers/usage.js.map +1 -0
  336. package/dist/gateway/console-api/handlers/wallet-card-link.d.ts +29 -0
  337. package/dist/gateway/console-api/handlers/wallet-card-link.d.ts.map +1 -0
  338. package/dist/gateway/console-api/handlers/wallet-card-link.js +46 -0
  339. package/dist/gateway/console-api/handlers/wallet-card-link.js.map +1 -0
  340. package/dist/gateway/console-api/handlers/wallet-chain.d.ts +26 -0
  341. package/dist/gateway/console-api/handlers/wallet-chain.d.ts.map +1 -0
  342. package/dist/gateway/console-api/handlers/wallet-chain.js +80 -0
  343. package/dist/gateway/console-api/handlers/wallet-chain.js.map +1 -0
  344. package/dist/gateway/console-api/handlers/wallet-mapping.d.ts +45 -0
  345. package/dist/gateway/console-api/handlers/wallet-mapping.d.ts.map +1 -0
  346. package/dist/gateway/console-api/handlers/wallet-mapping.js +202 -0
  347. package/dist/gateway/console-api/handlers/wallet-mapping.js.map +1 -0
  348. package/dist/gateway/console-api/handlers/wallet-operator.d.ts +41 -0
  349. package/dist/gateway/console-api/handlers/wallet-operator.d.ts.map +1 -0
  350. package/dist/gateway/console-api/handlers/wallet-operator.js +198 -0
  351. package/dist/gateway/console-api/handlers/wallet-operator.js.map +1 -0
  352. package/dist/gateway/console-api/handlers/wallet-operator.test.d.ts +2 -0
  353. package/dist/gateway/console-api/handlers/wallet-operator.test.d.ts.map +1 -0
  354. package/dist/gateway/console-api/handlers/wallet-operator.test.js +195 -0
  355. package/dist/gateway/console-api/handlers/wallet-operator.test.js.map +1 -0
  356. package/dist/gateway/console-api/handlers/wallet.d.ts +61 -0
  357. package/dist/gateway/console-api/handlers/wallet.d.ts.map +1 -0
  358. package/dist/gateway/console-api/handlers/wallet.js +221 -0
  359. package/dist/gateway/console-api/handlers/wallet.js.map +1 -0
  360. package/dist/gateway/console-api/handlers/wallet.test.d.ts +2 -0
  361. package/dist/gateway/console-api/handlers/wallet.test.d.ts.map +1 -0
  362. package/dist/gateway/console-api/handlers/wallet.test.js +581 -0
  363. package/dist/gateway/console-api/handlers/wallet.test.js.map +1 -0
  364. package/dist/gateway/console-api/handlers/workspaces.d.ts +12 -0
  365. package/dist/gateway/console-api/handlers/workspaces.d.ts.map +1 -0
  366. package/dist/gateway/console-api/handlers/workspaces.js +96 -0
  367. package/dist/gateway/console-api/handlers/workspaces.js.map +1 -0
  368. package/dist/gateway/console-api/operator-types.d.ts +68 -0
  369. package/dist/gateway/console-api/operator-types.d.ts.map +1 -0
  370. package/dist/gateway/console-api/operator-types.js +21 -0
  371. package/dist/gateway/console-api/operator-types.js.map +1 -0
  372. package/dist/gateway/console-api/router.d.ts +97 -0
  373. package/dist/gateway/console-api/router.d.ts.map +1 -0
  374. package/dist/gateway/console-api/router.js +69 -0
  375. package/dist/gateway/console-api/router.js.map +1 -0
  376. package/dist/gateway/console-api/routes.test.d.ts +2 -0
  377. package/dist/gateway/console-api/routes.test.d.ts.map +1 -0
  378. package/dist/gateway/console-api/routes.test.js +331 -0
  379. package/dist/gateway/console-api/routes.test.js.map +1 -0
  380. package/dist/gateway/console-api/serialize.d.ts +33 -0
  381. package/dist/gateway/console-api/serialize.d.ts.map +1 -0
  382. package/dist/gateway/console-api/serialize.js +179 -0
  383. package/dist/gateway/console-api/serialize.js.map +1 -0
  384. package/dist/gateway/console-api/server.d.ts +38 -0
  385. package/dist/gateway/console-api/server.d.ts.map +1 -0
  386. package/dist/gateway/console-api/server.js +308 -0
  387. package/dist/gateway/console-api/server.js.map +1 -0
  388. package/dist/gateway/console-api/server.test.d.ts +2 -0
  389. package/dist/gateway/console-api/server.test.d.ts.map +1 -0
  390. package/dist/gateway/console-api/server.test.js +149 -0
  391. package/dist/gateway/console-api/server.test.js.map +1 -0
  392. package/dist/gateway/console-api/test-support.d.ts +59 -0
  393. package/dist/gateway/console-api/test-support.d.ts.map +1 -0
  394. package/dist/gateway/console-api/test-support.js +120 -0
  395. package/dist/gateway/console-api/test-support.js.map +1 -0
  396. package/dist/gateway/console-api/types.d.ts +779 -0
  397. package/dist/gateway/console-api/types.d.ts.map +1 -0
  398. package/dist/gateway/console-api/types.js +6 -0
  399. package/dist/gateway/console-api/types.js.map +1 -0
  400. package/dist/gateway/console-location.d.ts +21 -0
  401. package/dist/gateway/console-location.d.ts.map +1 -0
  402. package/dist/gateway/console-location.js +41 -0
  403. package/dist/gateway/console-location.js.map +1 -0
  404. package/dist/gateway/console-recovery.d.ts +34 -0
  405. package/dist/gateway/console-recovery.d.ts.map +1 -0
  406. package/dist/gateway/console-recovery.js +94 -0
  407. package/dist/gateway/console-recovery.js.map +1 -0
  408. package/dist/gateway/console-recovery.test.d.ts +2 -0
  409. package/dist/gateway/console-recovery.test.d.ts.map +1 -0
  410. package/dist/gateway/console-recovery.test.js +106 -0
  411. package/dist/gateway/console-recovery.test.js.map +1 -0
  412. package/dist/gateway/console.d.ts +18 -0
  413. package/dist/gateway/console.d.ts.map +1 -0
  414. package/dist/gateway/console.js +101 -0
  415. package/dist/gateway/console.js.map +1 -0
  416. package/dist/gateway/console.test.d.ts +2 -0
  417. package/dist/gateway/console.test.d.ts.map +1 -0
  418. package/dist/gateway/console.test.js +165 -0
  419. package/dist/gateway/console.test.js.map +1 -0
  420. package/dist/gateway/errors.d.ts +3 -0
  421. package/dist/gateway/errors.d.ts.map +1 -0
  422. package/dist/gateway/errors.js +5 -0
  423. package/dist/gateway/errors.js.map +1 -0
  424. package/dist/gateway/exposure.d.ts +33 -0
  425. package/dist/gateway/exposure.d.ts.map +1 -0
  426. package/dist/gateway/exposure.js +146 -0
  427. package/dist/gateway/exposure.js.map +1 -0
  428. package/dist/gateway/exposure.test.d.ts +2 -0
  429. package/dist/gateway/exposure.test.d.ts.map +1 -0
  430. package/dist/gateway/exposure.test.js +93 -0
  431. package/dist/gateway/exposure.test.js.map +1 -0
  432. package/dist/gateway/gateway-policy.test.d.ts +2 -0
  433. package/dist/gateway/gateway-policy.test.d.ts.map +1 -0
  434. package/dist/gateway/gateway-policy.test.js +404 -0
  435. package/dist/gateway/gateway-policy.test.js.map +1 -0
  436. package/dist/gateway/gateway.test.js +47 -25
  437. package/dist/gateway/gateway.test.js.map +1 -1
  438. package/dist/gateway/keys.d.ts +2 -0
  439. package/dist/gateway/keys.d.ts.map +1 -1
  440. package/dist/gateway/keys.js +2 -0
  441. package/dist/gateway/keys.js.map +1 -1
  442. package/dist/gateway/limits.d.ts +32 -8
  443. package/dist/gateway/limits.d.ts.map +1 -1
  444. package/dist/gateway/limits.js +27 -11
  445. package/dist/gateway/limits.js.map +1 -1
  446. package/dist/gateway/observability.d.ts +51 -0
  447. package/dist/gateway/observability.d.ts.map +1 -0
  448. package/dist/gateway/observability.js +136 -0
  449. package/dist/gateway/observability.js.map +1 -0
  450. package/dist/gateway/policy-resolver.d.ts +73 -0
  451. package/dist/gateway/policy-resolver.d.ts.map +1 -0
  452. package/dist/gateway/policy-resolver.js +142 -0
  453. package/dist/gateway/policy-resolver.js.map +1 -0
  454. package/dist/gateway/policy-resolver.test.d.ts +2 -0
  455. package/dist/gateway/policy-resolver.test.d.ts.map +1 -0
  456. package/dist/gateway/policy-resolver.test.js +273 -0
  457. package/dist/gateway/policy-resolver.test.js.map +1 -0
  458. package/dist/gateway/request-errors.test.d.ts +2 -0
  459. package/dist/gateway/request-errors.test.d.ts.map +1 -0
  460. package/dist/gateway/request-errors.test.js +108 -0
  461. package/dist/gateway/request-errors.test.js.map +1 -0
  462. package/dist/gateway/request-shaping.d.ts +25 -0
  463. package/dist/gateway/request-shaping.d.ts.map +1 -0
  464. package/dist/gateway/request-shaping.js +66 -0
  465. package/dist/gateway/request-shaping.js.map +1 -0
  466. package/dist/gateway/response-usage.d.ts +35 -0
  467. package/dist/gateway/response-usage.d.ts.map +1 -0
  468. package/dist/gateway/response-usage.js +167 -0
  469. package/dist/gateway/response-usage.js.map +1 -0
  470. package/dist/gateway/response-usage.test.d.ts +2 -0
  471. package/dist/gateway/response-usage.test.d.ts.map +1 -0
  472. package/dist/gateway/response-usage.test.js +78 -0
  473. package/dist/gateway/response-usage.test.js.map +1 -0
  474. package/dist/gateway/runtime.d.ts +25 -0
  475. package/dist/gateway/runtime.d.ts.map +1 -1
  476. package/dist/gateway/runtime.js +39 -19
  477. package/dist/gateway/runtime.js.map +1 -1
  478. package/dist/gateway/server.d.ts +68 -2
  479. package/dist/gateway/server.d.ts.map +1 -1
  480. package/dist/gateway/server.js +532 -116
  481. package/dist/gateway/server.js.map +1 -1
  482. package/dist/gateway/services/audit.d.ts +16 -0
  483. package/dist/gateway/services/audit.d.ts.map +1 -0
  484. package/dist/gateway/services/audit.js +18 -0
  485. package/dist/gateway/services/audit.js.map +1 -0
  486. package/dist/gateway/services/context.d.ts +66 -0
  487. package/dist/gateway/services/context.d.ts.map +1 -0
  488. package/dist/gateway/services/context.js +52 -0
  489. package/dist/gateway/services/context.js.map +1 -0
  490. package/dist/gateway/services/keys.d.ts +78 -0
  491. package/dist/gateway/services/keys.d.ts.map +1 -0
  492. package/dist/gateway/services/keys.js +232 -0
  493. package/dist/gateway/services/keys.js.map +1 -0
  494. package/dist/gateway/services/members.d.ts +72 -0
  495. package/dist/gateway/services/members.d.ts.map +1 -0
  496. package/dist/gateway/services/members.js +161 -0
  497. package/dist/gateway/services/members.js.map +1 -0
  498. package/dist/gateway/services/network.d.ts +36 -0
  499. package/dist/gateway/services/network.d.ts.map +1 -0
  500. package/dist/gateway/services/network.js +147 -0
  501. package/dist/gateway/services/network.js.map +1 -0
  502. package/dist/gateway/services/operator.d.ts +98 -0
  503. package/dist/gateway/services/operator.d.ts.map +1 -0
  504. package/dist/gateway/services/operator.js +170 -0
  505. package/dist/gateway/services/operator.js.map +1 -0
  506. package/dist/gateway/services/operator.test.d.ts +2 -0
  507. package/dist/gateway/services/operator.test.d.ts.map +1 -0
  508. package/dist/gateway/services/operator.test.js +184 -0
  509. package/dist/gateway/services/operator.test.js.map +1 -0
  510. package/dist/gateway/services/peer-lists.d.ts +20 -0
  511. package/dist/gateway/services/peer-lists.d.ts.map +1 -0
  512. package/dist/gateway/services/peer-lists.js +134 -0
  513. package/dist/gateway/services/peer-lists.js.map +1 -0
  514. package/dist/gateway/services/presets.d.ts +34 -0
  515. package/dist/gateway/services/presets.d.ts.map +1 -0
  516. package/dist/gateway/services/presets.js +134 -0
  517. package/dist/gateway/services/presets.js.map +1 -0
  518. package/dist/gateway/services/routing.d.ts +13 -0
  519. package/dist/gateway/services/routing.d.ts.map +1 -0
  520. package/dist/gateway/services/routing.js +18 -0
  521. package/dist/gateway/services/routing.js.map +1 -0
  522. package/dist/gateway/services/services.test.d.ts +2 -0
  523. package/dist/gateway/services/services.test.d.ts.map +1 -0
  524. package/dist/gateway/services/services.test.js +476 -0
  525. package/dist/gateway/services/services.test.js.map +1 -0
  526. package/dist/gateway/services/settings.d.ts +68 -0
  527. package/dist/gateway/services/settings.d.ts.map +1 -0
  528. package/dist/gateway/services/settings.js +580 -0
  529. package/dist/gateway/services/settings.js.map +1 -0
  530. package/dist/gateway/services/tokens.d.ts +29 -0
  531. package/dist/gateway/services/tokens.d.ts.map +1 -0
  532. package/dist/gateway/services/tokens.js +48 -0
  533. package/dist/gateway/services/tokens.js.map +1 -0
  534. package/dist/gateway/services/usage.d.ts +55 -0
  535. package/dist/gateway/services/usage.d.ts.map +1 -0
  536. package/dist/gateway/services/usage.js +225 -0
  537. package/dist/gateway/services/usage.js.map +1 -0
  538. package/dist/gateway/services/wallet-address-env.test.d.ts +2 -0
  539. package/dist/gateway/services/wallet-address-env.test.d.ts.map +1 -0
  540. package/dist/gateway/services/wallet-address-env.test.js +119 -0
  541. package/dist/gateway/services/wallet-address-env.test.js.map +1 -0
  542. package/dist/gateway/services/wallet-address.d.ts +40 -0
  543. package/dist/gateway/services/wallet-address.d.ts.map +1 -0
  544. package/dist/gateway/services/wallet-address.js +116 -0
  545. package/dist/gateway/services/wallet-address.js.map +1 -0
  546. package/dist/gateway/services/wallet-address.test.d.ts +2 -0
  547. package/dist/gateway/services/wallet-address.test.d.ts.map +1 -0
  548. package/dist/gateway/services/wallet-address.test.js +84 -0
  549. package/dist/gateway/services/wallet-address.test.js.map +1 -0
  550. package/dist/gateway/services/workspaces.d.ts +75 -0
  551. package/dist/gateway/services/workspaces.d.ts.map +1 -0
  552. package/dist/gateway/services/workspaces.js +228 -0
  553. package/dist/gateway/services/workspaces.js.map +1 -0
  554. package/dist/gateway/spend-durability.test.d.ts +2 -0
  555. package/dist/gateway/spend-durability.test.d.ts.map +1 -0
  556. package/dist/gateway/spend-durability.test.js +330 -0
  557. package/dist/gateway/spend-durability.test.js.map +1 -0
  558. package/dist/gateway/spend-feed.d.ts +11 -1
  559. package/dist/gateway/spend-feed.d.ts.map +1 -1
  560. package/dist/gateway/spend-feed.js +17 -4
  561. package/dist/gateway/spend-feed.js.map +1 -1
  562. package/dist/gateway/spend-feed.test.d.ts +2 -0
  563. package/dist/gateway/spend-feed.test.d.ts.map +1 -0
  564. package/dist/gateway/spend-feed.test.js +34 -0
  565. package/dist/gateway/spend-feed.test.js.map +1 -0
  566. package/dist/gateway/store-data.test.d.ts +2 -0
  567. package/dist/gateway/store-data.test.d.ts.map +1 -0
  568. package/dist/gateway/store-data.test.js +346 -0
  569. package/dist/gateway/store-data.test.js.map +1 -0
  570. package/dist/gateway/store-migrations.d.ts +6 -0
  571. package/dist/gateway/store-migrations.d.ts.map +1 -0
  572. package/dist/gateway/store-migrations.js +301 -0
  573. package/dist/gateway/store-migrations.js.map +1 -0
  574. package/dist/gateway/store.d.ts +595 -10
  575. package/dist/gateway/store.d.ts.map +1 -1
  576. package/dist/gateway/store.js +1242 -120
  577. package/dist/gateway/store.js.map +1 -1
  578. package/dist/gateway/store.test.d.ts +2 -0
  579. package/dist/gateway/store.test.d.ts.map +1 -0
  580. package/dist/gateway/store.test.js +185 -0
  581. package/dist/gateway/store.test.js.map +1 -0
  582. package/dist/proxy/buyer-chain-reader.d.ts +68 -0
  583. package/dist/proxy/buyer-chain-reader.d.ts.map +1 -0
  584. package/dist/proxy/buyer-chain-reader.js +152 -0
  585. package/dist/proxy/buyer-chain-reader.js.map +1 -0
  586. package/dist/proxy/buyer-chain-reader.test.d.ts +2 -0
  587. package/dist/proxy/buyer-chain-reader.test.d.ts.map +1 -0
  588. package/dist/proxy/buyer-chain-reader.test.js +102 -0
  589. package/dist/proxy/buyer-chain-reader.test.js.map +1 -0
  590. package/dist/proxy/buyer-proxy.d.ts +169 -3
  591. package/dist/proxy/buyer-proxy.d.ts.map +1 -1
  592. package/dist/proxy/buyer-proxy.js +873 -117
  593. package/dist/proxy/buyer-proxy.js.map +1 -1
  594. package/dist/proxy/buyer-proxy.test.js +31 -0
  595. package/dist/proxy/buyer-proxy.test.js.map +1 -1
  596. package/dist/proxy/chain-read-cache.d.ts +47 -0
  597. package/dist/proxy/chain-read-cache.d.ts.map +1 -0
  598. package/dist/proxy/chain-read-cache.js +110 -0
  599. package/dist/proxy/chain-read-cache.js.map +1 -0
  600. package/dist/proxy/chain-read-cache.test.d.ts +2 -0
  601. package/dist/proxy/chain-read-cache.test.d.ts.map +1 -0
  602. package/dist/proxy/chain-read-cache.test.js +75 -0
  603. package/dist/proxy/chain-read-cache.test.js.map +1 -0
  604. package/dist/proxy/chain-rpc-test-support.d.ts +31 -0
  605. package/dist/proxy/chain-rpc-test-support.d.ts.map +1 -0
  606. package/dist/proxy/chain-rpc-test-support.js +136 -0
  607. package/dist/proxy/chain-rpc-test-support.js.map +1 -0
  608. package/dist/proxy/chain-rpc.d.ts +121 -0
  609. package/dist/proxy/chain-rpc.d.ts.map +1 -0
  610. package/dist/proxy/chain-rpc.js +420 -0
  611. package/dist/proxy/chain-rpc.js.map +1 -0
  612. package/dist/proxy/chain-rpc.test.d.ts +2 -0
  613. package/dist/proxy/chain-rpc.test.d.ts.map +1 -0
  614. package/dist/proxy/chain-rpc.test.js +180 -0
  615. package/dist/proxy/chain-rpc.test.js.map +1 -0
  616. package/dist/proxy/deposit-watch-hub.d.ts +47 -0
  617. package/dist/proxy/deposit-watch-hub.d.ts.map +1 -0
  618. package/dist/proxy/deposit-watch-hub.js +111 -0
  619. package/dist/proxy/deposit-watch-hub.js.map +1 -0
  620. package/dist/proxy/deposit-watch-hub.test.d.ts +2 -0
  621. package/dist/proxy/deposit-watch-hub.test.d.ts.map +1 -0
  622. package/dist/proxy/deposit-watch-hub.test.js +133 -0
  623. package/dist/proxy/deposit-watch-hub.test.js.map +1 -0
  624. package/dist/proxy/deposit-watcher.d.ts +44 -4
  625. package/dist/proxy/deposit-watcher.d.ts.map +1 -1
  626. package/dist/proxy/deposit-watcher.js +76 -11
  627. package/dist/proxy/deposit-watcher.js.map +1 -1
  628. package/dist/proxy/deposit-watcher.test.js +54 -1
  629. package/dist/proxy/deposit-watcher.test.js.map +1 -1
  630. package/dist/proxy/gateway-policy.test.d.ts +2 -0
  631. package/dist/proxy/gateway-policy.test.d.ts.map +1 -0
  632. package/dist/proxy/gateway-policy.test.js +576 -0
  633. package/dist/proxy/gateway-policy.test.js.map +1 -0
  634. package/dist/proxy/network-models.d.ts +2 -0
  635. package/dist/proxy/network-models.d.ts.map +1 -1
  636. package/dist/proxy/network-models.js +3 -1
  637. package/dist/proxy/network-models.js.map +1 -1
  638. package/dist/proxy/route-policy.d.ts +97 -0
  639. package/dist/proxy/route-policy.d.ts.map +1 -0
  640. package/dist/proxy/route-policy.js +230 -0
  641. package/dist/proxy/route-policy.js.map +1 -0
  642. package/dist/proxy/route-policy.test.d.ts +2 -0
  643. package/dist/proxy/route-policy.test.d.ts.map +1 -0
  644. package/dist/proxy/route-policy.test.js +120 -0
  645. package/dist/proxy/route-policy.test.js.map +1 -0
  646. package/dist/proxy/spend-attribution.d.ts +41 -10
  647. package/dist/proxy/spend-attribution.d.ts.map +1 -1
  648. package/dist/proxy/spend-attribution.js +133 -37
  649. package/dist/proxy/spend-attribution.js.map +1 -1
  650. package/dist/proxy/tee-control.d.ts +3 -1
  651. package/dist/proxy/tee-control.d.ts.map +1 -1
  652. package/dist/proxy/tee-control.js +5 -3
  653. package/dist/proxy/tee-control.js.map +1 -1
  654. package/dist/proxy/telemetry.d.ts +2 -1
  655. package/dist/proxy/telemetry.d.ts.map +1 -1
  656. package/dist/proxy/telemetry.js +10 -5
  657. package/dist/proxy/telemetry.js.map +1 -1
  658. package/dist/routing-policy/policy.d.ts +149 -0
  659. package/dist/routing-policy/policy.d.ts.map +1 -0
  660. package/dist/routing-policy/policy.js +450 -0
  661. package/dist/routing-policy/policy.js.map +1 -0
  662. package/dist/routing-policy/policy.test.d.ts +2 -0
  663. package/dist/routing-policy/policy.test.d.ts.map +1 -0
  664. package/dist/routing-policy/policy.test.js +134 -0
  665. package/dist/routing-policy/policy.test.js.map +1 -0
  666. package/package.json +15 -7
@@ -1,13 +1,27 @@
1
+ import { timingSafeEqual } from 'node:crypto';
1
2
  import * as http from 'node:http';
2
3
  import { DEFAULT_BUYER_IDENTITY } from '@antseed/node';
3
4
  import { SPEND_ATTRIBUTION_HEADER } from '../proxy/spend-attribution.js';
4
5
  import { BUYER_IDENTITY_HEADER } from '../proxy/request-utils.js';
6
+ import { GATEWAY_CONTROL_HEADER, ROUTING_POLICY_HEADER, encodePolicyHeader, meaningfulPolicy, policyAllowsModel } from '../routing-policy/policy.js';
7
+ import { effectiveKeyLimits, newRequestTag } from './accounting.js';
8
+ import { errorMessage } from './errors.js';
5
9
  import { isClientCredentialHeader } from '../proxy/credential-headers.js';
6
- import { newRequestTag } from './accounting.js';
7
10
  import { parseBearerToken } from './keys.js';
8
- import { hasSpendLimits, LIMIT_PERIODS } from './limits.js';
11
+ import { BUDGET_PERIODS } from './limits.js';
9
12
  import { formatUsdc, optionalUsdcToDecimalString, parseUsdToUsdc, usdcToDecimalString } from './money.js';
13
+ import { OtlpExporter, observabilitySettings } from './observability.js';
14
+ import { isEmptyPolicy, resolvePolicy } from './policy-resolver.js';
15
+ import { END_USER_HEADER, applyPreset, effectiveRequestModel, extractEndUser, presetSlug } from './request-shaping.js';
16
+ import { ResponseUsageReader } from './response-usage.js';
17
+ import { SPEND_FEED_UNAUTHORIZED_HINT } from './spend-feed.js';
10
18
  import { PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, PAYMENT_SIGNATURE_HEADER, X402_VERSION, buildPaymentRequirements, checkPaymentPayload, decodeHeaderJson, encodeHeaderJson, } from './x402.js';
19
+ /**
20
+ * The gateway's own components (the console chat agent) call `/v1` as a key
21
+ * by its id, without its secret: this header plus the control secret, from
22
+ * loopback only. Stripped from everything forwarded to the buyer.
23
+ */
24
+ export const GATEWAY_INTERNAL_KEY_HEADER = 'x-antseed-gateway-key';
11
25
  const HOP_BY_HOP = new Set([
12
26
  'connection',
13
27
  'keep-alive',
@@ -22,6 +36,19 @@ const HOP_BY_HOP = new Set([
22
36
  const MAX_MODEL_SNIFF_BYTES = 4 * 1024 * 1024;
23
37
  /** Largest request body the gateway accepts, matching the buyer's default upload limit. */
24
38
  const MAX_BODY_BYTES = 64 * 1024 * 1024;
39
+ /** How much of a failed response is read for its error code and message. */
40
+ const MAX_ERROR_BODY_BYTES = 16 * 1024;
41
+ const MAX_ERROR_MESSAGE_CHARS = 500;
42
+ /** Request and response bodies kept per request while content logging is on. */
43
+ const MAX_LOGGED_CONTENT_BYTES = 64 * 1024;
44
+ const RETENTION_SWEEP_MS = 60 * 60 * 1000;
45
+ const DAY_MS = 24 * 60 * 60 * 1000;
46
+ /** Why a key with caps cannot be served while its buyer's spend feed is not reporting. */
47
+ const SPEND_FEED_UNAVAILABLE_MESSAGES = {
48
+ unsupported: 'The buyer for this API key does not report spend; upgrade it to enforce spend limits',
49
+ unauthorized: `The buyer for this API key does not report spend to this gateway; ${SPEND_FEED_UNAUTHORIZED_HINT}`,
50
+ unreachable: 'The buyer for this API key is not reachable',
51
+ };
25
52
  const KEY_INFO_PATH = '/v1/key';
26
53
  const TOPUP_PATH = '/v1/key/topup';
27
54
  /**
@@ -48,8 +75,12 @@ export class GatewayServer {
48
75
  _options;
49
76
  _server = null;
50
77
  _port = 0;
78
+ _retentionTimer = null;
79
+ _pruning = null;
80
+ _exporter;
51
81
  constructor(_options) {
52
82
  this._options = _options;
83
+ this._exporter = _options.exporter ?? new OtlpExporter(() => observabilitySettings(_options.store), { onLog: (m) => this._log(m) });
53
84
  }
54
85
  get port() {
55
86
  return this._port;
@@ -59,7 +90,7 @@ export class GatewayServer {
59
90
  return this._port;
60
91
  this._server = http.createServer((req, res) => {
61
92
  this._handle(req, res).catch((error) => {
62
- this._log(`gateway error: ${error instanceof Error ? error.message : String(error)}`);
93
+ this._log(`gateway error: ${errorMessage(error)}`);
63
94
  if (!res.headersSent)
64
95
  sendError(res, 500, 'api_error', 'internal_error', 'Gateway error');
65
96
  else
@@ -71,12 +102,42 @@ export class GatewayServer {
71
102
  this._server.listen(this._options.listenPort ?? 0, this._options.listenHost ?? '127.0.0.1', () => resolve());
72
103
  });
73
104
  this._port = this._server.address().port;
105
+ void this.pruneRequestLog();
106
+ this._retentionTimer = setInterval(() => { void this.pruneRequestLog(); }, RETENTION_SWEEP_MS);
107
+ this._retentionTimer.unref?.();
74
108
  return this._port;
75
109
  }
110
+ /**
111
+ * Applies the request-log retention setting; resolves to rows removed. A
112
+ * large backlog is pruned one chunk per event-loop turn, and a sweep that
113
+ * is still running is joined rather than started twice.
114
+ */
115
+ pruneRequestLog(now = Date.now()) {
116
+ if (this._pruning)
117
+ return this._pruning;
118
+ const { retentionDays } = observabilitySettings(this._options.store);
119
+ if (!retentionDays)
120
+ return Promise.resolve(0);
121
+ this._pruning = this._options.store.pruneRequests(now - retentionDays * DAY_MS)
122
+ .then((removed) => {
123
+ if (removed > 0)
124
+ this._log(`pruned ${removed} request log row(s) older than ${retentionDays} day(s)`);
125
+ return removed;
126
+ }, (error) => {
127
+ this._log(`gateway could not prune the request log: ${errorMessage(error)}`);
128
+ return 0;
129
+ })
130
+ .finally(() => { this._pruning = null; });
131
+ return this._pruning;
132
+ }
76
133
  async stop() {
77
134
  const server = this._server;
78
135
  this._server = null;
79
136
  this._port = 0;
137
+ if (this._retentionTimer)
138
+ clearInterval(this._retentionTimer);
139
+ this._retentionTimer = null;
140
+ await this._exporter.stop();
80
141
  if (!server)
81
142
  return;
82
143
  await new Promise((resolve) => server.close(() => resolve()));
@@ -87,26 +148,21 @@ export class GatewayServer {
87
148
  async _handle(req, res) {
88
149
  const method = req.method ?? 'GET';
89
150
  const path = req.url ?? '/';
151
+ const pathname = path.split('?')[0];
152
+ if (this._options.console && (pathname === '/console' || pathname.startsWith('/console/'))) {
153
+ if (await this._options.console.handle(req, res))
154
+ return;
155
+ }
90
156
  const route = canonicalizeRoute(method, path);
91
157
  if (!route) {
92
158
  this._log(`gateway rejected route: ${method} ${path}`);
93
159
  sendError(res, 404, 'invalid_request_error', 'not_found', 'Not found');
94
160
  return;
95
161
  }
96
- const canonicalPath = route.path;
97
- const secret = parseBearerToken(req.headers.authorization);
98
- const key = secret ? this._options.store.findKeyBySecret(secret) : null;
99
- if (!key || key.status !== 'active') {
100
- this._log(`gateway rejected authentication: ${method} ${path}`);
101
- res.setHeader('www-authenticate', 'Bearer');
102
- sendError(res, 401, 'authentication_error', key ? 'key_revoked' : 'invalid_api_key', key ? 'API key has been revoked' : 'Invalid API key');
162
+ const authenticated = this._authenticate(req, res, `${method} ${path}`);
163
+ if (!authenticated)
103
164
  return;
104
- }
105
- if (key.expiresAt !== null && key.expiresAt <= Date.now()) {
106
- res.setHeader('www-authenticate', 'Bearer');
107
- sendError(res, 401, 'authentication_error', 'key_expired', 'API key has expired');
108
- return;
109
- }
165
+ const { key, context } = authenticated;
110
166
  if (route.local) {
111
167
  if (route.prefix === TOPUP_PATH)
112
168
  await this._topup(req, res, key);
@@ -114,112 +170,324 @@ export class GatewayServer {
114
170
  sendJson(res, 200, { data: await this._keyInfo(key) });
115
171
  return;
116
172
  }
117
- const buyerPort = this._options.buyerPort;
118
173
  // Caps are only as good as the spend that reaches the ledger, so a key
119
174
  // with caps fails closed while its buyer is not reporting spend.
120
- if (route.paid && hasSpendLimits(key.limits) && this._options.spendFeedState() !== 'reporting') {
121
- await this._options.refreshSpendFeed();
122
- const state = this._options.spendFeedState();
123
- if (state !== 'reporting') {
124
- sendError(res, 503, 'api_error', 'spend_tracking_unavailable', state === 'unsupported'
125
- ? 'The buyer for this API key does not report spend; upgrade it to enforce spend limits'
126
- : 'The buyer for this API key is not reachable');
127
- return;
128
- }
129
- }
130
- const body = await readBody(req);
175
+ if (route.paid && this._options.accounting.hasBudgets(key, context) && !await this._spendFeedReporting(res))
176
+ return;
177
+ let body = await readBody(req);
131
178
  if (!body)
132
179
  return sendBodyTooLarge(res);
133
- let tag;
134
- if (route.paid) {
135
- const admission = this._options.accounting.admit(key);
136
- if (!admission.ok) {
137
- this._log(`gateway spend limit reached: key=${key.id} period=${admission.breach.period}`);
138
- sendJson(res, 402, { error: spendLimitError(admission.breach) });
180
+ const contentType = req.headers['content-type'];
181
+ let parsed = parseJsonBody(body, contentType);
182
+ // What the buyer routes by (`service ?? model`), so the allow list and
183
+ // the request log see the model that is actually bought.
184
+ let model = effectiveRequestModel(parsed, body, contentType);
185
+ // `model: "@preset/<slug>"` runs the workspace's (or org's) preset.
186
+ const slug = presetSlug(model);
187
+ const preset = slug ? this._options.store.findPresetBySlug(slug, key.workspaceId) : null;
188
+ if (slug) {
189
+ if (!parsed) {
190
+ sendError(res, 400, 'invalid_request_error', 'preset_requires_json', 'Presets can only be used with JSON request bodies');
139
191
  return;
140
192
  }
141
- tag = admission.tag;
142
- }
143
- else {
144
- tag = newRequestTag();
193
+ if (!preset) {
194
+ sendError(res, 400, 'invalid_request_error', 'preset_not_found', `No preset named "${slug}"`);
195
+ return;
196
+ }
197
+ parsed = applyPreset(parsed, preset, route.prefix);
198
+ body = Buffer.from(JSON.stringify(parsed), 'utf8');
199
+ model = preset.model;
145
200
  }
146
- this._options.store.startRequest({
201
+ const policy = this._routingPolicy(res, route, key, context, preset, model);
202
+ if (!policy.allowed)
203
+ return;
204
+ const tag = this._admit(res, route, key, context);
205
+ if (!tag)
206
+ return;
207
+ const request = {
147
208
  tag,
148
- keyId: key.id,
149
- buyerIdentity: key.buyerIdentity,
209
+ key,
150
210
  method,
151
- path: canonicalPath.split('?')[0],
152
- model: sniffModel(body, req.headers['content-type']),
211
+ path,
212
+ buyerPath: route.path,
213
+ requestPath: route.prefix,
214
+ model: model ? model.slice(0, 200) : null,
215
+ endUser: extractEndUser(parsed, firstHeader(req.headers[END_USER_HEADER]) || undefined),
153
216
  startedAt: Date.now(),
154
- });
155
- this._options.store.touchKey(key.id);
156
- this._log(`gateway request: key=${key.id} identity=${key.buyerIdentity} ${method} ${path} -> ${canonicalPath}`);
157
- let finished = false;
158
- const finish = (status, buyerRequestId) => {
159
- if (finished)
160
- return;
161
- finished = true;
162
- this._options.store.finishRequest(tag, { status, buyerRequestId });
163
- this._options.accounting.finish(tag);
217
+ body,
218
+ policyHeaders: policy.headers,
219
+ modelListPolicy: route.prefix === '/v1/models' && policy.policy.allowedModels ? policy.policy : null,
164
220
  };
165
- const headers = {};
166
- for (const [name, value] of Object.entries(req.headers)) {
167
- const normalized = name.toLowerCase();
168
- // The client's key authenticated it to this gateway; its other
169
- // credentials are never needed downstream (see credential-headers.ts).
170
- if (normalized === 'host' || isClientCredentialHeader(normalized))
171
- continue;
172
- // The key decides who pays and how spend is tagged, never the client.
173
- if (normalized === 'content-length' || normalized === SPEND_ATTRIBUTION_HEADER || normalized === BUYER_IDENTITY_HEADER)
174
- continue;
175
- if (normalized.startsWith('x-forwarded-') || HOP_BY_HOP.has(normalized))
176
- continue;
177
- headers[name] = value;
221
+ try {
222
+ this._options.store.startRequest({
223
+ tag,
224
+ keyId: key.id,
225
+ buyerIdentity: key.buyerIdentity,
226
+ method,
227
+ path: request.requestPath,
228
+ model: request.model,
229
+ startedAt: request.startedAt,
230
+ workspaceId: key.workspaceId,
231
+ memberId: key.ownerMemberId,
232
+ endUser: request.endUser,
233
+ });
234
+ this._options.store.touchKey(key.id);
178
235
  }
179
- headers.host = `127.0.0.1:${buyerPort}`;
180
- headers.connection = 'close';
181
- headers['content-length'] = String(body.length);
182
- headers['x-antseed-system-proxy-source'] = tunnelRequestSource(req.headers);
183
- headers[SPEND_ATTRIBUTION_HEADER] = tag;
184
- if (key.buyerIdentity !== DEFAULT_BUYER_IDENTITY)
185
- headers[BUYER_IDENTITY_HEADER] = key.buyerIdentity;
186
- const upstream = http.request({
187
- hostname: '127.0.0.1',
188
- port: buyerPort,
189
- method,
190
- path: canonicalPath,
191
- headers,
192
- }, (upstreamRes) => {
193
- const status = upstreamRes.statusCode ?? 502;
194
- const buyerRequestId = firstHeader(upstreamRes.headers['x-antseed-request-id']) || null;
195
- const responseHeaders = {};
196
- for (const [name, value] of Object.entries(upstreamRes.headers)) {
197
- if (!HOP_BY_HOP.has(name.toLowerCase()) && value !== undefined)
198
- responseHeaders[name] = value;
199
- }
200
- responseHeaders.connection = 'close';
201
- res.writeHead(status, responseHeaders);
202
- upstreamRes.pipe(res);
203
- upstreamRes.once('end', () => finish(status, buyerRequestId));
204
- upstreamRes.once('error', () => finish(status, buyerRequestId));
205
- res.once('close', () => finish(status, buyerRequestId));
206
- });
207
- upstream.on('error', (error) => {
208
- this._log(`gateway upstream error: ${error.message}`);
209
- finish(502, null);
210
- if (!res.headersSent) {
211
- sendError(res, 502, 'api_error', 'buyer_unavailable', 'Antseed buyer proxy is unavailable');
236
+ catch (error) {
237
+ // Nothing was sent; the hold must not keep counting against the caps.
238
+ this._options.accounting.release(tag);
239
+ throw error;
240
+ }
241
+ this._forward(req, res, request);
242
+ }
243
+ /** The request's active API key and who it is accounted to; answers 401 itself otherwise. */
244
+ _authenticate(req, res, requestLine) {
245
+ const store = this._options.store;
246
+ const key = this._requestKey(req);
247
+ if (!key || key.status !== 'active') {
248
+ this._log(`gateway rejected authentication: ${requestLine}`);
249
+ if (key)
250
+ sendUnauthorized(res, 'key_revoked', 'API key has been revoked');
251
+ else
252
+ sendUnauthorized(res, 'invalid_api_key', 'Invalid API key');
253
+ return null;
254
+ }
255
+ if (key.expiresAt !== null && key.expiresAt <= Date.now()) {
256
+ sendUnauthorized(res, 'key_expired', 'API key has expired');
257
+ return null;
258
+ }
259
+ // Loaded once and shared by policy resolution and budget admission.
260
+ const member = key.ownerMemberId ? store.getMember(key.ownerMemberId) : null;
261
+ if (member?.status === 'disabled') {
262
+ sendUnauthorized(res, 'key_revoked', 'API key has been revoked');
263
+ return null;
264
+ }
265
+ return { key, context: { member, workspace: store.getWorkspace(key.workspaceId) } };
266
+ }
267
+ /**
268
+ * The key a request names: by id for the gateway's own components (see
269
+ * GATEWAY_INTERNAL_KEY_HEADER), else by its Bearer secret. The id header is
270
+ * only honored from an internal caller; from anyone else it is ignored, so
271
+ * it can neither stand in for a key nor block a valid Bearer one.
272
+ */
273
+ _requestKey(req) {
274
+ const internalKeyId = firstHeader(req.headers[GATEWAY_INTERNAL_KEY_HEADER]);
275
+ if (internalKeyId && this._internalCaller(req))
276
+ return this._options.store.getKey(internalKeyId);
277
+ const secret = parseBearerToken(req.headers.authorization);
278
+ return secret ? this._options.store.findKeyBySecret(secret) : null;
279
+ }
280
+ /** A request from the gateway process itself: loopback, carrying the control secret. */
281
+ _internalCaller(req) {
282
+ const expected = this._options.controlSecret;
283
+ const sent = firstHeader(req.headers[GATEWAY_CONTROL_HEADER]);
284
+ if (!expected || !sent || !isLoopback(req.socket.remoteAddress))
285
+ return false;
286
+ const a = Buffer.from(sent);
287
+ const b = Buffer.from(expected);
288
+ return a.length === b.length && timingSafeEqual(a, b);
289
+ }
290
+ /** Whether the buyer reports spend, refreshing the feed once; answers 503 itself when it does not. */
291
+ async _spendFeedReporting(res) {
292
+ if (this._options.spendFeedState() === 'reporting')
293
+ return true;
294
+ await this._options.refreshSpendFeed();
295
+ const state = this._options.spendFeedState();
296
+ if (state === 'reporting')
297
+ return true;
298
+ sendError(res, 503, 'api_error', 'spend_tracking_unavailable', SPEND_FEED_UNAVAILABLE_MESSAGES[state]);
299
+ return false;
300
+ }
301
+ /**
302
+ * The key's effective routing policy: refuses (answering itself) a model
303
+ * it does not allow, or a seller restriction the buyer would not apply.
304
+ * Settings that change nothing (the default sort, flags set to false) are
305
+ * not sent: a request without restrictions reaches the buyer exactly like
306
+ * one through a gateway without policies.
307
+ */
308
+ _routingPolicy(res, route, key, context, preset, model) {
309
+ const { policy } = resolvePolicy(this._options.store, { key, preset, member: context.member, workspace: context.workspace });
310
+ if ((route.paid || model) && !policyAllowsModel(policy, model)) {
311
+ sendError(res, 403, 'permission_error', 'model_not_allowed', model
312
+ ? `Model "${model}" is not allowed for this API key`
313
+ : 'This API key may only use specific models; name one in the request');
314
+ return { allowed: false };
315
+ }
316
+ const routed = meaningfulPolicy(policy);
317
+ if (isEmptyPolicy(routed))
318
+ return { allowed: true, headers: {}, policy };
319
+ const controlSecret = this._options.controlSecret ?? null;
320
+ const sellersRestricted = restrictsSellers(routed);
321
+ if (!controlSecret && sellersRestricted) {
322
+ sendError(res, 503, 'api_error', 'routing_policy_unavailable', 'This API key has a routing policy the gateway cannot pass to the buyer');
323
+ return { allowed: false };
324
+ }
325
+ if (route.paid && sellersRestricted && this._options.buyerPolicyUnsupported?.()) {
326
+ sendError(res, 503, 'api_error', 'buyer_policy_unsupported', "The buyer does not apply this API key's routing policy; upgrade it or check the gateway control secret");
327
+ return { allowed: false };
328
+ }
329
+ if (!controlSecret)
330
+ return { allowed: true, headers: {}, policy };
331
+ return { allowed: true, headers: { [ROUTING_POLICY_HEADER]: encodePolicyHeader(routed), [GATEWAY_CONTROL_HEADER]: controlSecret }, policy };
332
+ }
333
+ /** The request's tag; a paid request is admitted against its budgets first (402 answered here when one is spent). */
334
+ _admit(res, route, key, context) {
335
+ if (!route.paid)
336
+ return newRequestTag();
337
+ const admission = this._options.accounting.admit(key, context);
338
+ if (admission.ok)
339
+ return admission.tag;
340
+ this._log(`gateway spend limit reached: key=${key.id} level=${admission.breach.level ?? 'key'} period=${admission.breach.period}`);
341
+ sendJson(res, 402, { error: spendLimitError(admission.breach) });
342
+ return null;
343
+ }
344
+ /**
345
+ * Sends an admitted request to the buyer and streams the answer back.
346
+ * Every path must finish the request (and so release or start expiring
347
+ * its hold); an unexpected throw must not leak it.
348
+ */
349
+ _forward(req, res, request) {
350
+ const { tag, key, method, startedAt, endUser, body } = request;
351
+ const buyerPort = this._options.buyerPort;
352
+ let finish = null;
353
+ let sentToBuyer = false;
354
+ try {
355
+ this._log(`gateway request: key=${key.id} identity=${key.buyerIdentity} ${method} ${request.path} -> ${request.buyerPath}`);
356
+ const observability = observabilitySettings(this._options.store);
357
+ const requestContent = observability.logContent ? truncateContent(body) : null;
358
+ let responseChunks = [];
359
+ // The start of a failed response, read whatever the content setting, for its error code and message.
360
+ let errorChunks = [];
361
+ let gatewayError = null;
362
+ let sellerPeerId = null;
363
+ let reportedLatency = null;
364
+ let servedFree = false;
365
+ // Token counts the response reports, kept on the request until (or if
366
+ // the buyer never reports) its spend.
367
+ let usageReader = null;
368
+ let finished = false;
369
+ finish = (status, buyerRequestId) => {
370
+ if (finished)
371
+ return;
372
+ finished = true;
373
+ const finishedAt = Date.now();
374
+ const latencyMs = reportedLatency ?? finishedAt - startedAt;
375
+ const responseContent = observability.logContent ? truncateContent(Buffer.concat(responseChunks)) : null;
376
+ const store = this._options.store;
377
+ try {
378
+ const error = status >= 400 ? gatewayError ?? parseErrorBody(Buffer.concat(errorChunks), status) : null;
379
+ store.finishRequest(tag, { status, buyerRequestId, error });
380
+ store.recordRequestOutcome(tag, { sellerPeerId, latencyMs, endUser, servedFree });
381
+ const usage = usageReader?.result() ?? null;
382
+ if (usage)
383
+ store.recordResponseUsage(tag, usage);
384
+ if (observability.logContent)
385
+ store.recordRequestContent(tag, { requestBody: requestContent, responseBody: responseContent });
386
+ }
387
+ catch (error) {
388
+ this._log(`gateway could not record request ${tag}: ${errorMessage(error)}`);
389
+ }
390
+ this._options.accounting.finish(tag);
391
+ this._exporter.record({
392
+ tag, method, path: request.requestPath, model: request.model, status, startedAt, finishedAt,
393
+ keyId: key.id, workspaceId: key.workspaceId, memberId: key.ownerMemberId, endUser, sellerPeerId, latencyMs,
394
+ ...(observability.logContent ? { requestBody: requestContent, responseBody: responseContent } : {}),
395
+ });
396
+ };
397
+ const headers = { ...forwardedHeaders(req.headers), ...request.policyHeaders };
398
+ headers.host = `127.0.0.1:${buyerPort}`;
399
+ headers.connection = 'close';
400
+ headers['content-length'] = String(body.length);
401
+ headers['x-antseed-system-proxy-source'] = tunnelRequestSource(req.headers);
402
+ headers[SPEND_ATTRIBUTION_HEADER] = tag;
403
+ if (key.buyerIdentity !== DEFAULT_BUYER_IDENTITY) {
404
+ headers[BUYER_IDENTITY_HEADER] = key.buyerIdentity;
405
+ // The buyer lets only its gateway pay from a non-default wallet.
406
+ const controlSecret = this._options.controlSecret;
407
+ if (controlSecret)
408
+ headers[GATEWAY_CONTROL_HEADER] = controlSecret;
212
409
  }
410
+ const upstream = http.request({
411
+ hostname: '127.0.0.1',
412
+ port: buyerPort,
413
+ method,
414
+ path: request.buyerPath,
415
+ headers,
416
+ }, (upstreamRes) => {
417
+ const status = upstreamRes.statusCode ?? 502;
418
+ const buyerRequestId = firstHeader(upstreamRes.headers['x-antseed-request-id']) || null;
419
+ sellerPeerId = firstHeader(upstreamRes.headers['x-antseed-peer-id']).slice(0, 200) || null;
420
+ reportedLatency = latencyHeader(firstHeader(upstreamRes.headers['x-antseed-latency-ms']));
421
+ servedFree = freeSellerPricing(upstreamRes.headers);
422
+ if (observability.logContent)
423
+ responseChunks = collectPrefix(upstreamRes, MAX_LOGGED_CONTENT_BYTES);
424
+ if (status >= 400)
425
+ errorChunks = collectPrefix(upstreamRes, MAX_ERROR_BODY_BYTES);
426
+ else if (request.model !== null)
427
+ usageReader = readUsage(upstreamRes, (message) => this._log(message));
428
+ const responseHeaders = {};
429
+ for (const [name, value] of Object.entries(upstreamRes.headers)) {
430
+ if (!HOP_BY_HOP.has(name.toLowerCase()) && value !== undefined)
431
+ responseHeaders[name] = value;
432
+ }
433
+ responseHeaders.connection = 'close';
434
+ upstreamRes.once('error', () => finish(status, buyerRequestId));
435
+ res.once('close', () => finish(status, buyerRequestId));
436
+ const modelListPolicy = request.modelListPolicy;
437
+ if (modelListPolicy && status === 200) {
438
+ const chunks = [];
439
+ upstreamRes.on('data', (chunk) => chunks.push(chunk));
440
+ upstreamRes.once('end', () => {
441
+ const listing = filterModelList(Buffer.concat(chunks), modelListPolicy);
442
+ res.writeHead(status, { ...responseHeaders, 'content-length': String(listing.length) });
443
+ res.end(listing);
444
+ finish(status, buyerRequestId);
445
+ });
446
+ return;
447
+ }
448
+ res.writeHead(status, responseHeaders);
449
+ upstreamRes.pipe(res);
450
+ upstreamRes.once('end', () => finish(status, buyerRequestId));
451
+ });
452
+ upstream.on('error', (error) => {
453
+ this._log(`gateway upstream error: ${error.message}`);
454
+ gatewayError = { code: 'buyer_unavailable', message: 'Antseed buyer proxy is unavailable' };
455
+ finish(502, null);
456
+ if (!res.headersSent) {
457
+ sendError(res, 502, 'api_error', 'buyer_unavailable', 'Antseed buyer proxy is unavailable');
458
+ }
459
+ else {
460
+ res.destroy();
461
+ }
462
+ });
463
+ // A client that disconnects mid-stream should stop the paid request too.
464
+ res.once('close', () => {
465
+ if (!res.writableFinished)
466
+ upstream.destroy();
467
+ });
468
+ sentToBuyer = true;
469
+ upstream.end(body);
470
+ }
471
+ catch (error) {
472
+ this._log(`gateway error after admission: ${errorMessage(error)}`);
473
+ if (finish)
474
+ finish(500, null);
213
475
  else {
214
- res.destroy();
476
+ try {
477
+ this._options.store.finishRequest(tag, { status: 500, buyerRequestId: null, error: { code: 'internal_error', message: 'Gateway error' } });
478
+ }
479
+ catch {
480
+ // Already logged above; the hold still goes.
481
+ }
215
482
  }
216
- });
217
- // A client that disconnects mid-stream should stop the paid request too.
218
- res.once('close', () => {
219
- if (!res.writableFinished)
220
- upstream.destroy();
221
- });
222
- upstream.end(body);
483
+ // A request the buyer never saw cannot be signed for: drop its hold now.
484
+ if (!sentToBuyer)
485
+ this._options.accounting.release(tag);
486
+ if (!res.headersSent)
487
+ sendError(res, 500, 'api_error', 'internal_error', 'Gateway error');
488
+ else
489
+ res.destroy();
490
+ }
223
491
  }
224
492
  /**
225
493
  * x402 top-up: the key holder pays USDC straight to the key's buyer wallet.
@@ -311,7 +579,7 @@ export class GatewayServer {
311
579
  });
312
580
  }
313
581
  catch (error) {
314
- this._log(`gateway top-up settled but NOT recorded in the ledger: key=${key.id} amount=${formatUsdc(amountUsdc)} tx=${settled.transaction}: ${error instanceof Error ? error.message : String(error)}`);
582
+ this._log(`gateway top-up settled but NOT recorded in the ledger: key=${key.id} amount=${formatUsdc(amountUsdc)} tx=${settled.transaction}: ${errorMessage(error)}`);
315
583
  }
316
584
  this._log(`gateway top-up: key=${key.id} identity=${key.buyerIdentity} amount=${formatUsdc(amountUsdc)} tx=${settled.transaction}`);
317
585
  res.setHeader(PAYMENT_RESPONSE_HEADER, encodeHeaderJson(settled));
@@ -338,16 +606,18 @@ export class GatewayServer {
338
606
  return await topup.facilitator.settle(payment, requirements);
339
607
  }
340
608
  catch (error) {
341
- this._log(`gateway facilitator error: ${error instanceof Error ? error.message : String(error)}`);
609
+ this._log(`gateway facilitator error: ${errorMessage(error)}`);
342
610
  return failure('unexpected_settle_error');
343
611
  }
344
612
  }
345
613
  async _keyInfo(key) {
346
- const spent = this._options.store.periodSpend(key.id);
614
+ const spent = this._options.store.spendByPeriod({ keyId: key.id });
347
615
  const usage = this._options.store.usageStats(key.id);
348
616
  const buyerAddress = await this._options.identityAddress(key.buyerIdentity).catch(() => null);
349
- const limits = Object.fromEntries(LIMIT_PERIODS.map((period) => {
350
- const limit = key.limits[period];
617
+ // The caps admission enforces: the lower of the admins' and the owner's.
618
+ const caps = effectiveKeyLimits(key);
619
+ const limits = Object.fromEntries(BUDGET_PERIODS.map((period) => {
620
+ const limit = caps[period];
351
621
  return [period, {
352
622
  limit_usd: optionalUsdcToDecimalString(limit),
353
623
  spent_usd: usdcToDecimalString(spent[period]),
@@ -381,11 +651,13 @@ export class GatewayServer {
381
651
  */
382
652
  function spendLimitError(breach) {
383
653
  const label = breach.period === 'total' ? 'lifetime' : breach.period;
654
+ const level = breach.level ?? 'key';
384
655
  return {
385
656
  type: 'insufficient_quota',
386
657
  code: 'spend_limit_reached',
387
- message: `This API key reached its ${label} spend limit of ${formatUsdc(breach.limitUsdc)}.`,
658
+ message: `${budgetHolder(level)} reached its ${label} spend limit of ${formatUsdc(breach.limitUsdc)}.`,
388
659
  limit: {
660
+ level,
389
661
  period: breach.period,
390
662
  limit_usd: usdcToDecimalString(breach.limitUsdc),
391
663
  spent_usd: usdcToDecimalString(breach.spentUsdc),
@@ -393,6 +665,13 @@ function spendLimitError(breach) {
393
665
  },
394
666
  };
395
667
  }
668
+ function budgetHolder(level) {
669
+ if (level === 'key')
670
+ return 'This API key';
671
+ if (level === 'member')
672
+ return 'The member who owns this API key';
673
+ return 'This API key\'s workspace';
674
+ }
396
675
  function sendJson(res, status, payload) {
397
676
  res.writeHead(status, { 'content-type': 'application/json' });
398
677
  res.end(JSON.stringify(payload));
@@ -400,6 +679,10 @@ function sendJson(res, status, payload) {
400
679
  function sendError(res, status, type, code, message) {
401
680
  sendJson(res, status, { error: { message, type, code } });
402
681
  }
682
+ function sendUnauthorized(res, code, message) {
683
+ res.setHeader('www-authenticate', 'Bearer');
684
+ sendError(res, 401, 'authentication_error', code, message);
685
+ }
403
686
  /** The request body, or null once it exceeds MAX_BODY_BYTES (the rest is drained, not kept). */
404
687
  async function readBody(req) {
405
688
  if (Number(req.headers['content-length']) > MAX_BODY_BYTES) {
@@ -418,19 +701,132 @@ async function readBody(req) {
418
701
  function sendBodyTooLarge(res) {
419
702
  sendError(res, 413, 'invalid_request_error', 'request_too_large', `Request bodies are limited to ${MAX_BODY_BYTES / 1024 / 1024} MiB`);
420
703
  }
421
- function sniffModel(body, contentType) {
704
+ /** A JSON object body, or null (empty, too large to inspect, not JSON, not an object). */
705
+ function parseJsonBody(body, contentType) {
422
706
  if (body.length === 0 || body.length > MAX_MODEL_SNIFF_BYTES)
423
707
  return null;
424
708
  if (contentType && !contentType.includes('json'))
425
709
  return null;
426
710
  try {
427
- const parsed = JSON.parse(body.toString('utf8'));
428
- return typeof parsed.model === 'string' ? parsed.model.slice(0, 200) : null;
711
+ return jsonObject(JSON.parse(body.toString('utf8')));
429
712
  }
430
713
  catch {
431
714
  return null;
432
715
  }
433
716
  }
717
+ function jsonObject(value) {
718
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
719
+ }
720
+ /**
721
+ * Error code and message of a failed response: the OpenAI/Anthropic envelope
722
+ * (`{ error: { code | type, message } }`, `{ error: "…" }`), a top-level
723
+ * `{ code, message }`, or the start of a non-JSON body.
724
+ */
725
+ export function parseErrorBody(body, status) {
726
+ const text = body.subarray(0, MAX_ERROR_BODY_BYTES).toString('utf8').trim();
727
+ const fallback = `http_${status}`;
728
+ const clip = (value) => value ? value.slice(0, MAX_ERROR_MESSAGE_CHARS) : null;
729
+ let parsed;
730
+ try {
731
+ parsed = JSON.parse(text);
732
+ }
733
+ catch {
734
+ return { code: fallback, message: clip(text.replace(/\s+/g, ' ')) };
735
+ }
736
+ const pick = (value) => typeof value === 'string' && value.trim() ? value.trim() : null;
737
+ const root = jsonObject(parsed) ?? {};
738
+ const envelope = root['error'];
739
+ if (typeof envelope === 'string')
740
+ return { code: pick(root['code']) ?? fallback, message: clip(envelope) };
741
+ const inner = jsonObject(envelope) ?? root;
742
+ return {
743
+ code: (pick(inner['code']) ?? pick(inner['type']) ?? fallback).slice(0, 100),
744
+ message: clip(pick(inner['message']) ?? pick(root['message']) ?? pick(root['detail'])),
745
+ };
746
+ }
747
+ /** Keeps the first `maxBytes` (or so) of a stream as it flows past. */
748
+ function collectPrefix(stream, maxBytes) {
749
+ const chunks = [];
750
+ let bytes = 0;
751
+ stream.on('data', (chunk) => {
752
+ if (bytes >= maxBytes)
753
+ return;
754
+ chunks.push(chunk);
755
+ bytes += chunk.length;
756
+ });
757
+ return chunks;
758
+ }
759
+ /** Feeds a successful model response to a usage reader as it streams; a reader error only stops reading. */
760
+ function readUsage(stream, log) {
761
+ const reader = new ResponseUsageReader(firstHeader(stream.headers['content-type']));
762
+ const onData = (chunk) => {
763
+ try {
764
+ reader.push(chunk);
765
+ }
766
+ catch (error) {
767
+ stream.off('data', onData);
768
+ log(`gateway could not read response usage: ${errorMessage(error)}`);
769
+ }
770
+ };
771
+ stream.on('data', onData);
772
+ return reader;
773
+ }
774
+ /** The buyer's own latency measurement, when it sent a usable one. */
775
+ /**
776
+ * Whether the seller's advertised prices (the buyer's pricing headers) are
777
+ * all zero: a free seller, for which the buyer never reports spend. Unknown
778
+ * input or output prices are not free.
779
+ */
780
+ function freeSellerPricing(headers) {
781
+ const price = (name) => {
782
+ const value = firstHeader(headers[name]);
783
+ const amount = Number(value);
784
+ return value && Number.isFinite(amount) ? amount : null;
785
+ };
786
+ const cached = price('x-antseed-cached-input-usd-per-million');
787
+ return price('x-antseed-input-usd-per-million') === 0 && price('x-antseed-output-usd-per-million') === 0 && (cached === null || cached === 0);
788
+ }
789
+ function latencyHeader(value) {
790
+ const latency = Number(value);
791
+ return value && Number.isFinite(latency) && latency >= 0 ? Math.floor(latency) : null;
792
+ }
793
+ /**
794
+ * Client headers never forwarded: the gateway sets its own `host` and
795
+ * `content-length`, and the key (never the client) decides who pays, how
796
+ * spend is tagged and which sellers may serve.
797
+ */
798
+ const STRIPPED_HEADERS = new Set([
799
+ 'host',
800
+ 'content-length',
801
+ SPEND_ATTRIBUTION_HEADER,
802
+ BUYER_IDENTITY_HEADER,
803
+ ROUTING_POLICY_HEADER,
804
+ GATEWAY_CONTROL_HEADER,
805
+ GATEWAY_INTERNAL_KEY_HEADER,
806
+ END_USER_HEADER,
807
+ ]);
808
+ /** Client headers passed on to the buyer, minus everything the key (not the client) decides. */
809
+ function forwardedHeaders(incoming) {
810
+ const headers = {};
811
+ for (const [name, value] of Object.entries(incoming)) {
812
+ const normalized = name.toLowerCase();
813
+ // The client's key authenticated it to this gateway; its other
814
+ // credentials are never needed downstream (see credential-headers.ts).
815
+ if (isClientCredentialHeader(normalized) || STRIPPED_HEADERS.has(normalized))
816
+ continue;
817
+ if (normalized.startsWith('x-forwarded-') || HOP_BY_HOP.has(normalized))
818
+ continue;
819
+ headers[name] = value;
820
+ }
821
+ return headers;
822
+ }
823
+ function truncateContent(body) {
824
+ return body.subarray(0, MAX_LOGGED_CONTENT_BYTES).toString('utf8');
825
+ }
826
+ /** Whether a policy says anything the buyer must apply (the gateway enforces `allowedModels` itself). */
827
+ function restrictsSellers(policy) {
828
+ return Object.keys(policy).some((field) => field !== 'allowedModels' && field !== 'sort' && field !== 'preferFreePeers');
829
+ }
434
830
  function tunnelRequestSource(headers) {
435
831
  const originator = normalizeSource(firstHeader(headers.originator));
436
832
  if (originator)
@@ -442,12 +838,32 @@ function tunnelRequestSource(headers) {
442
838
  const product = normalizeSource(userAgent.split(/[/\s]/, 1)[0] ?? '');
443
839
  return product.startsWith('cursor') ? 'cursor' : 'public-tunnel';
444
840
  }
841
+ function isLoopback(address) {
842
+ return address === '127.0.0.1' || address === '::1' || address === '::ffff:127.0.0.1';
843
+ }
445
844
  function firstHeader(value) {
446
845
  return Array.isArray(value) ? value[0] ?? '' : value ?? '';
447
846
  }
448
847
  function normalizeSource(value) {
449
848
  return value.trim().toLowerCase().replace(/[^a-z0-9.]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 64);
450
849
  }
850
+ /** A `/v1/models` listing without the models the policy does not allow (matched by id or alias). */
851
+ function filterModelList(body, policy) {
852
+ let listing;
853
+ try {
854
+ listing = JSON.parse(body.toString('utf8'));
855
+ }
856
+ catch {
857
+ return body;
858
+ }
859
+ if (!listing || !Array.isArray(listing.data))
860
+ return body;
861
+ listing.data = listing.data.filter((entry) => {
862
+ const names = [entry?.id, ...(Array.isArray(entry?.aliases) ? entry.aliases : [])];
863
+ return names.some((name) => typeof name === 'string' && policyAllowsModel(policy, name));
864
+ });
865
+ return Buffer.from(JSON.stringify(listing), 'utf8');
866
+ }
451
867
  function canonicalizeRoute(method, path) {
452
868
  const queryIndex = path.indexOf('?');
453
869
  const pathname = (queryIndex === -1 ? path : path.slice(0, queryIndex)).toLowerCase();