mppx 0.1.1 → 0.2.1

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 (221) hide show
  1. package/dist/Challenge.d.ts +18 -18
  2. package/dist/Challenge.d.ts.map +1 -1
  3. package/dist/Challenge.js +8 -8
  4. package/dist/Challenge.js.map +1 -1
  5. package/dist/Errors.d.ts +58 -8
  6. package/dist/Errors.d.ts.map +1 -1
  7. package/dist/Errors.js +51 -9
  8. package/dist/Errors.js.map +1 -1
  9. package/dist/Method.d.ts +154 -0
  10. package/dist/Method.d.ts.map +1 -0
  11. package/dist/Method.js +81 -0
  12. package/dist/Method.js.map +1 -0
  13. package/dist/PaymentRequest.d.ts +5 -5
  14. package/dist/PaymentRequest.d.ts.map +1 -1
  15. package/dist/PaymentRequest.js +11 -6
  16. package/dist/PaymentRequest.js.map +1 -1
  17. package/dist/cli.js +67 -18
  18. package/dist/cli.js.map +1 -1
  19. package/dist/client/Methods.d.ts +2 -2
  20. package/dist/client/Methods.d.ts.map +1 -1
  21. package/dist/client/Methods.js +2 -2
  22. package/dist/client/Methods.js.map +1 -1
  23. package/dist/client/Mppx.d.ts +7 -7
  24. package/dist/client/Mppx.d.ts.map +1 -1
  25. package/dist/client/Mppx.js +3 -3
  26. package/dist/client/Mppx.js.map +1 -1
  27. package/dist/client/internal/Fetch.d.ts +10 -10
  28. package/dist/client/internal/Fetch.d.ts.map +1 -1
  29. package/dist/client/internal/Fetch.js +2 -2
  30. package/dist/client/internal/Fetch.js.map +1 -1
  31. package/dist/index.d.ts +1 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +1 -2
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp-sdk/client/McpClient.d.ts +6 -6
  36. package/dist/mcp-sdk/client/McpClient.d.ts.map +1 -1
  37. package/dist/mcp-sdk/client/McpClient.js +4 -4
  38. package/dist/mcp-sdk/client/McpClient.js.map +1 -1
  39. package/dist/middlewares/elysia.d.ts +1 -1
  40. package/dist/middlewares/express.d.ts +1 -1
  41. package/dist/middlewares/hono.d.ts +1 -1
  42. package/dist/middlewares/internal/mppx.d.ts +7 -7
  43. package/dist/middlewares/internal/mppx.d.ts.map +1 -1
  44. package/dist/middlewares/internal/mppx.js +5 -5
  45. package/dist/middlewares/internal/mppx.js.map +1 -1
  46. package/dist/middlewares/nextjs.d.ts +1 -1
  47. package/dist/proxy/Service.js +2 -2
  48. package/dist/proxy/Service.js.map +1 -1
  49. package/dist/server/Methods.d.ts +2 -2
  50. package/dist/server/Methods.d.ts.map +1 -1
  51. package/dist/server/Methods.js +2 -2
  52. package/dist/server/Methods.js.map +1 -1
  53. package/dist/server/Mppx.d.ts +17 -17
  54. package/dist/server/Mppx.d.ts.map +1 -1
  55. package/dist/server/Mppx.js +9 -9
  56. package/dist/server/Mppx.js.map +1 -1
  57. package/dist/stripe/{Intents.d.ts → Methods.d.ts} +22 -22
  58. package/dist/stripe/Methods.d.ts.map +1 -0
  59. package/dist/stripe/Methods.js +42 -0
  60. package/dist/stripe/Methods.js.map +1 -0
  61. package/dist/stripe/client/Charge.d.ts +40 -27
  62. package/dist/stripe/client/Charge.d.ts.map +1 -1
  63. package/dist/stripe/client/Charge.js +15 -7
  64. package/dist/stripe/client/Charge.js.map +1 -1
  65. package/dist/stripe/client/{MethodIntents.d.ts → Methods.d.ts} +24 -23
  66. package/dist/stripe/client/Methods.d.ts.map +1 -0
  67. package/dist/stripe/client/{MethodIntents.js → Methods.js} +3 -3
  68. package/dist/stripe/client/Methods.js.map +1 -0
  69. package/dist/stripe/client/index.d.ts +1 -1
  70. package/dist/stripe/client/index.d.ts.map +1 -1
  71. package/dist/stripe/client/index.js +1 -1
  72. package/dist/stripe/client/index.js.map +1 -1
  73. package/dist/stripe/index.d.ts +1 -1
  74. package/dist/stripe/index.d.ts.map +1 -1
  75. package/dist/stripe/index.js +1 -1
  76. package/dist/stripe/index.js.map +1 -1
  77. package/dist/stripe/internal/types.d.ts +25 -0
  78. package/dist/stripe/internal/types.d.ts.map +1 -0
  79. package/dist/stripe/internal/types.js +2 -0
  80. package/dist/stripe/internal/types.js.map +1 -0
  81. package/dist/stripe/server/Charge.d.ts +47 -28
  82. package/dist/stripe/server/Charge.d.ts.map +1 -1
  83. package/dist/stripe/server/Charge.js +90 -32
  84. package/dist/stripe/server/Charge.js.map +1 -1
  85. package/dist/stripe/server/{MethodIntents.d.ts → Methods.d.ts} +24 -23
  86. package/dist/stripe/server/Methods.d.ts.map +1 -0
  87. package/dist/stripe/server/{MethodIntents.js → Methods.js} +3 -3
  88. package/dist/stripe/server/Methods.js.map +1 -0
  89. package/dist/stripe/server/index.d.ts +1 -1
  90. package/dist/stripe/server/index.d.ts.map +1 -1
  91. package/dist/stripe/server/index.js +1 -1
  92. package/dist/stripe/server/index.js.map +1 -1
  93. package/dist/tempo/{Intents.d.ts → Methods.d.ts} +72 -69
  94. package/dist/tempo/Methods.d.ts.map +1 -0
  95. package/dist/tempo/Methods.js +118 -0
  96. package/dist/tempo/Methods.js.map +1 -0
  97. package/dist/tempo/client/ChannelOps.d.ts +1 -1
  98. package/dist/tempo/client/ChannelOps.js +1 -1
  99. package/dist/tempo/client/Charge.d.ts +25 -25
  100. package/dist/tempo/client/Charge.d.ts.map +1 -1
  101. package/dist/tempo/client/Charge.js +3 -3
  102. package/dist/tempo/client/Charge.js.map +1 -1
  103. package/dist/tempo/client/{MethodIntents.d.ts → Methods.d.ts} +74 -70
  104. package/dist/tempo/client/Methods.d.ts.map +1 -0
  105. package/dist/tempo/client/{MethodIntents.js → Methods.js} +3 -3
  106. package/dist/tempo/client/Methods.js.map +1 -0
  107. package/dist/tempo/client/Session.d.ts +49 -45
  108. package/dist/tempo/client/Session.d.ts.map +1 -1
  109. package/dist/tempo/client/Session.js +4 -4
  110. package/dist/tempo/client/Session.js.map +1 -1
  111. package/dist/tempo/client/SessionManager.d.ts +1 -1
  112. package/dist/tempo/client/SessionManager.js +1 -1
  113. package/dist/tempo/client/index.d.ts +1 -1
  114. package/dist/tempo/client/index.d.ts.map +1 -1
  115. package/dist/tempo/client/index.js +1 -1
  116. package/dist/tempo/client/index.js.map +1 -1
  117. package/dist/tempo/index.d.ts +1 -1
  118. package/dist/tempo/index.d.ts.map +1 -1
  119. package/dist/tempo/index.js +1 -1
  120. package/dist/tempo/index.js.map +1 -1
  121. package/dist/tempo/server/Charge.d.ts +27 -27
  122. package/dist/tempo/server/Charge.d.ts.map +1 -1
  123. package/dist/tempo/server/Charge.js +3 -3
  124. package/dist/tempo/server/Charge.js.map +1 -1
  125. package/dist/tempo/server/{MethodIntents.d.ts → Methods.d.ts} +73 -69
  126. package/dist/tempo/server/Methods.d.ts.map +1 -0
  127. package/dist/tempo/server/{MethodIntents.js → Methods.js} +4 -4
  128. package/dist/tempo/server/Methods.js.map +1 -0
  129. package/dist/tempo/server/Session.d.ts +51 -47
  130. package/dist/tempo/server/Session.d.ts.map +1 -1
  131. package/dist/tempo/server/Session.js +4 -4
  132. package/dist/tempo/server/Session.js.map +1 -1
  133. package/dist/tempo/server/index.d.ts +6 -0
  134. package/dist/tempo/server/index.d.ts.map +1 -0
  135. package/dist/tempo/server/index.js +6 -0
  136. package/dist/tempo/server/index.js.map +1 -0
  137. package/package.json +2 -1
  138. package/src/Challenge.test-d.ts +3 -3
  139. package/src/Challenge.test.ts +7 -7
  140. package/src/Challenge.ts +34 -34
  141. package/src/Errors.test.ts +75 -21
  142. package/src/Errors.ts +74 -9
  143. package/src/Method.test.ts +76 -0
  144. package/src/Method.ts +228 -0
  145. package/src/PaymentRequest.test.ts +5 -5
  146. package/src/PaymentRequest.ts +15 -10
  147. package/src/cli.test.ts +12 -22
  148. package/src/cli.ts +74 -21
  149. package/src/client/Methods.ts +2 -2
  150. package/src/client/Mppx.test-d.ts +6 -6
  151. package/src/client/Mppx.test.ts +26 -22
  152. package/src/client/Mppx.ts +10 -10
  153. package/src/client/Transport.test.ts +6 -6
  154. package/src/client/internal/Fetch.ts +21 -24
  155. package/src/index.ts +1 -2
  156. package/src/mcp-sdk/client/McpClient.test.ts +1 -1
  157. package/src/mcp-sdk/client/McpClient.ts +11 -13
  158. package/src/middlewares/elysia.ts +1 -1
  159. package/src/middlewares/express.ts +1 -1
  160. package/src/middlewares/hono.ts +1 -1
  161. package/src/middlewares/internal/mppx.ts +10 -10
  162. package/src/middlewares/nextjs.ts +1 -1
  163. package/src/proxy/Service.ts +2 -2
  164. package/src/server/Methods.ts +2 -2
  165. package/src/server/Mppx.test-d.ts +27 -29
  166. package/src/server/Mppx.test.ts +23 -19
  167. package/src/server/Mppx.ts +43 -43
  168. package/src/server/Transport.test.ts +8 -8
  169. package/src/stripe/{Intents.test.ts → Methods.test.ts} +12 -12
  170. package/src/stripe/Methods.ts +45 -0
  171. package/src/stripe/client/Charge.test.ts +189 -0
  172. package/src/stripe/client/Charge.ts +29 -16
  173. package/src/stripe/client/{MethodIntents.ts → Methods.ts} +2 -2
  174. package/src/stripe/client/index.ts +1 -1
  175. package/src/stripe/index.ts +1 -1
  176. package/src/stripe/internal/types.ts +22 -0
  177. package/src/stripe/server/Charge.test.ts +241 -0
  178. package/src/stripe/server/Charge.ts +124 -38
  179. package/src/stripe/server/{MethodIntents.ts → Methods.ts} +2 -2
  180. package/src/stripe/server/index.ts +1 -1
  181. package/src/tempo/{Intents.test.ts → Methods.test.ts} +15 -15
  182. package/src/tempo/{Intents.ts → Methods.ts} +77 -22
  183. package/src/tempo/client/ChannelOps.ts +1 -1
  184. package/src/tempo/client/Charge.ts +3 -3
  185. package/src/tempo/client/{MethodIntents.ts → Methods.ts} +2 -2
  186. package/src/tempo/client/Session.ts +4 -4
  187. package/src/tempo/client/SessionManager.ts +1 -1
  188. package/src/tempo/client/index.ts +1 -1
  189. package/src/tempo/index.ts +1 -1
  190. package/src/tempo/server/Charge.ts +4 -7
  191. package/src/tempo/server/{MethodIntents.ts → Methods.ts} +3 -3
  192. package/src/tempo/server/Session.test.ts +4 -7
  193. package/src/tempo/server/Session.ts +6 -6
  194. package/src/tempo/server/index.ts +1 -1
  195. package/dist/Intent.d.ts +0 -101
  196. package/dist/Intent.d.ts.map +0 -1
  197. package/dist/Intent.js +0 -83
  198. package/dist/Intent.js.map +0 -1
  199. package/dist/MethodIntent.d.ts +0 -225
  200. package/dist/MethodIntent.d.ts.map +0 -1
  201. package/dist/MethodIntent.js +0 -156
  202. package/dist/MethodIntent.js.map +0 -1
  203. package/dist/stripe/Intents.d.ts.map +0 -1
  204. package/dist/stripe/Intents.js +0 -27
  205. package/dist/stripe/Intents.js.map +0 -1
  206. package/dist/stripe/client/MethodIntents.d.ts.map +0 -1
  207. package/dist/stripe/client/MethodIntents.js.map +0 -1
  208. package/dist/stripe/server/MethodIntents.d.ts.map +0 -1
  209. package/dist/stripe/server/MethodIntents.js.map +0 -1
  210. package/dist/tempo/Intents.d.ts.map +0 -1
  211. package/dist/tempo/Intents.js +0 -81
  212. package/dist/tempo/Intents.js.map +0 -1
  213. package/dist/tempo/client/MethodIntents.d.ts.map +0 -1
  214. package/dist/tempo/client/MethodIntents.js.map +0 -1
  215. package/dist/tempo/server/MethodIntents.d.ts.map +0 -1
  216. package/dist/tempo/server/MethodIntents.js.map +0 -1
  217. package/src/Intent.test.ts +0 -180
  218. package/src/Intent.ts +0 -109
  219. package/src/MethodIntent.test.ts +0 -303
  220. package/src/MethodIntent.ts +0 -388
  221. package/src/stripe/Intents.ts +0 -27
