mppx 0.8.14 → 0.8.17

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 (507) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/Challenge.d.ts.map +1 -1
  3. package/dist/Challenge.js +40 -35
  4. package/dist/Challenge.js.map +1 -1
  5. package/dist/Constants.d.ts +17 -17
  6. package/dist/Constants.d.ts.map +1 -1
  7. package/dist/Credential.d.ts.map +1 -1
  8. package/dist/Errors.d.ts +3 -3
  9. package/dist/Errors.d.ts.map +1 -1
  10. package/dist/Errors.js.map +1 -1
  11. package/dist/Method.d.ts +35 -5
  12. package/dist/Method.d.ts.map +1 -1
  13. package/dist/Method.js +7 -22
  14. package/dist/Method.js.map +1 -1
  15. package/dist/Store.d.ts +19 -0
  16. package/dist/Store.d.ts.map +1 -1
  17. package/dist/Store.js +43 -0
  18. package/dist/Store.js.map +1 -1
  19. package/dist/attestation/Client.d.ts +17 -0
  20. package/dist/attestation/Client.d.ts.map +1 -0
  21. package/dist/attestation/Client.js +28 -0
  22. package/dist/attestation/Client.js.map +1 -0
  23. package/dist/attestation/Constants.d.ts +15 -0
  24. package/dist/attestation/Constants.d.ts.map +1 -0
  25. package/dist/attestation/Constants.js +15 -0
  26. package/dist/attestation/Constants.js.map +1 -0
  27. package/dist/attestation/Server.d.ts +4 -0
  28. package/dist/attestation/Server.d.ts.map +1 -0
  29. package/dist/attestation/Server.js +8 -0
  30. package/dist/attestation/Server.js.map +1 -0
  31. package/dist/attestation/Types.d.ts +76 -0
  32. package/dist/attestation/Types.d.ts.map +1 -0
  33. package/dist/attestation/Types.js +2 -0
  34. package/dist/attestation/Types.js.map +1 -0
  35. package/dist/attestation/index.d.ts +6 -0
  36. package/dist/attestation/index.d.ts.map +1 -0
  37. package/dist/attestation/index.js +6 -0
  38. package/dist/attestation/index.js.map +1 -0
  39. package/dist/attestation/internal/HttpMessageSignature.d.ts +73 -0
  40. package/dist/attestation/internal/HttpMessageSignature.d.ts.map +1 -0
  41. package/dist/attestation/internal/HttpMessageSignature.js +320 -0
  42. package/dist/attestation/internal/HttpMessageSignature.js.map +1 -0
  43. package/dist/attestation/internal/SigningContext.d.ts +4 -0
  44. package/dist/attestation/internal/SigningContext.d.ts.map +1 -0
  45. package/dist/attestation/internal/SigningContext.js +11 -0
  46. package/dist/attestation/internal/SigningContext.js.map +1 -0
  47. package/dist/cli/account.d.ts +14 -14
  48. package/dist/cli/account.d.ts.map +1 -1
  49. package/dist/cli/cli.d.ts +6 -6
  50. package/dist/cli/cli.d.ts.map +1 -1
  51. package/dist/cli/cli.js +1 -0
  52. package/dist/cli/cli.js.map +1 -1
  53. package/dist/cli/plugins/tempo.js.map +1 -1
  54. package/dist/cli/sessions/commands.d.ts +4 -4
  55. package/dist/cli/sessions/commands.d.ts.map +1 -1
  56. package/dist/cli/sessions/commands.js.map +1 -1
  57. package/dist/cli/sessions/store.d.ts.map +1 -1
  58. package/dist/cli/sessions/store.js.map +1 -1
  59. package/dist/cli/utils.d.ts +1 -1
  60. package/dist/cli/utils.d.ts.map +1 -1
  61. package/dist/cli/utils.js.map +1 -1
  62. package/dist/cli/validate/discovery.js.map +1 -1
  63. package/dist/cli/validate/index.d.ts +3 -3
  64. package/dist/cli/validate/index.d.ts.map +1 -1
  65. package/dist/cli/validate/payment.d.ts.map +1 -1
  66. package/dist/cli/validate/payment.js +18 -4
  67. package/dist/cli/validate/payment.js.map +1 -1
  68. package/dist/client/Mppx.d.ts +3 -0
  69. package/dist/client/Mppx.d.ts.map +1 -1
  70. package/dist/client/Mppx.js +13 -5
  71. package/dist/client/Mppx.js.map +1 -1
  72. package/dist/client/Transport.d.ts +3 -5
  73. package/dist/client/Transport.d.ts.map +1 -1
  74. package/dist/client/Transport.js +1 -17
  75. package/dist/client/Transport.js.map +1 -1
  76. package/dist/client/internal/Fetch.d.ts.map +1 -1
  77. package/dist/client/internal/Fetch.js +92 -13
  78. package/dist/client/internal/Fetch.js.map +1 -1
  79. package/dist/client/internal/MethodChallenge.d.ts +2 -0
  80. package/dist/client/internal/MethodChallenge.d.ts.map +1 -1
  81. package/dist/client/internal/MethodChallenge.js +4 -0
  82. package/dist/client/internal/MethodChallenge.js.map +1 -1
  83. package/dist/client/internal/MethodResponse.d.ts +15 -0
  84. package/dist/client/internal/MethodResponse.d.ts.map +1 -1
  85. package/dist/client/internal/MethodResponse.js +10 -0
  86. package/dist/client/internal/MethodResponse.js.map +1 -1
  87. package/dist/client/node.js.map +1 -1
  88. package/dist/discovery/OpenApi.d.ts +3 -5
  89. package/dist/discovery/OpenApi.d.ts.map +1 -1
  90. package/dist/discovery/OpenApi.js +13 -34
  91. package/dist/discovery/OpenApi.js.map +1 -1
  92. package/dist/discovery/internal/Metadata.d.ts +20 -0
  93. package/dist/discovery/internal/Metadata.d.ts.map +1 -0
  94. package/dist/discovery/internal/Metadata.js +36 -0
  95. package/dist/discovery/internal/Metadata.js.map +1 -0
  96. package/dist/evm/Methods.d.ts +11 -11
  97. package/dist/evm/Methods.d.ts.map +1 -1
  98. package/dist/evm/Types.d.ts +17 -17
  99. package/dist/evm/Types.d.ts.map +1 -1
  100. package/dist/evm/client/Charge.d.ts +11 -11
  101. package/dist/evm/client/Methods.d.ts +11 -11
  102. package/dist/evm/server/Charge.d.ts +1 -1
  103. package/dist/evm/server/Charge.d.ts.map +1 -1
  104. package/dist/evm/server/Charge.js +2 -0
  105. package/dist/evm/server/Charge.js.map +1 -1
  106. package/dist/evm/server/Methods.d.ts +11 -11
  107. package/dist/internal/HeaderCodec.d.ts +2 -2
  108. package/dist/internal/HeaderCodec.d.ts.map +1 -1
  109. package/dist/internal/types.d.ts +6 -0
  110. package/dist/internal/types.d.ts.map +1 -1
  111. package/dist/middlewares/elysia.js.map +1 -1
  112. package/dist/middlewares/express.js.map +1 -1
  113. package/dist/middlewares/hono.js.map +1 -1
  114. package/dist/middlewares/nextjs.js.map +1 -1
  115. package/dist/proxy/Proxy.d.ts +2 -0
  116. package/dist/proxy/Proxy.d.ts.map +1 -1
  117. package/dist/proxy/Proxy.js +117 -9
  118. package/dist/proxy/Proxy.js.map +1 -1
  119. package/dist/proxy/Service.d.ts +36 -1
  120. package/dist/proxy/Service.d.ts.map +1 -1
  121. package/dist/proxy/Service.js +9 -8
  122. package/dist/proxy/Service.js.map +1 -1
  123. package/dist/proxy/services/anthropic.d.ts.map +1 -1
  124. package/dist/proxy/services/anthropic.js +1 -0
  125. package/dist/proxy/services/anthropic.js.map +1 -1
  126. package/dist/proxy/services/openai.d.ts.map +1 -1
  127. package/dist/proxy/services/openai.js +1 -0
  128. package/dist/proxy/services/openai.js.map +1 -1
  129. package/dist/proxy/services/stripe.d.ts.map +1 -1
  130. package/dist/proxy/services/stripe.js +1 -0
  131. package/dist/proxy/services/stripe.js.map +1 -1
  132. package/dist/server/Mppx.d.ts +75 -13
  133. package/dist/server/Mppx.d.ts.map +1 -1
  134. package/dist/server/Mppx.js +201 -23
  135. package/dist/server/Mppx.js.map +1 -1
  136. package/dist/server/internal/html/config.d.ts +9 -9
  137. package/dist/server/internal/html/config.d.ts.map +1 -1
  138. package/dist/server/internal/html/constants.d.ts +17 -17
  139. package/dist/server/internal/html/constants.d.ts.map +1 -1
  140. package/dist/stripe/Methods.d.ts +10 -10
  141. package/dist/stripe/Methods.d.ts.map +1 -1
  142. package/dist/stripe/client/Charge.d.ts +10 -10
  143. package/dist/stripe/client/Methods.d.ts +10 -10
  144. package/dist/stripe/internal/constants.d.ts +1 -1
  145. package/dist/stripe/internal/constants.js +1 -1
  146. package/dist/stripe/internal/types.d.ts +1 -0
  147. package/dist/stripe/internal/types.d.ts.map +1 -1
  148. package/dist/stripe/server/Charge.d.ts +11 -11
  149. package/dist/stripe/server/Charge.d.ts.map +1 -1
  150. package/dist/stripe/server/Charge.js +49 -1
  151. package/dist/stripe/server/Charge.js.map +1 -1
  152. package/dist/stripe/server/Methods.d.ts +137 -48
  153. package/dist/stripe/server/Methods.d.ts.map +1 -1
  154. package/dist/stripe/server/Methods.js +259 -4
  155. package/dist/stripe/server/Methods.js.map +1 -1
  156. package/dist/stripe/server/internal/deposit-address.d.ts +13 -0
  157. package/dist/stripe/server/internal/deposit-address.d.ts.map +1 -0
  158. package/dist/stripe/server/internal/deposit-address.js +28 -0
  159. package/dist/stripe/server/internal/deposit-address.js.map +1 -0
  160. package/dist/stripe/server/internal/html.gen.d.ts +1 -1
  161. package/dist/stripe/server/internal/html.gen.d.ts.map +1 -1
  162. package/dist/stripe/server/internal/html.gen.js +1 -1
  163. package/dist/stripe/server/internal/html.gen.js.map +1 -1
  164. package/dist/stripe/server/internal/record-payment.d.ts +15 -0
  165. package/dist/stripe/server/internal/record-payment.d.ts.map +1 -0
  166. package/dist/stripe/server/internal/record-payment.js +42 -0
  167. package/dist/stripe/server/internal/record-payment.js.map +1 -0
  168. package/dist/stripe/server/internal/request.d.ts +25 -0
  169. package/dist/stripe/server/internal/request.d.ts.map +1 -0
  170. package/dist/stripe/server/internal/request.js +29 -0
  171. package/dist/stripe/server/internal/request.js.map +1 -0
  172. package/dist/tap/Constants.d.ts +28 -0
  173. package/dist/tap/Constants.d.ts.map +1 -0
  174. package/dist/tap/Constants.js +32 -0
  175. package/dist/tap/Constants.js.map +1 -0
  176. package/dist/tap/Types.d.ts +11 -0
  177. package/dist/tap/Types.d.ts.map +1 -0
  178. package/dist/tap/Types.js +2 -0
  179. package/dist/tap/Types.js.map +1 -0
  180. package/dist/tap/client/index.d.ts +26 -0
  181. package/dist/tap/client/index.d.ts.map +1 -0
  182. package/dist/tap/client/index.js +33 -0
  183. package/dist/tap/client/index.js.map +1 -0
  184. package/dist/tap/index.d.ts +5 -0
  185. package/dist/tap/index.d.ts.map +1 -0
  186. package/dist/tap/index.js +5 -0
  187. package/dist/tap/index.js.map +1 -0
  188. package/dist/tap/server/index.d.ts +20 -0
  189. package/dist/tap/server/index.d.ts.map +1 -0
  190. package/dist/tap/server/index.js +36 -0
  191. package/dist/tap/server/index.js.map +1 -0
  192. package/dist/tempo/Attribution.d.ts +1 -1
  193. package/dist/tempo/Methods.d.ts +60 -60
  194. package/dist/tempo/Methods.d.ts.map +1 -1
  195. package/dist/tempo/Proof.d.ts +16 -16
  196. package/dist/tempo/client/Charge.d.ts +19 -19
  197. package/dist/tempo/client/Charge.d.ts.map +1 -1
  198. package/dist/tempo/client/Charge.js +1 -7
  199. package/dist/tempo/client/Charge.js.map +1 -1
  200. package/dist/tempo/client/Methods.d.ts +38 -38
  201. package/dist/tempo/client/Methods.js.map +1 -1
  202. package/dist/tempo/client/Subscription.d.ts +23 -23
  203. package/dist/tempo/client/Subscription.js.map +1 -1
  204. package/dist/tempo/internal/address.d.ts +2 -1
  205. package/dist/tempo/internal/address.d.ts.map +1 -1
  206. package/dist/tempo/internal/address.js +3 -1
  207. package/dist/tempo/internal/address.js.map +1 -1
  208. package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
  209. package/dist/tempo/internal/auto-swap.js +4 -19
  210. package/dist/tempo/internal/auto-swap.js.map +1 -1
  211. package/dist/tempo/internal/defaults.d.ts +6 -6
  212. package/dist/tempo/internal/defaults.d.ts.map +1 -1
  213. package/dist/tempo/internal/fee-payer.d.ts +12 -12
  214. package/dist/tempo/internal/fee-payer.d.ts.map +1 -1
  215. package/dist/tempo/internal/fee-payer.js.map +1 -1
  216. package/dist/tempo/internal/proof.d.ts +17 -17
  217. package/dist/tempo/internal/proof.d.ts.map +1 -1
  218. package/dist/tempo/legacy/client/Session.d.ts +20 -20
  219. package/dist/tempo/legacy/client/Session.js.map +1 -1
  220. package/dist/tempo/legacy/client/SessionManager.js.map +1 -1
  221. package/dist/tempo/legacy/index.d.ts +1 -3
  222. package/dist/tempo/legacy/index.d.ts.map +1 -1
  223. package/dist/tempo/legacy/index.js +1 -3
  224. package/dist/tempo/legacy/index.js.map +1 -1
  225. package/dist/tempo/legacy/session/escrow.abi.d.ts +374 -374
  226. package/dist/tempo/legacy/session/escrow.abi.d.ts.map +1 -1
  227. package/dist/tempo/server/Charge.d.ts +34 -12
  228. package/dist/tempo/server/Charge.d.ts.map +1 -1
  229. package/dist/tempo/server/Charge.js +44 -39
  230. package/dist/tempo/server/Charge.js.map +1 -1
  231. package/dist/tempo/server/Methods.d.ts +37 -52
  232. package/dist/tempo/server/Methods.d.ts.map +1 -1
  233. package/dist/tempo/server/Methods.js +0 -14
  234. package/dist/tempo/server/Methods.js.map +1 -1
  235. package/dist/tempo/server/Relay.d.ts +14 -5
  236. package/dist/tempo/server/Relay.d.ts.map +1 -1
  237. package/dist/tempo/server/Relay.js +6 -4
  238. package/dist/tempo/server/Relay.js.map +1 -1
  239. package/dist/tempo/server/SponsorBudget.d.ts.map +1 -1
  240. package/dist/tempo/server/SponsorBudget.js +7 -1
  241. package/dist/tempo/server/SponsorBudget.js.map +1 -1
  242. package/dist/tempo/server/Subscription.d.ts +25 -25
  243. package/dist/tempo/server/Subscription.d.ts.map +1 -1
  244. package/dist/tempo/server/Subscription.js +2 -0
  245. package/dist/tempo/server/Subscription.js.map +1 -1
  246. package/dist/tempo/server/index.d.ts +1 -1
  247. package/dist/tempo/server/index.d.ts.map +1 -1
  248. package/dist/tempo/server/index.js +1 -1
  249. package/dist/tempo/server/index.js.map +1 -1
  250. package/dist/tempo/server/internal/html.gen.d.ts +1 -1
  251. package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
  252. package/dist/tempo/server/internal/html.gen.js +1 -1
  253. package/dist/tempo/server/internal/html.gen.js.map +1 -1
  254. package/dist/tempo/server/internal/transport.d.ts +2 -0
  255. package/dist/tempo/server/internal/transport.d.ts.map +1 -1
  256. package/dist/tempo/server/internal/transport.js +9 -2
  257. package/dist/tempo/server/internal/transport.js.map +1 -1
  258. package/dist/tempo/session/client/ChannelOps.js.map +1 -1
  259. package/dist/tempo/session/client/CredentialState.d.ts +1 -1
  260. package/dist/tempo/session/client/CredentialState.js.map +1 -1
  261. package/dist/tempo/session/client/ReceiptCoordinator.js.map +1 -1
  262. package/dist/tempo/session/client/Runtime.js.map +1 -1
  263. package/dist/tempo/session/client/Session.d.ts +19 -19
  264. package/dist/tempo/session/client/Session.d.ts.map +1 -1
  265. package/dist/tempo/session/client/Session.js +128 -14
  266. package/dist/tempo/session/client/Session.js.map +1 -1
  267. package/dist/tempo/session/client/SessionManager.d.ts.map +1 -1
  268. package/dist/tempo/session/client/SessionManager.js +62 -20
  269. package/dist/tempo/session/client/SessionManager.js.map +1 -1
  270. package/dist/tempo/session/client/Transports.d.ts +9 -1
  271. package/dist/tempo/session/client/Transports.d.ts.map +1 -1
  272. package/dist/tempo/session/client/Transports.js +36 -13
  273. package/dist/tempo/session/client/Transports.js.map +1 -1
  274. package/dist/tempo/session/precompile/Chain.d.ts +27 -0
  275. package/dist/tempo/session/precompile/Chain.d.ts.map +1 -1
  276. package/dist/tempo/session/precompile/Chain.js +68 -7
  277. package/dist/tempo/session/precompile/Chain.js.map +1 -1
  278. package/dist/tempo/session/precompile/Protocol.js.map +1 -1
  279. package/dist/tempo/session/precompile/Voucher.d.ts +4 -4
  280. package/dist/tempo/session/precompile/Voucher.d.ts.map +1 -1
  281. package/dist/tempo/session/precompile/escrow.abi.d.ts +306 -306
  282. package/dist/tempo/session/precompile/escrow.abi.d.ts.map +1 -1
  283. package/dist/tempo/session/server/ChannelStore.d.ts +9 -0
  284. package/dist/tempo/session/server/ChannelStore.d.ts.map +1 -1
  285. package/dist/tempo/session/server/ChannelStore.js +16 -8
  286. package/dist/tempo/session/server/ChannelStore.js.map +1 -1
  287. package/dist/tempo/session/server/CredentialVerification.d.ts +30 -13
  288. package/dist/tempo/session/server/CredentialVerification.d.ts.map +1 -1
  289. package/dist/tempo/session/server/CredentialVerification.js +207 -13
  290. package/dist/tempo/session/server/CredentialVerification.js.map +1 -1
  291. package/dist/tempo/session/server/MeteredStream.d.ts +3 -0
  292. package/dist/tempo/session/server/MeteredStream.d.ts.map +1 -1
  293. package/dist/tempo/session/server/MeteredStream.js +3 -1
  294. package/dist/tempo/session/server/MeteredStream.js.map +1 -1
  295. package/dist/tempo/session/server/Session.d.ts +32 -21
  296. package/dist/tempo/session/server/Session.d.ts.map +1 -1
  297. package/dist/tempo/session/server/Session.js +116 -53
  298. package/dist/tempo/session/server/Session.js.map +1 -1
  299. package/dist/tempo/session/server/Sse.d.ts +3 -1
  300. package/dist/tempo/session/server/Sse.d.ts.map +1 -1
  301. package/dist/tempo/session/server/Sse.js +2 -1
  302. package/dist/tempo/session/server/Sse.js.map +1 -1
  303. package/dist/tempo/session/server/Transports.d.ts +1 -1
  304. package/dist/tempo/session/server/Transports.d.ts.map +1 -1
  305. package/dist/tempo/session/server/Transports.js +1 -0
  306. package/dist/tempo/session/server/Transports.js.map +1 -1
  307. package/dist/tempo/session/server/Ws.d.ts +6 -1
  308. package/dist/tempo/session/server/Ws.d.ts.map +1 -1
  309. package/dist/tempo/session/server/Ws.js +4 -0
  310. package/dist/tempo/session/server/Ws.js.map +1 -1
  311. package/dist/tempo/subscription/KeyAuthorization.d.ts +38 -866
  312. package/dist/tempo/subscription/KeyAuthorization.d.ts.map +1 -1
  313. package/dist/tempo/subscription/KeyAuthorization.js +14 -3
  314. package/dist/tempo/subscription/KeyAuthorization.js.map +1 -1
  315. package/dist/viem/Account.d.ts.map +1 -1
  316. package/dist/viem/Account.js.map +1 -1
  317. package/dist/viem/Client.d.ts.map +1 -1
  318. package/dist/viem/Client.js +6 -1
  319. package/dist/viem/Client.js.map +1 -1
  320. package/dist/web-bot-auth/Constants.d.ts +20 -0
  321. package/dist/web-bot-auth/Constants.d.ts.map +1 -0
  322. package/dist/web-bot-auth/Constants.js +24 -0
  323. package/dist/web-bot-auth/Constants.js.map +1 -0
  324. package/dist/web-bot-auth/Types.d.ts +10 -0
  325. package/dist/web-bot-auth/Types.d.ts.map +1 -0
  326. package/dist/web-bot-auth/Types.js +2 -0
  327. package/dist/web-bot-auth/Types.js.map +1 -0
  328. package/dist/web-bot-auth/client/index.d.ts +29 -0
  329. package/dist/web-bot-auth/client/index.d.ts.map +1 -0
  330. package/dist/web-bot-auth/client/index.js +64 -0
  331. package/dist/web-bot-auth/client/index.js.map +1 -0
  332. package/dist/web-bot-auth/index.d.ts +7 -0
  333. package/dist/web-bot-auth/index.d.ts.map +1 -0
  334. package/dist/web-bot-auth/index.js +7 -0
  335. package/dist/web-bot-auth/index.js.map +1 -0
  336. package/dist/web-bot-auth/internal/JwkThumbprint.d.ts +5 -0
  337. package/dist/web-bot-auth/internal/JwkThumbprint.d.ts.map +1 -0
  338. package/dist/web-bot-auth/internal/JwkThumbprint.js +20 -0
  339. package/dist/web-bot-auth/internal/JwkThumbprint.js.map +1 -0
  340. package/dist/web-bot-auth/internal/SignatureAgent.d.ts +3 -0
  341. package/dist/web-bot-auth/internal/SignatureAgent.d.ts.map +1 -0
  342. package/dist/web-bot-auth/internal/SignatureAgent.js +18 -0
  343. package/dist/web-bot-auth/internal/SignatureAgent.js.map +1 -0
  344. package/dist/web-bot-auth/server/index.d.ts +35 -0
  345. package/dist/web-bot-auth/server/index.d.ts.map +1 -0
  346. package/dist/web-bot-auth/server/index.js +88 -0
  347. package/dist/web-bot-auth/server/index.js.map +1 -0
  348. package/dist/x402/Assets.d.ts.map +1 -1
  349. package/dist/x402/Types.d.ts +6 -6
  350. package/dist/x402/Types.d.ts.map +1 -1
  351. package/dist/x402/server/EvmCharge.d.ts.map +1 -1
  352. package/dist/x402/server/EvmCharge.js +32 -20
  353. package/dist/x402/server/EvmCharge.js.map +1 -1
  354. package/package.json +20 -4
  355. package/src/Challenge.fuzz.test.ts +80 -47
  356. package/src/Challenge.test.ts +65 -0
  357. package/src/Challenge.ts +39 -35
  358. package/src/Method.ts +82 -68
  359. package/src/Store.test-d.ts +16 -0
  360. package/src/Store.test.ts +50 -0
  361. package/src/Store.ts +68 -0
  362. package/src/attestation/Attestation.integration.test.ts +208 -0
  363. package/src/attestation/Client.test.ts +83 -0
  364. package/src/attestation/Client.ts +34 -0
  365. package/src/attestation/Constants.ts +15 -0
  366. package/src/attestation/Server.test.ts +60 -0
  367. package/src/attestation/Server.ts +12 -0
  368. package/src/attestation/Types.test-d.ts +54 -0
  369. package/src/attestation/Types.ts +77 -0
  370. package/src/attestation/index.ts +5 -0
  371. package/src/attestation/internal/HttpMessageSignature.test.ts +101 -0
  372. package/src/attestation/internal/HttpMessageSignature.ts +429 -0
  373. package/src/attestation/internal/SigningContext.ts +13 -0
  374. package/src/bin.js +2 -0
  375. package/src/cli/cli.ts +1 -0
  376. package/src/cli/validate/payment.ts +18 -4
  377. package/src/cli/validate.test.ts +16 -0
  378. package/src/client/Mppx.test-d.ts +17 -0
  379. package/src/client/Mppx.test.ts +14 -14
  380. package/src/client/Mppx.ts +25 -4
  381. package/src/client/Transport.test.ts +12 -45
  382. package/src/client/Transport.ts +3 -24
  383. package/src/client/internal/Fetch.test.ts +77 -0
  384. package/src/client/internal/Fetch.ts +112 -14
  385. package/src/client/internal/MethodChallenge.ts +5 -0
  386. package/src/client/internal/MethodResponse.ts +28 -0
  387. package/src/discovery/OpenApi.test.ts +170 -0
  388. package/src/discovery/OpenApi.ts +16 -48
  389. package/src/discovery/internal/Metadata.ts +51 -0
  390. package/src/evm/server/Charge.ts +6 -1
  391. package/src/internal/AcceptPayment.test.ts +12 -8
  392. package/src/internal/types.ts +9 -0
  393. package/src/mcp/client/McpClient.integration.test.ts +19 -32
  394. package/src/middlewares/elysia.test.ts +2 -12
  395. package/src/middlewares/express.test.ts +2 -12
  396. package/src/middlewares/hono.test.ts +6 -9
  397. package/src/middlewares/nextjs.test.ts +2 -12
  398. package/src/proxy/Proxy.test.ts +26 -19
  399. package/src/proxy/Proxy.ts +147 -9
  400. package/src/proxy/Proxy.upstreamError.test.ts +364 -0
  401. package/src/proxy/Service.test.ts +73 -3
  402. package/src/proxy/Service.ts +50 -23
  403. package/src/proxy/services/anthropic.ts +1 -0
  404. package/src/proxy/services/hooks.test-d.ts +14 -0
  405. package/src/proxy/services/hooks.test.ts +44 -0
  406. package/src/proxy/services/openai.ts +1 -0
  407. package/src/proxy/services/stripe.ts +1 -0
  408. package/src/server/Methods.test-d.ts +88 -0
  409. package/src/server/Methods.test.ts +69 -0
  410. package/src/server/Mppx.test-d.ts +141 -7
  411. package/src/server/Mppx.test.ts +1017 -119
  412. package/src/server/Mppx.ts +350 -54
  413. package/src/stripe/internal/constants.ts +1 -1
  414. package/src/stripe/internal/types.ts +1 -0
  415. package/src/stripe/server/Charge.test-d.ts +16 -1
  416. package/src/stripe/server/Charge.test.ts +79 -0
  417. package/src/stripe/server/Charge.ts +54 -1
  418. package/src/stripe/server/Methods.test-d.ts +157 -0
  419. package/src/stripe/server/Methods.test.ts +403 -0
  420. package/src/stripe/server/Methods.ts +423 -6
  421. package/src/stripe/server/internal/deposit-address.ts +57 -0
  422. package/src/stripe/server/internal/html/node_modules/.bin/mppx +3 -3
  423. package/src/stripe/server/internal/html/package.json +1 -1
  424. package/src/stripe/server/internal/html.gen.ts +1 -1
  425. package/src/stripe/server/internal/record-payment.ts +66 -0
  426. package/src/stripe/server/internal/request.ts +49 -0
  427. package/src/tap/Constants.ts +32 -0
  428. package/src/tap/Tap.test.ts +125 -0
  429. package/src/tap/Types.ts +11 -0
  430. package/src/tap/client/index.ts +54 -0
  431. package/src/tap/index.ts +4 -0
  432. package/src/tap/server/index.ts +48 -0
  433. package/src/tempo/PublicExports.test-d.ts +3 -3
  434. package/src/tempo/client/Charge.ts +1 -19
  435. package/src/tempo/internal/address.test.ts +42 -0
  436. package/src/tempo/internal/address.ts +3 -3
  437. package/src/tempo/internal/auto-swap.test.ts +4 -4
  438. package/src/tempo/internal/auto-swap.ts +7 -50
  439. package/src/tempo/legacy/README.md +5 -5
  440. package/src/tempo/legacy/index.ts +1 -3
  441. package/src/tempo/server/AtomicStore.test-d.ts +13 -0
  442. package/src/tempo/server/Charge.test.ts +19 -84
  443. package/src/tempo/server/Charge.ts +92 -56
  444. package/src/tempo/server/Methods.ts +0 -20
  445. package/src/tempo/server/Relay.test.ts +161 -7
  446. package/src/tempo/server/Relay.ts +15 -6
  447. package/src/tempo/server/SponsorBudget.test.ts +29 -0
  448. package/src/tempo/server/SponsorBudget.ts +7 -1
  449. package/src/tempo/server/Subscription.ts +4 -1
  450. package/src/tempo/server/index.ts +1 -1
  451. package/src/tempo/server/internal/html/node_modules/.bin/mppx +3 -3
  452. package/src/tempo/server/internal/html/package.json +1 -1
  453. package/src/tempo/server/internal/html.gen.ts +1 -1
  454. package/src/tempo/server/internal/transport.test.ts +22 -3
  455. package/src/tempo/server/internal/transport.ts +15 -3
  456. package/src/tempo/session/README.md +119 -0
  457. package/src/tempo/session/client/Session.test.ts +299 -33
  458. package/src/tempo/session/client/Session.ts +152 -16
  459. package/src/tempo/session/client/SessionManager.test.ts +216 -9
  460. package/src/tempo/session/client/SessionManager.ts +63 -17
  461. package/src/tempo/session/client/Transports.test.ts +22 -0
  462. package/src/tempo/session/client/Transports.ts +58 -22
  463. package/src/tempo/session/precompile/Chain.ts +131 -11
  464. package/src/tempo/session/server/ChannelStore.ts +33 -12
  465. package/src/tempo/session/server/CredentialVerification.test.ts +4 -4
  466. package/src/tempo/session/server/CredentialVerification.ts +340 -28
  467. package/src/tempo/session/server/MeteredStream.ts +5 -1
  468. package/src/tempo/session/server/Session.test.ts +483 -36
  469. package/src/tempo/session/server/Session.ts +159 -60
  470. package/src/tempo/session/server/Sse.test.ts +77 -0
  471. package/src/tempo/session/server/Sse.ts +8 -1
  472. package/src/tempo/session/server/Transports.ts +2 -1
  473. package/src/tempo/session/server/Ws.test.ts +171 -0
  474. package/src/tempo/session/server/Ws.ts +10 -1
  475. package/src/tempo/subscription/KeyAuthorization.test.ts +70 -1
  476. package/src/tempo/subscription/KeyAuthorization.ts +14 -3
  477. package/src/viem/Client.test.ts +18 -1
  478. package/src/viem/Client.ts +7 -1
  479. package/src/web-bot-auth/Constants.ts +24 -0
  480. package/src/web-bot-auth/Types.ts +9 -0
  481. package/src/web-bot-auth/WebBotAuth.test.ts +182 -0
  482. package/src/web-bot-auth/client/index.ts +84 -0
  483. package/src/web-bot-auth/index.ts +6 -0
  484. package/src/web-bot-auth/internal/JwkThumbprint.ts +21 -0
  485. package/src/web-bot-auth/internal/SignatureAgent.ts +18 -0
  486. package/src/web-bot-auth/server/index.ts +113 -0
  487. package/src/x402/Exact.e2e.test.ts +121 -81
  488. package/src/x402/Exact.localnet.test.ts +1 -1
  489. package/src/x402/server/EvmCharge.ts +35 -19
  490. package/dist/tempo/legacy/server/Session.d.ts +0 -208
  491. package/dist/tempo/legacy/server/Session.d.ts.map +0 -1
  492. package/dist/tempo/legacy/server/Session.js +0 -698
  493. package/dist/tempo/legacy/server/Session.js.map +0 -1
  494. package/dist/tempo/legacy/server/index.d.ts +0 -5
  495. package/dist/tempo/legacy/server/index.d.ts.map +0 -1
  496. package/dist/tempo/legacy/server/index.js +0 -5
  497. package/dist/tempo/legacy/server/index.js.map +0 -1
  498. package/dist/tempo/legacy/session/ChannelStore.d.ts +0 -22
  499. package/dist/tempo/legacy/session/ChannelStore.d.ts.map +0 -1
  500. package/dist/tempo/legacy/session/ChannelStore.js +0 -6
  501. package/dist/tempo/legacy/session/ChannelStore.js.map +0 -1
  502. package/src/tempo/legacy/server/Defaults.test-d.ts +0 -9
  503. package/src/tempo/legacy/server/Session.test.ts +0 -6370
  504. package/src/tempo/legacy/server/Session.ts +0 -1024
  505. package/src/tempo/legacy/server/index.ts +0 -4
  506. package/src/tempo/legacy/session/ChannelStore.test.ts +0 -58
  507. package/src/tempo/legacy/session/ChannelStore.ts +0 -39
@@ -1,4 +1,5 @@
1
- import { KeyAuthorization } from 'ox/tempo'
1
+ import { Rlp } from 'ox'
2
+ import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo'
2
3
  import { privateKeyToAccount } from 'viem/accounts'
3
4
  import { describe, expect, test } from 'vp/test'
4
5
 
@@ -69,6 +70,25 @@ async function createPayload(request = parseRequest()) {
69
70
  } as const
70
71
  }
71
72
 
73
+ function serializeCompositeSignature(
74
+ type: 'keychain' | 'multisig',
75
+ inner: SignatureEnvelope.Primitive,
76
+ ) {
77
+ return SignatureEnvelope.serialize(
78
+ type === 'keychain'
79
+ ? {
80
+ inner,
81
+ type,
82
+ userAddress: rootAccount.address,
83
+ }
84
+ : {
85
+ account: rootAccount.address,
86
+ signatures: [inner],
87
+ type,
88
+ },
89
+ )
90
+ }
91
+
72
92
  describe('tempo subscription key authorization', () => {
73
93
  test('signs and verifies a scoped key authorization', async () => {
74
94
  const request = parseRequest()
@@ -87,6 +107,55 @@ describe('tempo subscription key authorization', () => {
87
107
  )
88
108
  })
89
109
 
110
+ test.each(['keychain', 'multisig'] as const)(
111
+ 'rejects %s authorization signatures',
112
+ async (type) => {
113
+ const request = parseRequest()
114
+
115
+ await expect(
116
+ signSubscriptionKeyAuthorization({
117
+ accessKey,
118
+ account: {
119
+ async sign({ hash }) {
120
+ const inner = SignatureEnvelope.from(await rootAccount.sign({ hash }))
121
+ if (inner.type === 'keychain' || inner.type === 'multisig') {
122
+ throw new Error('expected primitive signature')
123
+ }
124
+ return serializeCompositeSignature(type, inner)
125
+ },
126
+ },
127
+ chainId: 4217,
128
+ request,
129
+ }),
130
+ ).rejects.toThrow('keyAuthorization must use a primitive signature')
131
+ },
132
+ )
133
+
134
+ test.each(['keychain', 'multisig'] as const)(
135
+ 'rejects serialized %s authorization signatures',
136
+ async (type) => {
137
+ const request = parseRequest()
138
+ const payload = await createPayload(request)
139
+ const authorization = KeyAuthorization.deserialize(payload.signature)
140
+ const [authorizationTuple] = KeyAuthorization.toTuple(authorization)
141
+
142
+ expect(() =>
143
+ verifySubscriptionKeyAuthorization({
144
+ accessKey,
145
+ chainId: 4217,
146
+ payload: {
147
+ ...payload,
148
+ signature: Rlp.fromHex([
149
+ authorizationTuple,
150
+ serializeCompositeSignature(type, authorization.signature!),
151
+ ]),
152
+ },
153
+ request,
154
+ }),
155
+ ).toThrow('keyAuthorization must use a primitive signature')
156
+ },
157
+ )
158
+
90
159
  test('builds wallet allowed calls from the subscription request', () => {
91
160
  const request = parseRequest()
92
161
 
@@ -168,8 +168,14 @@ export async function signSubscriptionKeyAuthorization(parameters: {
168
168
  const signature = await account.sign({
169
169
  hash: KeyAuthorization.getSignPayload(authorization),
170
170
  })
171
+ const signatureEnvelope = SignatureEnvelope.from(signature)
172
+ if (signatureEnvelope.type === 'keychain' || signatureEnvelope.type === 'multisig') {
173
+ throw new VerificationFailedError({
174
+ reason: 'keyAuthorization must use a primitive signature',
175
+ })
176
+ }
171
177
  return KeyAuthorization.from(authorization, {
172
- signature: SignatureEnvelope.from(signature),
178
+ signature,
173
179
  })
174
180
  }
175
181
 
@@ -238,14 +244,19 @@ function createUnsignedAuthorization(parameters: {
238
244
  function deserializeAuthorization(signature: `0x${string}`) {
239
245
  try {
240
246
  return KeyAuthorization.deserialize(signature)
241
- } catch {
247
+ } catch (error) {
248
+ if (error instanceof KeyAuthorization.InvalidSignatureTypeError) {
249
+ throw new VerificationFailedError({
250
+ reason: 'keyAuthorization must use a primitive signature',
251
+ })
252
+ }
242
253
  throw new VerificationFailedError({ reason: 'invalid keyAuthorization payload' })
243
254
  }
244
255
  }
245
256
 
246
257
  function getPrimitiveSignature(authorization: Authorization) {
247
258
  const signature = authorization.signature
248
- if (!signature || signature.type === 'keychain') {
259
+ if (!signature) {
249
260
  throw new VerificationFailedError({
250
261
  reason: 'keyAuthorization must use a primitive signature',
251
262
  })
@@ -2,7 +2,7 @@ import { createClient, custom, defineChain, type Hex } from 'viem'
2
2
  import { privateKeyToAccount } from 'viem/accounts'
3
3
  import { signTransaction } from 'viem/actions'
4
4
  import { Account as TempoAccount, Transaction } from 'viem/tempo'
5
- import { tempoLocalnet } from 'viem/tempo/chains'
5
+ import { tempo as tempoMainnetChain, tempoLocalnet, tempoModerato } from 'viem/tempo/chains'
6
6
  import { afterEach, describe, expect, test, vi } from 'vp/test'
7
7
 
8
8
  import * as Client from './Client.js'
@@ -48,6 +48,23 @@ describe('getResolver', () => {
48
48
  expect(client.chain?.name).toBe('test')
49
49
  })
50
50
 
51
+ test('behavior: resolves the correct named Tempo chain even when the default chain differs', async () => {
52
+ const getClient = Client.getResolver({
53
+ // Default chain is mainnet, but the resolved chain ID below is testnet.
54
+ chain: tempoMainnetChain as never,
55
+ rpcUrl: {
56
+ [tempoMainnetChain.id]: 'https://rpc.example.com',
57
+ [tempoModerato.id]: 'https://rpc2.example.com',
58
+ },
59
+ })
60
+
61
+ const client = await getClient({ chainId: tempoModerato.id })
62
+
63
+ expect(client.chain?.id).toBe(tempoModerato.id)
64
+ expect(client.chain?.name).toBe(tempoModerato.name)
65
+ expect(client.chain?.name).not.toBe(tempoMainnetChain.name)
66
+ })
67
+
51
68
  test('error: throws when no rpcUrl provided', () => {
52
69
  const getClient = Client.getResolver({})
53
70
 
@@ -1,8 +1,14 @@
1
1
  import { type Chain, type Client, createClient, createTransport, custom, http } from 'viem'
2
2
  import { withFeePayer } from 'viem/tempo'
3
+ import { tempo as tempoMainnetChain, tempoModerato } from 'viem/tempo/chains'
3
4
 
4
5
  import type { MaybePromise } from '../internal/types.js'
5
6
 
7
+ const knownTempoChains: Record<number, Chain> = {
8
+ [tempoMainnetChain.id]: tempoMainnetChain,
9
+ [tempoModerato.id]: tempoModerato,
10
+ }
11
+
6
12
  export function getResolver(
7
13
  parameters: getResolver.Parameters & {
8
14
  /** Default chain to use if not provided. */
@@ -73,7 +79,7 @@ export function getResolver(
73
79
  if (!url) throw new Error(`No \`rpcUrl\` configured for \`chainId\` (${resolvedChainId}).`)
74
80
  const transport = feePayerUrl ? withFeePayer(http(url), http(feePayerUrl)) : http(url)
75
81
  return createClient({
76
- chain: { ...chain, id: resolvedChainId } as never,
82
+ chain: (knownTempoChains[resolvedChainId] ?? { ...chain, id: resolvedChainId }) as never,
77
83
  transport,
78
84
  })
79
85
  }
@@ -0,0 +1,24 @@
1
+ import { Constants as HttpMessageSignature } from '../attestation/internal/HttpMessageSignature.js'
2
+
3
+ /** Web Bot Auth values for the supported HTTPS-directory signature profile. */
4
+ export const Constants = {
5
+ /** Stable identifier for Web Bot Auth signers and replay storage. */
6
+ protocol: 'web-bot-auth',
7
+ /** Web Bot Auth discovery type supported by this adapter. */
8
+ discoveryType: 'directory',
9
+ /** RFC 9421 signature label used when no label is configured. */
10
+ label: 'webbot',
11
+ /** Tag identifying a Web Bot Auth request signature. */
12
+ tag: 'web-bot-auth',
13
+ /** Structured HTTP header linking a bot signature to its HTTPS directory origin. */
14
+ signatureAgentHeader: 'Signature-Agent',
15
+ /** Default lifetime, in seconds, for a bot request signature. */
16
+ defaultSignatureLifetime: 60,
17
+ /** Default verifier limit, following the draft's recommended 24-hour maximum. */
18
+ defaultMaximumSignatureLifetime: 24 * 60 * 60,
19
+ /** HTTP components required by this directory profile. */
20
+ requiredComponents: [
21
+ HttpMessageSignature.components.authority,
22
+ HttpMessageSignature.components.signatureAgent,
23
+ ],
24
+ } as const
@@ -0,0 +1,9 @@
1
+ /** Verified Web Bot Auth HTTPS-directory profile request signature. */
2
+ export type VerifiedRequest = {
3
+ /** Public-key thumbprint advertised by the bot. */
4
+ keyId: string
5
+ /** HTTPS directory origin carried in the signed `Signature-Agent` header. */
6
+ signatureAgent: string
7
+ /** Signature nonce supplied by the bot. */
8
+ nonce: string
9
+ }
@@ -0,0 +1,182 @@
1
+ import * as Attestation from 'mppx/attestation'
2
+ import * as WebBotAuth from 'mppx/attestation/web-bot-auth'
3
+ import { expect, test } from 'vp/test'
4
+ import { jwkThumbprint, keyPair, rsaKeyPair } from '~test/Attestation.js'
5
+
6
+ import * as HttpMessageSignature from '../attestation/internal/HttpMessageSignature.js'
7
+
8
+ test('emits and verifies a signed Signature-Agent member', async () => {
9
+ const keys = await keyPair()
10
+ const keyId = await jwkThumbprint(keys.publicKey)
11
+ const signatureAgent = 'https://agent.example'
12
+ const signed = await WebBotAuth.Client.signer({
13
+ expiresIn: WebBotAuth.Constants.defaultSignatureLifetime + 1,
14
+ key: keys.privateKey,
15
+ keyId,
16
+ signatureAgent: `${signatureAgent}/`,
17
+ }).sign(new Request('https://merchant.example/resource'))
18
+
19
+ expect(signed.headers.get(WebBotAuth.Constants.signatureAgentHeader)).toBe(
20
+ `${WebBotAuth.Constants.label}="${signatureAgent}"`,
21
+ )
22
+ expect(signed.headers.get(Attestation.Headers.signatureInput)).toContain(
23
+ `"signature-agent";key="${WebBotAuth.Constants.label}"`,
24
+ )
25
+ expect(
26
+ await WebBotAuth.Server.verifier({
27
+ keyResolver: () => keys.publicKey,
28
+ maxAge: WebBotAuth.Constants.defaultSignatureLifetime,
29
+ nonceStore: Attestation.Store.memory(),
30
+ }).verify(signed),
31
+ ).toMatchObject({ status: 'invalid' })
32
+ expect(
33
+ await WebBotAuth.Server.verifier({
34
+ keyResolver: () => keys.publicKey,
35
+ nonceStore: Attestation.Store.memory(),
36
+ }).verify(signed),
37
+ ).toMatchObject({
38
+ status: 'verified',
39
+ value: { keyId, signatureAgent },
40
+ })
41
+ })
42
+
43
+ test('signs and verifies RSA-PSS SHA-512', async () => {
44
+ const keys = await rsaKeyPair()
45
+ const keyId = await jwkThumbprint(keys.publicKey)
46
+ const algorithms: Attestation.SignatureAlgorithm[] = []
47
+ const signed = await WebBotAuth.Client.signer({
48
+ key: keys.privateKey,
49
+ keyId,
50
+ signatureAgent: 'https://agent.example',
51
+ }).sign(new Request('https://merchant.example/resource'))
52
+ const result = await WebBotAuth.Server.verifier({
53
+ keyResolver({ algorithm, keyId: candidate }) {
54
+ algorithms.push(algorithm)
55
+ return candidate === keyId ? keys.publicKey : undefined
56
+ },
57
+ nonceStore: Attestation.Store.memory(),
58
+ }).verify(signed)
59
+
60
+ expect(signed.headers.get(Attestation.Headers.signatureInput)).toContain(
61
+ `alg="${Attestation.Algorithms.rsaPssSha512}"`,
62
+ )
63
+ expect(algorithms).toEqual([Attestation.Algorithms.rsaPssSha512])
64
+ expect(result).toMatchObject({ status: 'verified' })
65
+ })
66
+
67
+ test('preserves directory lookup failures as unverified outcomes', async () => {
68
+ const keys = await keyPair()
69
+ const keyId = await jwkThumbprint(keys.publicKey)
70
+ const signed = await WebBotAuth.Client.signer({
71
+ key: keys.privateKey,
72
+ keyId,
73
+ signatureAgent: 'https://agent.example',
74
+ }).sign(new Request('https://merchant.example/resource'))
75
+
76
+ expect(
77
+ await WebBotAuth.Server.verifier({
78
+ keyResolver: () => undefined,
79
+ nonceStore: Attestation.Store.memory(),
80
+ }).verify(signed),
81
+ ).toEqual({
82
+ reason: 'No public key is available for the signature key ID.',
83
+ status: 'unverified',
84
+ })
85
+ expect(
86
+ await WebBotAuth.Server.verifier({
87
+ keyResolver() {
88
+ throw new Error('directory unavailable')
89
+ },
90
+ nonceStore: Attestation.Store.memory(),
91
+ }).verify(signed),
92
+ ).toEqual({
93
+ reason: 'The public key could not be resolved.',
94
+ status: 'unverified',
95
+ })
96
+ })
97
+
98
+ test('rejects mismatched keys, non-directory discovery, and header tampering', async () => {
99
+ const advertisedKeys = await keyPair()
100
+ const signingKeys = await keyPair()
101
+ const advertisedKeyId = await jwkThumbprint(advertisedKeys.publicKey)
102
+ const signatureAgent = 'https://agent.example'
103
+ const signed = await WebBotAuth.Client.signer({
104
+ key: signingKeys.privateKey,
105
+ keyId: advertisedKeyId,
106
+ signatureAgent,
107
+ }).sign(new Request('https://merchant.example/resource'))
108
+ const verifier = WebBotAuth.Server.verifier({
109
+ keyResolver: () => signingKeys.publicKey,
110
+ nonceStore: Attestation.Store.memory(),
111
+ })
112
+
113
+ expect(await verifier.verify(signed)).toMatchObject({ status: 'invalid' })
114
+
115
+ const alteredHeaders = new Headers(signed.headers)
116
+ alteredHeaders.set(
117
+ WebBotAuth.Constants.signatureAgentHeader,
118
+ `${WebBotAuth.Constants.label}="https://attacker.example"`,
119
+ )
120
+ expect(
121
+ await WebBotAuth.Server.verifier({
122
+ keyResolver: () => signingKeys.publicKey,
123
+ nonceStore: Attestation.Store.memory(),
124
+ }).verify(new Request(signed, { headers: alteredHeaders })),
125
+ ).toMatchObject({ status: 'invalid' })
126
+
127
+ const discoveryHeaders = new Headers({
128
+ [WebBotAuth.Constants.signatureAgentHeader]:
129
+ 'webbot="https://agent.example/keys";type=jwks_uri',
130
+ })
131
+ const unsupportedDiscovery = await HttpMessageSignature.sign(
132
+ new Request('https://merchant.example/resource', { headers: discoveryHeaders }),
133
+ {
134
+ components: [
135
+ HttpMessageSignature.Constants.components.authority,
136
+ {
137
+ id: HttpMessageSignature.Constants.components.signatureAgent,
138
+ parameters: new Map([['key', WebBotAuth.Constants.label]]),
139
+ },
140
+ ],
141
+ key: advertisedKeys.privateKey,
142
+ keyId: advertisedKeyId,
143
+ label: WebBotAuth.Constants.label,
144
+ tag: WebBotAuth.Constants.tag,
145
+ },
146
+ )
147
+ expect(
148
+ await WebBotAuth.Server.verifier({
149
+ keyResolver: () => advertisedKeys.publicKey,
150
+ nonceStore: Attestation.Store.memory(),
151
+ }).verify(unsupportedDiscovery),
152
+ ).toMatchObject({
153
+ reason: 'The Signature-Agent discovery type is not supported by this directory profile.',
154
+ status: 'invalid',
155
+ })
156
+ })
157
+
158
+ test('validates signer and verifier configuration', async () => {
159
+ const keys = await keyPair()
160
+ const keyId = await jwkThumbprint(keys.publicKey)
161
+ const config = { key: keys.privateKey, keyId, signatureAgent: 'https://agent.example' }
162
+
163
+ expect(() => WebBotAuth.Client.signer({ ...config, keyId: 'not-a-thumbprint' })).toThrow(
164
+ 'Web Bot Auth keyId must be an RFC 7638 SHA-256 JWK thumbprint.',
165
+ )
166
+ expect(() => WebBotAuth.Client.signer({ ...config, signatureAgent: 'https://' })).toThrow(
167
+ 'Signature-Agent must identify a valid HTTPS origin.',
168
+ )
169
+ expect(() =>
170
+ WebBotAuth.Client.signer({ ...config, signatureAgent: 'https://agent.example/keys' }),
171
+ ).toThrow('Signature-Agent must identify a valid HTTPS origin.')
172
+ expect(() => WebBotAuth.Client.signer({ ...config, expiresIn: 0 })).toThrow(
173
+ 'Web Bot Auth expiresIn must be a positive integer.',
174
+ )
175
+ expect(() =>
176
+ WebBotAuth.Server.verifier({
177
+ keyResolver: () => keys.publicKey,
178
+ maxAge: 0,
179
+ nonceStore: Attestation.Store.memory(),
180
+ }),
181
+ ).toThrow('Web Bot Auth maxAge must be a positive integer.')
182
+ })
@@ -0,0 +1,84 @@
1
+ import { parseDictionary, serializeDictionary } from 'structured-headers'
2
+ import type { Dictionary } from 'structured-headers'
3
+
4
+ import * as HttpMessageSignature from '../../attestation/internal/HttpMessageSignature.js'
5
+ import type * as AttestationTypes from '../../attestation/Types.js'
6
+ import { Constants } from '../Constants.js'
7
+ import * as JwkThumbprint from '../internal/JwkThumbprint.js'
8
+ import * as SignatureAgent from '../internal/SignatureAgent.js'
9
+
10
+ /**
11
+ * Creates a Web Bot Auth HTTPS-directory profile request signer.
12
+ *
13
+ * The signed `Signature-Agent` header links the request to the HTTPS origin
14
+ * of an HTTP Message Signatures Directory. This adapter does not support
15
+ * direct key configuration or other Web Bot Auth discovery types. It
16
+ * establishes bot identity only; it does not assert consumer identity or
17
+ * authority to make a payment.
18
+ */
19
+ export function signer(config: signer.Config): AttestationTypes.Signer<typeof Constants.protocol> {
20
+ const label = config.label ?? Constants.label
21
+ const signatureAgentKey = config.signatureAgentKey ?? label
22
+ const expiresIn = config.expiresIn ?? Constants.defaultSignatureLifetime
23
+ const signatureAgent = SignatureAgent.directoryOrigin(config.signatureAgent)
24
+ if (!JwkThumbprint.is(config.keyId))
25
+ throw new TypeError('Web Bot Auth keyId must be an RFC 7638 SHA-256 JWK thumbprint.')
26
+ if (!signatureAgent) throw new TypeError('Signature-Agent must identify a valid HTTPS origin.')
27
+ if (!Number.isInteger(expiresIn) || expiresIn <= 0)
28
+ throw new RangeError('Web Bot Auth expiresIn must be a positive integer.')
29
+ return {
30
+ protocol: Constants.protocol,
31
+ sign(request, context) {
32
+ const headers = new Headers(request.headers)
33
+ const signatureAgents = parseSignatureAgents(headers)
34
+ if (signatureAgents.has(signatureAgentKey))
35
+ throw new Error(`Signature-Agent member "${signatureAgentKey}" already exists.`)
36
+ signatureAgents.set(signatureAgentKey, [signatureAgent, new Map()])
37
+ headers.set(Constants.signatureAgentHeader, serializeDictionary(signatureAgents))
38
+ return HttpMessageSignature.sign(new Request(request, { headers }), {
39
+ components: [
40
+ HttpMessageSignature.Constants.components.authority,
41
+ {
42
+ id: HttpMessageSignature.Constants.components.signatureAgent,
43
+ parameters: new Map([['key', signatureAgentKey]]),
44
+ },
45
+ ],
46
+ context,
47
+ expiresIn,
48
+ key: config.key,
49
+ keyId: config.keyId,
50
+ label,
51
+ tag: Constants.tag,
52
+ })
53
+ },
54
+ }
55
+ }
56
+
57
+ export declare namespace signer {
58
+ type Config = {
59
+ /** Ed25519 or RSA-PSS SHA-512 private key registered for the bot. */
60
+ key: CryptoKey
61
+ /** RFC 7638 JWK thumbprint for the registered public key. */
62
+ keyId: string
63
+ /** Required HTTPS directory origin, sent with the default `directory` discovery type. */
64
+ signatureAgent: string
65
+ /** Dictionary member name used for `Signature-Agent`. @default signature label */
66
+ signatureAgentKey?: string | undefined
67
+ /** Signature lifetime in seconds. @default 60 */
68
+ expiresIn?: number | undefined
69
+ /** RFC 9421 dictionary label. @default 'webbot' */
70
+ label?: string | undefined
71
+ }
72
+ }
73
+
74
+ function parseSignatureAgents(headers: Headers): Dictionary {
75
+ const value = headers.get(Constants.signatureAgentHeader)
76
+ if (!value) return new Map()
77
+ try {
78
+ return parseDictionary(value)
79
+ } catch {
80
+ throw new Error(
81
+ `HTTP header "${Constants.signatureAgentHeader}" is not a structured dictionary.`,
82
+ )
83
+ }
84
+ }
@@ -0,0 +1,6 @@
1
+ /** Client helpers for the Web Bot Auth HTTPS-directory profile. */
2
+ export * as Client from './client/index.js'
3
+ /** Server helpers for the Web Bot Auth HTTPS-directory profile. */
4
+ export * as Server from './server/index.js'
5
+ export * from './Constants.js'
6
+ export * from './Types.js'
@@ -0,0 +1,21 @@
1
+ import { Base64 } from 'ox'
2
+
3
+ const pattern = /^[A-Za-z0-9_-]{43}$/
4
+
5
+ /** Returns whether a value has the RFC 7638 SHA-256 thumbprint encoding. */
6
+ export function is(value: string): boolean {
7
+ return pattern.test(value)
8
+ }
9
+
10
+ /** Derives an RFC 7638 thumbprint from an extractable Ed25519 or RSA public key. */
11
+ export async function fromKey(key: CryptoKey): Promise<string> {
12
+ const jwk = await crypto.subtle.exportKey('jwk', key)
13
+ let canonical: string
14
+ if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519' && jwk.x)
15
+ canonical = JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x })
16
+ else if (jwk.kty === 'RSA' && jwk.e && jwk.n)
17
+ canonical = JSON.stringify({ e: jwk.e, kty: jwk.kty, n: jwk.n })
18
+ else throw new TypeError('Web Bot Auth requires an Ed25519 or RSA public key.')
19
+ const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(canonical))
20
+ return Base64.fromBytes(new Uint8Array(digest), { pad: false, url: true })
21
+ }
@@ -0,0 +1,18 @@
1
+ /** Returns the canonical origin for a Web Bot Auth directory identifier. */
2
+ export function directoryOrigin(value: string): string | undefined {
3
+ try {
4
+ const url = new URL(value)
5
+ if (
6
+ url.protocol !== 'https:' ||
7
+ url.username ||
8
+ url.password ||
9
+ url.pathname !== '/' ||
10
+ url.search ||
11
+ url.hash
12
+ )
13
+ return undefined
14
+ return url.origin
15
+ } catch {
16
+ return undefined
17
+ }
18
+ }
@@ -0,0 +1,113 @@
1
+ import { isInnerList, parseDictionary, Token } from 'structured-headers'
2
+
3
+ import * as HttpMessageSignature from '../../attestation/internal/HttpMessageSignature.js'
4
+ import type * as Attestation from '../../attestation/Types.js'
5
+ import type * as Store from '../../Store.js'
6
+ import { Constants } from '../Constants.js'
7
+ import * as JwkThumbprint from '../internal/JwkThumbprint.js'
8
+ import * as SignatureAgent from '../internal/SignatureAgent.js'
9
+ import type * as Types from '../Types.js'
10
+
11
+ /**
12
+ * Creates a verifier for the Web Bot Auth HTTPS-directory profile.
13
+ *
14
+ * It requires an `@authority` and signed `Signature-Agent` directory member;
15
+ * direct key configuration and other Web Bot Auth discovery types are outside
16
+ * this adapter's scope. Verification confirms the cryptographic identity of an
17
+ * automated HTTP client. It must not be used on its own as user or payment
18
+ * authorization.
19
+ */
20
+ export function verifier(config: verifier.Config): Attestation.Verifier<Types.VerifiedRequest> {
21
+ const maxAge = config.maxAge ?? Constants.defaultMaximumSignatureLifetime
22
+ if (!Number.isInteger(maxAge) || maxAge <= 0)
23
+ throw new RangeError('Web Bot Auth maxAge must be a positive integer.')
24
+ return {
25
+ async verify(request) {
26
+ let signatureAgent: string | undefined
27
+ const result = await HttpMessageSignature.verify(request, {
28
+ async keyResolver(parameters) {
29
+ return config.keyResolver({
30
+ ...parameters,
31
+ signatureAgent: signatureAgent!,
32
+ })
33
+ },
34
+ async validateKey(key, input) {
35
+ try {
36
+ return (await JwkThumbprint.fromKey(key)) === input.keyId
37
+ ? undefined
38
+ : 'The Web Bot Auth key does not match its RFC 7638 keyid.'
39
+ } catch {
40
+ return 'The Web Bot Auth key must be an extractable Ed25519 or RSA public key.'
41
+ }
42
+ },
43
+ maxAge,
44
+ nonceNamespace: Constants.protocol,
45
+ nonceStore: config.nonceStore,
46
+ requiredComponents: Constants.requiredComponents,
47
+ tag: Constants.tag,
48
+ validate(signature, request) {
49
+ if (!JwkThumbprint.is(signature.keyId))
50
+ return 'The Web Bot Auth keyid must be an RFC 7638 SHA-256 JWK thumbprint.'
51
+ const component = signature.components.find(
52
+ (entry) => entry.id === HttpMessageSignature.Constants.components.signatureAgent,
53
+ )
54
+ const key = component?.parameters?.get('key')
55
+ if (typeof key !== 'string')
56
+ return 'The signed Signature-Agent component must identify a dictionary member.'
57
+ const value = request.headers.get(Constants.signatureAgentHeader)
58
+ if (!value) return 'The Signature-Agent header is required.'
59
+ let agents
60
+ try {
61
+ agents = parseDictionary(value)
62
+ } catch {
63
+ return 'The Signature-Agent header must be a structured dictionary.'
64
+ }
65
+ const agent = agents.get(key)
66
+ if (!agent || isInnerList(agent) || typeof agent[0] !== 'string')
67
+ return 'The signed Signature-Agent member must be an HTTPS URL.'
68
+ const type = agent[1].get('type')
69
+ if (
70
+ type !== undefined &&
71
+ (!(type instanceof Token) || type.toString() !== Constants.discoveryType)
72
+ )
73
+ return 'The Signature-Agent discovery type is not supported by this directory profile.'
74
+ const origin = SignatureAgent.directoryOrigin(agent[0])
75
+ if (!origin) return 'The Signature-Agent header must identify a valid HTTPS origin.'
76
+ signatureAgent = origin
77
+ return undefined
78
+ },
79
+ })
80
+ if (result.status !== 'verified') return result
81
+ return {
82
+ status: 'verified',
83
+ value: {
84
+ keyId: result.input.keyId,
85
+ nonce: result.input.nonce,
86
+ signatureAgent: signatureAgent!,
87
+ },
88
+ }
89
+ },
90
+ }
91
+ }
92
+
93
+ export declare namespace verifier {
94
+ type Config = {
95
+ /**
96
+ * Resolves a public key for the advertised directory.
97
+ *
98
+ * Apply the origin's trust policy before any network lookup; do not fetch an
99
+ * arbitrary caller-provided `signatureAgent` URL. Returned public keys
100
+ * must be extractable so their RFC 7638 thumbprints can be verified.
101
+ */
102
+ keyResolver: (parameters: {
103
+ algorithm: Attestation.SignatureAlgorithm
104
+ keyId: string
105
+ request: Request
106
+ signatureAgent: string
107
+ }) => Promise<CryptoKey | undefined> | CryptoKey | undefined
108
+ /** Maximum accepted signature lifetime in seconds. @default 86400 */
109
+ maxAge?: number | undefined
110
+ /** Atomically consumes each nonce in shared storage for multi-instance deployments. */
111
+ nonceStore: Store.AtomicStore
112
+ }
113
+ }