@@ -3,10 +3,10 @@ import type { McpError } from '@modelcontextprotocol/sdk/types.js'
3
3
  import type * as Challenge from '../../Challenge.js'
4
4
  import * as Credential from '../../Credential.js'
5
5
  import * as core_Mcp from '../../Mcp.js'
6
- import type * as MethodIntent from '../../MethodIntent.js'
6
+ import type * as Method from '../../Method.js'
7
7
  import type * as z from '../../zod.js'
8
8
 
9
- type AnyClient = MethodIntent.Client<any, any>
9
+ type AnyClient = Method.Client<any, any>
10
10
 
11
11
  /**
12
12
  * Result of a tool call with payment handling.
@@ -47,7 +47,7 @@ export type CallToolResult = Awaited<ReturnType<Client['callTool']>> & {
47
47
  */
48
48
  export function wrap<
49
49
  const client extends Pick<Client, 'callTool'>,
50
- const methods extends readonly MethodIntent.AnyClient[],
50
+ const methods extends readonly Method.AnyClient[],
51
51
  >(client: client, config: wrap.Config<methods>): wrap.McpClient<client, methods> {
52
52
  const { methods } = config
53
53
 
@@ -77,11 +77,11 @@ export function wrap<
77
77
 
78
78
  // Select first challenge that matches an installed method intent
79
79
  const challenge = challenges.find((c) =>
80
- methods.some((m) => m.method === c.method && m.name === c.intent),
80
+ methods.some((m) => m.name === c.method && m.intent === c.intent),
81
81
  )
82
82
  if (!challenge) {
83
83
  const available = challenges.map((c) => `${c.method}.${c.intent}`).join(', ')
84
- const installed = methods.map((m) => `${m.method}.${m.name}`).join(', ')
84
+ const installed = methods.map((m) => `${m.name}.${m.intent}`).join(', ')
85
85
  throw new Error(
86
86
  `No compatible payment method. Server offers: ${available}. Client has: ${installed}`,
87
87
  )
@@ -113,7 +113,7 @@ export function wrap<
113
113
 
114
114
  /** Union of all context types from all methods that have context schemas. */
115
115
  type AnyContextFor<methods extends readonly AnyClient[]> = {
116
- [key in keyof methods]: methods[key] extends MethodIntent.Client<any, infer context>
116
+ [key in keyof methods]: methods[key] extends Method.Client<any, infer context>
117
117
  ? context extends z.ZodMiniType
118
118
  ? z.input<context>
119
119
  : undefined
@@ -121,10 +121,8 @@ type AnyContextFor<methods extends readonly AnyClient[]> = {
121
121
  }[number]
122
122
 
123
123
  export declare namespace wrap {
124
- type Config<
125
- methods extends readonly MethodIntent.AnyClient[] = readonly MethodIntent.AnyClient[],
126
- > = {
127
- /** Array of method intents to use. */
124
+ type Config<methods extends readonly Method.AnyClient[] = readonly Method.AnyClient[]> = {
125
+ /** Array of methods to use. */
128
126
  methods: methods
129
127
  }
130
128
 
@@ -165,7 +163,7 @@ export function isPaymentRequiredError(
165
163
  }
166
164
 
167
165
  /** @internal */
168
- async function createCredential<methods extends readonly MethodIntent.AnyClient[]>(
166
+ async function createCredential<methods extends readonly Method.AnyClient[]>(
169
167
  challenge: Challenge.Challenge,
170
168
  config: {
171
169
  context?: unknown
@@ -174,10 +172,10 @@ async function createCredential<methods extends readonly MethodIntent.AnyClient[
174
172
  ): Promise<string> {
175
173
  const { context, methods } = config
176
174
 
177
- const mi = methods.find((m) => m.method === challenge.method && m.name === challenge.intent)
175
+ const mi = methods.find((m) => m.name === challenge.method && m.intent === challenge.intent)
178
176
  if (!mi)
179
177
  throw new Error(
180
- `No method intent found for "${challenge.method}.${challenge.intent}". Available: ${methods.map((m) => `${m.method}.${m.name}`).join(', ')}`,
178
+ `No method found for "${challenge.method}.${challenge.intent}". Available: ${methods.map((m) => `${m.name}.${m.intent}`).join(', ')}`,
181
179
  )
182
180
 
183
181
  const parsedContext = mi.context && context !== undefined ? mi.context.parse(context) : undefined
@@ -55,7 +55,7 @@ export namespace Mppx {
55
55
  * )
56
56
  * ```
57
57
  */
58
- export function payment<const intent extends Mppx_internal.AnyIntentFn>(
58
+ export function payment<const intent extends Mppx_internal.AnyMethodFn>(
59
59
  intent: intent,
60
60
  options: intent extends (options: infer options) => any ? options : never,
61
61
  ): ElysiaHook {
@@ -55,7 +55,7 @@ export namespace Mppx {
55
55
  * })
56
56
  * ```
57
57
  */
58
- export function payment<const intent extends Mppx_internal.AnyIntentFn>(
58
+ export function payment<const intent extends Mppx_internal.AnyMethodFn>(
59
59
  intent: intent,
60
60
  options: intent extends (options: infer options) => any ? options : never,
61
61
  ): RequestHandler {
@@ -49,7 +49,7 @@ export namespace Mppx {
49
49
  * )
50
50
  * ```
51
51
  */
52
- export function payment<const intent extends Mppx_internal.AnyIntentFn>(
52
+ export function payment<const intent extends Mppx_internal.AnyMethodFn>(
53
53
  intent: intent,
54
54
  options: intent extends (options: infer options) => any ? options : never,
55
55
  ): MiddlewareHandler {
@@ -1,8 +1,8 @@
1
- import type * as MethodIntent from '../../MethodIntent.js'
1
+ import type * as Method from '../../Method.js'
2
2
  import type * as Mppx from '../../server/Mppx.js'
3
3
 
4
- export type AnyIntentFn = Mppx.AnyIntentFn
5
- export type AnyServer = MethodIntent.AnyServer
4
+ export type AnyMethodFn = Mppx.AnyMethodFn
5
+ export type AnyServer = Method.AnyServer
6
6
 
7
7
  export type Wrap<mppx, handler> = {
8
8
  [key in keyof mppx]: mppx[key] extends (options: infer options) => any
@@ -11,20 +11,20 @@ export type Wrap<mppx, handler> = {
11
11
  }
12
12
 
13
13
  /**
14
- * Wraps a payment handler so each intent returns a framework-specific
15
- * handler instead of the raw intent response.
14
+ * Wraps a payment handler so each method returns a framework-specific
15
+ * handler instead of the raw method response.
16
16
  *
17
17
  * @param mppx - The payment handler created by `Mppx.create`.
18
- * @param wrapper - A function that adapts an intent function into a framework handler.
18
+ * @param wrapper - A function that adapts a method function into a framework handler.
19
19
  */
20
20
  export function wrap<mppx extends Mppx.Mppx<any, any>, handler>(
21
21
  mppx: mppx,
22
- wrapper: (intent: AnyIntentFn, options: any) => handler,
22
+ wrapper: (method: AnyMethodFn, options: any) => handler,
23
23
  ): Wrap<mppx, handler> {
24
24
  const result: Record<string, unknown> = { ...mppx }
25
- for (const mi of mppx.methods as readonly MethodIntent.AnyServer[]) {
26
- const intentFn = (mppx as any)[mi.name]
27
- result[mi.name] = (options: any) => wrapper(intentFn, options)
25
+ for (const mi of mppx.methods as readonly Method.AnyServer[]) {
26
+ const methodFn = (mppx as any)[mi.intent]
27
+ result[mi.intent] = (options: any) => wrapper(methodFn, options)
28
28
  }
29
29
  return result as never
30
30
  }
@@ -52,7 +52,7 @@ export namespace Mppx {
52
52
  * )
53
53
  * ```
54
54
  */
55
- export function payment<const intent extends Mppx_internal.AnyIntentFn>(
55
+ export function payment<const intent extends Mppx_internal.AnyMethodFn>(
56
56
  intent: intent,
57
57
  options: intent extends (options: infer options) => any ? options : never,
58
58
  handler: RouteHandler,
@@ -217,11 +217,11 @@ function resolvePayment(endpoint: Endpoint): Record<string, unknown> | null {
217
217
  if (endpoint === true) return null
218
218
  const handler = typeof endpoint === 'function' ? endpoint : endpoint.pay
219
219
  if (!('_internal' in handler)) return {}
220
- const { name, method, defaults, schema, ...rest } = handler._internal as Record<string, unknown>
220
+ const { name, intent, defaults, schema, ...rest } = handler._internal as Record<string, unknown>
221
221
  const amount = (() => {
222
222
  if (typeof rest.amount === 'string' && typeof rest.decimals === 'number')
223
223
  return String(Value.from(rest.amount, rest.decimals))
224
224
  return rest.amount
225
225
  })()
226
- return { intent: name, method, ...rest, ...(amount !== undefined && { amount }) }
226
+ return { intent, method: name, ...rest, ...(amount !== undefined && { amount }) }
227
227
  }
@@ -1,2 +1,2 @@
1
- export { stripe } from '../stripe/server/MethodIntents.js'
2
- export { tempo } from '../tempo/server/MethodIntents.js'
1
+ export { stripe } from '../stripe/server/index.js'
2
+ export { tempo } from '../tempo/server/index.js'
@@ -2,29 +2,32 @@ import { tempo } from 'mppx/server'
2
2
  import { createClient, http } from 'viem'
3
3
  import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
4
4
  import { describe, expectTypeOf, test } from 'vitest'
5
- import * as Intent from '../Intent.js'
6
- import * as MethodIntent from '../MethodIntent.js'
5
+ import * as Method from '../Method.js'
7
6
  import * as z from '../zod.js'
8
7
  import * as Mppx from './Mppx.js'
9
8
 
10
9
  const account = privateKeyToAccount(generatePrivateKey())
11
10
  const getClient = () => createClient({ account, transport: http() })
12
11
 
13
- const fooCharge = MethodIntent.fromIntent(Intent.charge, {
14
- method: 'test',
12
+ const fooCharge = Method.from({
13
+ name: 'test',
14
+ intent: 'charge',
15
15
  schema: {
16
16
  credential: {
17
17
  payload: z.object({ signature: z.string() }),
18
18
  },
19
- request: {
20
- requires: ['recipient'],
21
- },
19
+ request: z.object({
20
+ amount: z.string(),
21
+ currency: z.string(),
22
+ decimals: z.number(),
23
+ recipient: z.string(),
24
+ }),
22
25
  },
23
26
  })
24
27
 
25
28
  describe('Mppx', () => {
26
29
  test('has methods and realm properties', () => {
27
- const method = MethodIntent.toServer(fooCharge, {
30
+ const method = Method.toServer(fooCharge, {
28
31
  async verify() {
29
32
  return {
30
33
  method: 'test',
@@ -45,8 +48,8 @@ describe('Mppx', () => {
45
48
  expectTypeOf(handler.realm).toBeString()
46
49
  })
47
50
 
48
- test('has intent functions matching method intents', () => {
49
- const method = MethodIntent.toServer(fooCharge, {
51
+ test('has method functions matching methods', () => {
52
+ const method = Method.toServer(fooCharge, {
50
53
  async verify() {
51
54
  return {
52
55
  method: 'test',
@@ -66,8 +69,8 @@ describe('Mppx', () => {
66
69
  expectTypeOf(handler.charge).toBeFunction()
67
70
  })
68
71
 
69
- test('intent function options include request', () => {
70
- const method = MethodIntent.toServer(fooCharge, {
72
+ test('method function options include request', () => {
73
+ const method = Method.toServer(fooCharge, {
71
74
  async verify() {
72
75
  return {
73
76
  method: 'test',
@@ -93,8 +96,8 @@ describe('Mppx', () => {
93
96
  })
94
97
  })
95
98
 
96
- test('intent function returns handler that accepts Request', async () => {
97
- const method = MethodIntent.toServer(fooCharge, {
99
+ test('method function returns handler that accepts Request', async () => {
100
+ const method = Method.toServer(fooCharge, {
98
101
  async verify() {
99
102
  return {
100
103
  method: 'test',
@@ -128,10 +131,14 @@ describe('Mppx', () => {
128
131
  }
129
132
  })
130
133
 
131
- test('multiple method intents', () => {
132
- const authorize = Intent.from({
133
- name: 'authorize',
134
+ test('multiple methods', () => {
135
+ const fooAuthorize = Method.from({
136
+ name: 'test',
137
+ intent: 'authorize',
134
138
  schema: {
139
+ credential: {
140
+ payload: z.object({ token: z.string() }),
141
+ },
135
142
  request: z.object({
136
143
  scope: z.string(),
137
144
  duration: z.number(),
@@ -139,16 +146,7 @@ describe('Mppx', () => {
139
146
  },
140
147
  })
141
148
 
142
- const fooAuthorize = MethodIntent.fromIntent(authorize, {
143
- method: 'test',
144
- schema: {
145
- credential: {
146
- payload: z.object({ token: z.string() }),
147
- },
148
- },
149
- })
150
-
151
- const chargeMethod = MethodIntent.toServer(fooCharge, {
149
+ const chargeMethod = Method.toServer(fooCharge, {
152
150
  defaults: {
153
151
  currency: '0x1234',
154
152
  recipient: '0xabc',
@@ -163,7 +161,7 @@ describe('Mppx', () => {
163
161
  },
164
162
  })
165
163
 
166
- const authorizeMethod = MethodIntent.toServer(fooAuthorize, {
164
+ const authorizeMethod = Method.toServer(fooAuthorize, {
167
165
  async verify() {
168
166
  return {
169
167
  method: 'test',
@@ -194,7 +192,7 @@ describe('Mppx', () => {
194
192
  })
195
193
 
196
194
  describe('defaults', () => {
197
- test('defaulted fields are optional in intent options', () => {
195
+ test('defaulted fields are optional in method options', () => {
198
196
  const handler = Mppx.create({
199
197
  methods: [tempo({ currency: '0x1234', recipient: '0xabc', getClient })],
200
198
  realm: 'api.example.com',
@@ -1,4 +1,4 @@
1
- import { Challenge, Credential, Intent, MethodIntent, z } from 'mppx'
1
+ import { Challenge, Credential, Method, z } from 'mppx'
2
2
  import { Mppx, Transport, tempo } from 'mppx/server'
3
3
  import { describe, expect, test } from 'vitest'
4
4
  import * as Http from '~test/Http.js'
@@ -56,8 +56,8 @@ describe('request handler', () => {
56
56
  "detail": "Payment is required for "api.example.com".",
57
57
  "instance": "[instance]",
58
58
  "status": 402,
59
- "title": "PaymentRequiredError",
60
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/payment-required",
59
+ "title": "Payment Required",
60
+ "type": "https://paymentauth.org/problems/payment-required",
61
61
  }
62
62
  `)
63
63
  })
@@ -88,8 +88,8 @@ describe('request handler', () => {
88
88
  "detail": "Credential is malformed: Invalid base64url or JSON..",
89
89
  "instance": "[instance]",
90
90
  "status": 402,
91
- "title": "MalformedCredentialError",
92
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/malformed-credential",
91
+ "title": "Malformed Credential",
92
+ "type": "https://paymentauth.org/problems/malformed-credential",
93
93
  }
94
94
  `)
95
95
  })
@@ -132,8 +132,8 @@ describe('request handler', () => {
132
132
  "detail": "Challenge "wrong-id" is invalid: challenge was not issued by this server.",
133
133
  "instance": "[instance]",
134
134
  "status": 402,
135
- "title": "InvalidChallengeError",
136
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/invalid-challenge",
135
+ "title": "Invalid Challenge",
136
+ "type": "https://paymentauth.org/problems/invalid-challenge",
137
137
  }
138
138
  `)
139
139
  })
@@ -178,8 +178,8 @@ describe('request handler', () => {
178
178
  "detail": "[detail]",
179
179
  "instance": "[instance]",
180
180
  "status": 402,
181
- "title": "InvalidPayloadError",
182
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/invalid-payload",
181
+ "title": "Invalid Payload",
182
+ "type": "https://paymentauth.org/problems/invalid-payload",
183
183
  }
184
184
  `)
185
185
  expect(body.detail).toContain('Credential payload is invalid')
@@ -218,8 +218,8 @@ describe('request handler (node)', () => {
218
218
  "detail": "Payment is required for "api.example.com".",
219
219
  "instance": "[instance]",
220
220
  "status": 402,
221
- "title": "PaymentRequiredError",
222
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/payment-required",
221
+ "title": "Payment Required",
222
+ "type": "https://paymentauth.org/problems/payment-required",
223
223
  }
224
224
  `)
225
225
 
@@ -271,8 +271,8 @@ describe('request handler (node)', () => {
271
271
  "detail": "[detail]",
272
272
  "instance": "[instance]",
273
273
  "status": 402,
274
- "title": "VerificationFailedError",
275
- "type": "https://tempoxyz.github.io/payment-auth-spec/problems/verification-failed",
274
+ "title": "Verification Failed",
275
+ "type": "https://paymentauth.org/problems/verification-failed",
276
276
  }
277
277
  `)
278
278
  expect(body.detail).toContain('Payment verification failed')
@@ -283,19 +283,23 @@ describe('request handler (node)', () => {
283
283
 
284
284
  describe('receipt handling', () => {
285
285
  test('returns 200 when verify returns a success receipt', async () => {
286
- const mockCharge = MethodIntent.fromIntent(Intent.charge, {
287
- method: 'mock',
286
+ const mockCharge = Method.from({
287
+ name: 'mock',
288
+ intent: 'charge',
288
289
  schema: {
289
290
  credential: {
290
291
  payload: z.object({ token: z.string() }),
291
292
  },
292
- request: {
293
- requires: ['recipient'],
294
- },
293
+ request: z.object({
294
+ amount: z.string(),
295
+ currency: z.string(),
296
+ decimals: z.number(),
297
+ recipient: z.string(),
298
+ }),
295
299
  },
296
300
  })
297
301
 
298
- const mockMethod = MethodIntent.toServer(mockCharge, {
302
+ const mockMethod = Method.toServer(mockCharge, {
299
303
  async verify() {
300
304
  return {
301
305
  method: 'mock',
@@ -2,14 +2,14 @@ import type { IncomingMessage, ServerResponse } from 'node:http'
2
2
  import * as Challenge from '../Challenge.js'
3
3
  import type * as Credential from '../Credential.js'
4
4
  import * as Errors from '../Errors.js'
5
- import type * as MethodIntent from '../MethodIntent.js'
5
+ import type * as Method from '../Method.js'
6
6
  import type * as Receipt from '../Receipt.js'
7
7
  import type * as z from '../zod.js'
8
8
  import * as NodeListener from './NodeListener.js'
9
9
  import * as Request from './Request.js'
10
10
  import * as Transport from './Transport.js'
11
11
 
12
- export type Methods = readonly (MethodIntent.AnyServer | readonly MethodIntent.AnyServer[])[]
12
+ export type Methods = readonly (Method.AnyServer | readonly Method.AnyServer[])[]
13
13
 
14
14
  /**
15
15
  * Payment handler.
@@ -26,14 +26,14 @@ export type Mppx<
26
26
  transport: transport
27
27
  } & Handlers<FlattenMethods<methods>, transport>
28
28
 
29
- /** Extracts the transport override from a method intent, if any. */
29
+ /** Extracts the transport override from a method, if any. */
30
30
  type TransportOverrideOf<mi> = mi extends { transport?: infer transport }
31
31
  ? Exclude<transport, undefined> extends Transport.AnyTransport
32
32
  ? Exclude<transport, undefined>
33
33
  : never
34
34
  : never
35
35
 
36
- /** Resolves the effective transport for an intent: override if present, else global default. */
36
+ /** Resolves the effective transport for a method: override if present, else global default. */
37
37
  type EffectiveTransportOf<mi, defaultTransport extends Transport.AnyTransport> = [
38
38
  TransportOverrideOf<mi>,
39
39
  ] extends [never]
@@ -41,18 +41,18 @@ type EffectiveTransportOf<mi, defaultTransport extends Transport.AnyTransport> =
41
41
  : TransportOverrideOf<mi>
42
42
 
43
43
  type Handlers<
44
- methods extends readonly MethodIntent.AnyServer[],
44
+ methods extends readonly Method.AnyServer[],
45
45
  transport extends Transport.AnyTransport,
46
46
  > = {
47
- [intent in methods[number]['name']]: IntentFn<
48
- Extract<methods[number], { name: intent }>,
49
- EffectiveTransportOf<Extract<methods[number], { name: intent }>, transport>,
50
- NonNullable<Extract<methods[number], { name: intent }>['defaults']>
47
+ [method_name in methods[number]['intent']]: MethodFn<
48
+ Extract<methods[number], { intent: method_name }>,
49
+ EffectiveTransportOf<Extract<methods[number], { intent: method_name }>, transport>,
50
+ NonNullable<Extract<methods[number], { intent: method_name }>['defaults']>
51
51
  >
52
52
  }
53
53
 
54
54
  /**
55
- * Creates a server-side payment handler from method intents.
55
+ * Creates a server-side payment handler from methods.
56
56
  *
57
57
  * It is highly recommended to set a `secretKey` to bind challenges to their contents,
58
58
  * and allow the server to verify that incoming credentials match challenges it issued.
@@ -82,9 +82,9 @@ export function create<
82
82
  const handlers: Record<string, unknown> = {}
83
83
 
84
84
  for (const mi of methods) {
85
- handlers[mi.name] = createIntentFn({
85
+ handlers[mi.intent] = createMethodFn({
86
86
  defaults: mi.defaults,
87
- intent: mi,
87
+ method: mi,
88
88
  realm,
89
89
  request: mi.request as never,
90
90
  respond: mi.respond as never,
@@ -113,25 +113,25 @@ export declare namespace create {
113
113
  }
114
114
  }
115
115
 
116
- function createIntentFn<
117
- intent extends MethodIntent.MethodIntent,
116
+ function createMethodFn<
117
+ method extends Method.Method,
118
118
  transport extends Transport.AnyTransport,
119
119
  defaults extends Record<string, unknown>,
120
120
  >(
121
- parameters: createIntentFn.Parameters<intent, transport, defaults>,
122
- ): createIntentFn.ReturnType<intent, transport, defaults>
121
+ parameters: createMethodFn.Parameters<method, transport, defaults>,
122
+ ): createMethodFn.ReturnType<method, transport, defaults>
123
123
  // biome-ignore lint/correctness/noUnusedVariables: _
124
- function createIntentFn(parameters: createIntentFn.Parameters): createIntentFn.ReturnType {
125
- const { defaults, intent, realm, respond, secretKey, transport, verify } = parameters
124
+ function createMethodFn(parameters: createMethodFn.Parameters): createMethodFn.ReturnType {
125
+ const { defaults, method, realm, respond, secretKey, transport, verify } = parameters
126
126
 
127
127
  return (options) => {
128
128
  const meta = {
129
- ...intent,
129
+ ...method,
130
130
  ...defaults,
131
131
  ...options,
132
132
  }
133
133
  return Object.assign(
134
- async (input: Transport.InputOf): Promise<IntentFn.Response> => {
134
+ async (input: Transport.InputOf): Promise<MethodFn.Response> => {
135
135
  const { description, ...rest } = options
136
136
  const expires = 'expires' in options ? (options.expires as string | undefined) : undefined
137
137
 
@@ -160,7 +160,7 @@ function createIntentFn(parameters: createIntentFn.Parameters): createIntentFn.R
160
160
  // Recompute challenge from options. The HMAC-bound ID means we don't need to
161
161
  // store challenges server-side—if the client echoes back a credential with
162
162
  // a matching ID, we know it was issued by us with these exact parameters.
163
- const challenge = Challenge.fromIntent(intent, {
163
+ const challenge = Challenge.fromMethod(method, {
164
164
  description,
165
165
  expires,
166
166
  realm,
@@ -202,9 +202,9 @@ function createIntentFn(parameters: createIntentFn.Parameters): createIntentFn.R
202
202
  return { challenge: response, status: 402 }
203
203
  }
204
204
 
205
- // Validate payload structure against intent schema
205
+ // Validate payload structure against method schema
206
206
  try {
207
- intent.schema.credential.payload.parse(credential.payload)
207
+ method.schema.credential.payload.parse(credential.payload)
208
208
  } catch (e) {
209
209
  const response = await transport.respondChallenge({
210
210
  challenge,
@@ -265,50 +265,50 @@ function createIntentFn(parameters: createIntentFn.Parameters): createIntentFn.R
265
265
  }
266
266
  }
267
267
 
268
- declare namespace createIntentFn {
268
+ declare namespace createMethodFn {
269
269
  type Parameters<
270
- intent extends MethodIntent.MethodIntent = MethodIntent.MethodIntent,
270
+ method extends Method.Method = Method.Method,
271
271
  transport extends Transport.AnyTransport = Transport.Http,
272
272
  defaults extends Record<string, unknown> = Record<string, unknown>,
273
273
  > = {
274
274
  defaults?: defaults
275
- intent: intent
275
+ method: method
276
276
  realm: string
277
- request?: MethodIntent.RequestFn<intent>
278
- respond?: MethodIntent.RespondFn<intent>
277
+ request?: Method.RequestFn<method>
278
+ respond?: Method.RespondFn<method>
279
279
  secretKey: string
280
280
  transport: transport
281
- verify: MethodIntent.VerifyFn<intent>
281
+ verify: Method.VerifyFn<method>
282
282
  }
283
283
 
284
284
  type ReturnType<
285
- intent extends MethodIntent.MethodIntent = MethodIntent.MethodIntent,
285
+ method extends Method.Method = Method.Method,
286
286
  transport extends Transport.AnyTransport = Transport.Http,
287
287
  defaults extends Record<string, unknown> = Record<string, unknown>,
288
- > = IntentFn<intent, transport, defaults>
288
+ > = MethodFn<method, transport, defaults>
289
289
  }
290
290
 
291
- export type IntentFn<
292
- intent extends MethodIntent.MethodIntent,
291
+ export type MethodFn<
292
+ method extends Method.Method,
293
293
  transport extends Transport.AnyTransport,
294
294
  defaults extends Record<string, unknown>,
295
295
  > = (
296
- options: IntentFn.Options<intent, defaults>,
297
- ) => (input: Transport.InputOf<transport>) => Promise<IntentFn.Response<transport>>
296
+ options: MethodFn.Options<method, defaults>,
297
+ ) => (input: Transport.InputOf<transport>) => Promise<MethodFn.Response<transport>>
298
298
  /** @internal */
299
- export type AnyIntentFn = (options: any) => (input: any) => Promise<any>
299
+ export type AnyMethodFn = (options: any) => (input: any) => Promise<any>
300
300
 
301
301
  /** @internal */
302
- declare namespace IntentFn {
302
+ declare namespace MethodFn {
303
303
  export type Options<
304
- intent extends MethodIntent.MethodIntent,
304
+ method extends Method.Method,
305
305
  defaults extends Record<string, unknown> = Record<string, unknown>,
306
306
  > = {
307
307
  /** Optional human-readable description of the payment. */
308
308
  description?: string | undefined
309
309
  /** Optional challenge expiration timestamp (ISO 8601). */
310
310
  expires?: string | undefined
311
- } & MethodIntent.WithDefaults<z.input<intent['schema']['request']>, defaults>
311
+ } & Method.WithDefaults<z.input<method['schema']['request']>, defaults>
312
312
 
313
313
  export type Response<transport extends Transport.AnyTransport = Transport.Http> =
314
314
  | {
@@ -346,8 +346,8 @@ declare namespace IntentFn {
346
346
  * ```
347
347
  */
348
348
  export function toNodeListener(
349
- handler: (input: globalThis.Request) => Promise<IntentFn.Response<Transport.Http>>,
350
- ): (req: IncomingMessage, res: ServerResponse) => Promise<IntentFn.Response<Transport.Http>> {
349
+ handler: (input: globalThis.Request) => Promise<MethodFn.Response<Transport.Http>>,
350
+ ): (req: IncomingMessage, res: ServerResponse) => Promise<MethodFn.Response<Transport.Http>> {
351
351
  return async (req, res) => {
352
352
  const result = await handler(Request.fromNodeListener(req, res))
353
353
 
@@ -370,9 +370,9 @@ type FlattenMethods<methods extends Methods> = methods extends readonly [
370
370
  infer head,
371
371
  ...infer tail extends Methods,
372
372
  ]
373
- ? head extends readonly MethodIntent.AnyServer[]
373
+ ? head extends readonly Method.AnyServer[]
374
374
  ? readonly [...head, ...FlattenMethods<tail>]
375
- : head extends MethodIntent.AnyServer
375
+ : head extends Method.AnyServer
376
376
  ? readonly [head, ...FlattenMethods<tail>]
377
377
  : never
378
378
  : readonly []