@devlab.group/agent-commerce 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -71
- package/dist/ap2.d.ts +20 -23
- package/dist/ap2.js +53 -75
- package/dist/ap2.js.map +1 -1
- package/dist/authorization-BpbWGGrf.d.ts +115 -0
- package/dist/{chunk-PBYN7EK2.js → chunk-74BSEXB5.js} +10 -9
- package/dist/chunk-74BSEXB5.js.map +1 -0
- package/dist/chunk-AFI2CEZS.js +10 -0
- package/dist/chunk-AFI2CEZS.js.map +1 -0
- package/dist/{chunk-NKNXVDHN.js → chunk-ATTWSFQP.js} +45 -66
- package/dist/chunk-ATTWSFQP.js.map +1 -0
- package/dist/{chunk-5GEWKNIH.js → chunk-IVJC5YLE.js} +63 -27
- package/dist/chunk-IVJC5YLE.js.map +1 -0
- package/dist/{chunk-US622BKF.js → chunk-RAJGPGJG.js} +5 -8
- package/dist/chunk-RAJGPGJG.js.map +1 -0
- package/dist/{chunk-6D2EZ5ME.js → chunk-V2V2E7HX.js} +2 -2
- package/dist/{chunk-6D2EZ5ME.js.map → chunk-V2V2E7HX.js.map} +1 -1
- package/dist/cli/index.js +501 -494
- package/dist/cli/index.js.map +1 -1
- package/dist/{constants-6mypC60h.d.ts → constants-Bkq04FRZ.d.ts} +1 -3
- package/dist/guardrails-71XwtXlT.d.ts +31 -0
- package/dist/index.d.ts +230 -265
- package/dist/index.js +1050 -607
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +6 -59
- package/dist/mcp.js +61 -53
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +4 -4
- package/dist/mpp.js +21 -19
- package/dist/mpp.js.map +1 -1
- package/dist/protocol-adapter-DTkrXTev.d.ts +238 -0
- package/dist/runtime-CiYbgGpi.d.ts +303 -0
- package/dist/{types-CJtwLu1c.d.ts → types-O6lg3Q5V.d.ts} +17 -23
- package/dist/x402.d.ts +43 -75
- package/dist/x402.js +10 -9
- package/dist/x402.js.map +1 -1
- package/package.json +1 -1
- package/dist/authorization-DA7mjy_O.d.ts +0 -123
- package/dist/chunk-5GEWKNIH.js.map +0 -1
- package/dist/chunk-NKNXVDHN.js.map +0 -1
- package/dist/chunk-PBYN7EK2.js.map +0 -1
- package/dist/chunk-US622BKF.js.map +0 -1
- package/dist/guardrails-Dmwi63KB.d.ts +0 -38
- package/dist/protocol-adapter-APRjs1E2.d.ts +0 -273
- package/dist/runtime-DC5XQ9Cc.d.ts +0 -351
package/dist/mpp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/payments/mpp/descriptor.ts","../src/payments/mpp/provider.ts"],"names":[],"mappings":"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","file":"mpp.js","sourcesContent":["/**\n * Describes the MPP profile and its unsupported variants.\n *\n * The protocol name alone cannot identify a compatible intent, method and\n * extension set, so the descriptor lists both the target and its gaps.\n *\n * Importing the descriptor does not load `mppx`.\n */\nimport type { AdapterDescriptor } from '../../core/public-types.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport { MPP_NETWORKS, MPP_PROFILE, MPP_SUPPORTED_SPEC } from './constants.js';\n\nexport const MPP_DESCRIPTOR: AdapterDescriptor = {\n name: 'mpp',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: MPP_SUPPORTED_SPEC,\n capabilities: [\n `intent=${MPP_PROFILE.intent}`,\n `method=${MPP_PROFILE.method}`,\n `credential=${MPP_PROFILE.credentialType}`,\n 'eip-3009',\n ...MPP_NETWORKS.map((network) => `network=${network}`),\n `asset=${MPP_PROFILE.assetSymbol}`,\n 'verify-before-settle',\n 'payment-receipt',\n ],\n // The pinned specs are -00 drafts and mppx is pre-1.0, so the wire format can still change\n status: 'experimental',\n unsupported: [\n // Name other methods as a class instead of maintaining a second list\n 'methods other than evm',\n // This profile supports only the EIP-3009 `authorization` credential\n 'credential=permit2',\n 'credential=transaction',\n 'credential=hash',\n // The draft allows splits only with permit2 credentials\n 'splits',\n 'intent=subscription',\n // A separate EVM draft, not an option of charge\n 'evm sessions',\n 'discovery extension',\n ],\n};\n","/**\n * MPP payment provider for the `charge` intent, the `evm` method and the\n * EIP-3009 `authorization` credential.\n *\n * It issues challenges and verifies credentials without moving funds: local\n * checks first, then a read-only check by an x402 facilitator. Settlement hands\n * the same signed authorization to that facilitator through an internal x402\n * provider built from these options. The MPP layer adds no signing key.\n */\nimport { Challenge, Credential, Errors, Method, PaymentRequest, Receipt } from 'mppx';\nimport { Methods, type Types } from 'mppx/evm';\nimport { charge } from 'mppx/evm/server';\nimport { getAddress, isAddress } from 'viem';\nimport {\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentSubmission,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core/index.js';\nimport { parseCanonicalAmount } from '../x402/amount.js';\nimport type { X402FacilitatorConfig } from '../x402/guardrails.js';\nimport { createX402PaymentProvider } from '../x402/provider.js';\nimport { computeReplayKey } from '../x402/replay-key.js';\nimport {\n isMppNetwork,\n MPP_DEFAULT_NETWORK,\n MPP_MIN_CHALLENGE_SECRET_LENGTH,\n MPP_NETWORKS,\n MPP_PROFILE,\n MPP_SPEC_DRAFTS,\n} from './constants.js';\nimport { MPP_DESCRIPTOR } from './descriptor.js';\n\nconst DEFAULT_IDS: IdGenerator = {\n next: (prefix?: string) => `${prefix ? `${prefix}_` : ''}${crypto.randomUUID()}`,\n};\nconst DEFAULT_CHALLENGE_TTL_SECONDS = 300;\n\nexport interface MppProviderOptions {\n /** Merchant-controlled settlement destination. Never gateway-owned */\n readonly recipient: `0x${string}`;\n /** EIP-3009 token the charge is paid in */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'USDC' or 'MockUSDC' */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2' */\n readonly assetVersion: string;\n /** Value of each challenge's `realm`, such as the gateway's host */\n readonly realm: string;\n /** Key that binds each challenge to this gateway. Never logged or published */\n readonly challengeSecret: string;\n /** RPC endpoint of the settlement chain */\n readonly rpcUrl: string;\n /** The x402 facilitator that verifies and broadcasts the authorization */\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet. Never a default */\n readonly allowMainnet?: boolean;\n /** Must be `true` to settle on a mainnet through a facilitator that takes no credential */\n readonly allowUnauthenticatedFacilitator?: boolean;\n readonly logger?: Logger;\n /**\n * Seconds a challenge stays valid, 300 by default. The mppx client signs its\n * authorization to expire at the same moment.\n */\n readonly challengeTtlSeconds?: number;\n /** CAIP-2 network; accepts `eip155:84532` or `eip155:8453` and defaults to the former */\n readonly network?: string;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\n// mppx reports a verification failure only as message text. The pinned\n// release's wording maps to stable reasons, and the tests cover every entry;\n// unmapped text becomes `authorization_invalid`.\nconst VERIFICATION_REASONS: readonly (readonly [string, string])[] = [\n ['EVM authorization challenge hash mismatch', 'wrong_nonce'],\n ['EVM authorization signature mismatch', 'invalid_signature'],\n ['EVM authorization is not valid yet', 'authorization_not_yet_valid'],\n ['EVM authorization has expired', 'authorization_expired'],\n ['EVM authorization source mismatch', 'source_mismatch'],\n ['EVM authorization amount mismatch', 'wrong_amount'],\n ['EVM authorization recipient mismatch', 'wrong_recipient'],\n];\n\nfunction configInvalid(message: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message);\n}\n\ntype MppChallengeOptions = Omit<\n MppProviderOptions,\n 'rpcUrl' | 'facilitator' | 'allowMainnet' | 'allowUnauthenticatedFacilitator' | 'logger'\n>;\n\nfunction validateOptions(options: MppChallengeOptions): void {\n if (!isAddress(options.recipient)) throw configInvalid('MPP recipient is not an EVM address');\n if (!isAddress(options.asset)) throw configInvalid('MPP asset is not an EVM address');\n if (options.assetName.length === 0 || options.assetVersion.length === 0) {\n throw configInvalid('MPP asset needs its EIP-712 domain name and version');\n }\n // mppx refuses CR or LF in the quoted realm parameter, so checking here fails\n // at construction instead of on every challenge\n if (options.realm.length === 0 || /[\\r\\n]/.test(options.realm)) {\n throw configInvalid('MPP realm must be a non-empty single-line string');\n }\n if (options.challengeSecret.length < MPP_MIN_CHALLENGE_SECRET_LENGTH) {\n throw configInvalid(\n `MPP challenge secret must have length at least ${MPP_MIN_CHALLENGE_SECRET_LENGTH}`,\n );\n }\n const ttl = options.challengeTtlSeconds;\n if (ttl !== undefined && (!Number.isInteger(ttl) || ttl <= 0)) {\n throw configInvalid('MPP challenge TTL must be a positive whole number of seconds');\n }\n if (options.network !== undefined && !isMppNetwork(options.network)) {\n throw configInvalid(`MPP network must be one of ${MPP_NETWORKS.join(', ')}`);\n }\n}\n\nfunction verificationReason(error: unknown): string {\n if (error instanceof Errors.PaymentExpiredError) return 'challenge_expired';\n if (error instanceof Errors.InvalidPayloadError) return 'invalid_payload';\n if (error instanceof Errors.InvalidChallengeError) return 'invalid_challenge';\n if (error instanceof Errors.VerificationFailedError) {\n const match = VERIFICATION_REASONS.find(([text]) => error.message.includes(text));\n if (match) return match[1];\n }\n return 'authorization_invalid';\n}\n\nexport function createMppPaymentProvider(options: MppProviderOptions): PaymentProvider {\n const { rpcUrl, facilitator, allowMainnet, allowUnauthenticatedFacilitator, logger, ...rest } =\n options;\n // Checked first so a bad MPP option is reported as one, not as an x402 error\n validateOptions(rest);\n // Built from the same terms, and never registered as a rail, so an MPP-only\n // deployment needs no x402 configuration\n const settlement = createX402PaymentProvider({\n network: options.network ?? MPP_DEFAULT_NETWORK,\n rpcUrl,\n asset: options.asset,\n assetName: options.assetName,\n assetVersion: options.assetVersion,\n assetDecimals: MPP_PROFILE.assetDecimals,\n payTo: options.recipient,\n facilitator,\n ...(allowMainnet !== undefined ? { allowMainnet } : {}),\n ...(allowUnauthenticatedFacilitator !== undefined ? { allowUnauthenticatedFacilitator } : {}),\n ...(logger !== undefined ? { logger } : {}),\n ...(options.clock !== undefined ? { clock: options.clock } : {}),\n });\n return createMppProviderWithSettlement(rest, settlement);\n}\n\n/** Internal seam: tests inject a settlement provider. Not exported from the `./mpp` entry */\nexport function createMppProviderWithSettlement(\n options: MppChallengeOptions,\n settlement: PaymentProvider,\n): PaymentProvider {\n validateOptions(options);\n if (settlement.name !== 'x402') {\n throw configInvalid('MPP settlement must be an x402 payment provider');\n }\n const network = options.network ?? MPP_DEFAULT_NETWORK;\n const chainId = Number(network.split(':')[1]);\n const clock = options.clock ?? systemClock;\n const ttlSeconds = options.challengeTtlSeconds ?? DEFAULT_CHALLENGE_TTL_SECONDS;\n const recipient = getAddress(options.recipient);\n const asset = getAddress(options.asset);\n const ids = options.ids ?? DEFAULT_IDS;\n\n // charge() requires a callback even though this provider never invokes the\n // mppx broadcast path. Settlement is delegated to the x402 provider.\n const method = charge({\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n authorization: { name: options.assetName, version: options.assetVersion },\n settle: async () => {\n throw new CommerceError('INTERNAL_ERROR', 'MPP direct broadcast is disabled');\n },\n });\n\n function rejected(requirement: PaymentRequirement, reason: string): PaymentResult {\n return {\n status: 'rejected',\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n rejectionReason: reason,\n };\n }\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n if (context.currency !== MPP_PROFILE.assetSymbol) {\n throw configInvalid(\n `Resource \"${context.resource.id}\" is priced in ${context.currency}, but MPP charges ${MPP_PROFILE.assetSymbol}`,\n );\n }\n // Strict parse first: mppx converts with viem's parseUnits, which rounds\n // excess precision instead of refusing it\n if (parseCanonicalAmount(context.amount, MPP_PROFILE.assetDecimals) <= 0n) {\n throw new CommerceError('PAYMENT_INVALID', `Amount \"${context.amount}\" must be above zero`, {\n details: { amount: context.amount },\n });\n }\n // Reject a mismatched settlement requirement before the buyer signs\n await settlementRequirement(context);\n const expires = new Date(clock.now().getTime() + ttlSeconds * 1000);\n const challenge = Challenge.fromMethod(Methods.charge, {\n secretKey: options.challengeSecret,\n realm: options.realm,\n expires,\n // Bound by the challenge HMAC, so a challenge for one resource cannot pay\n // for another at the same price\n meta: { resource: context.resource.id },\n request: {\n amount: context.amount,\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n credentialTypes: [MPP_PROFILE.credentialType],\n },\n });\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'mpp',\n amount: context.amount,\n currency: context.currency,\n destination: recipient,\n network,\n asset,\n expiresAt: expires.toISOString(),\n challenge: {\n provider: 'mpp',\n version: MPP_SPEC_DRAFTS.core,\n accepts: [challenge],\n // Serialised here because the HTTP route, which sends it as\n // `WWW-Authenticate`, is in the main entry and cannot import mppx\n envelope: { wwwAuthenticate: Challenge.serialize(challenge) },\n },\n };\n }\n\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, resource, submission } = context;\n if (requirement.provider !== 'mpp' || requirement.challenge.provider !== 'mpp') {\n return rejected(requirement, 'wrong_provider');\n }\n const issued = requirement.challenge.accepts[0] as Challenge.Challenge | undefined;\n if (!issued) return rejected(requirement, 'missing_challenge');\n\n let credential: Credential.Credential;\n try {\n credential = Credential.deserialize(submission.payload);\n } catch {\n return rejected(requirement, 'malformed_credential');\n }\n const echoed = credential.challenge;\n\n // A valid HMAC means this gateway issued the challenge, not that it was\n // issued for this resource and price. The binding checks below close that gap.\n if (!Challenge.verify(echoed, { secretKey: options.challengeSecret })) {\n return rejected(requirement, 'challenge_not_issued');\n }\n const binding = bindingMismatch(echoed, issued, resource.id);\n if (binding) return rejected(requirement, binding);\n if (!echoed.expires || new Date(echoed.expires).getTime() <= clock.now().getTime()) {\n return rejected(requirement, 'challenge_expired');\n }\n if ((credential.payload as { type?: unknown } | null)?.type !== MPP_PROFILE.credentialType) {\n return rejected(requirement, 'unsupported_credential');\n }\n\n // Local checks only: signature recovery, nonce == challenge hash, the\n // validity window and payload terms. With no network call involved, any\n // failure here is a verdict on the credential, not an outage.\n let payer: `0x${string}`;\n try {\n const validation = await Method.validateCredential([method], credential);\n payer = getAddress((validation.details as { payer: string }).payer);\n } catch (error) {\n return rejected(requirement, verificationReason(error));\n }\n\n // Match x402's key so the same authorization collides across both rails\n const replayKey = computeReplayKey({\n chainId,\n asset,\n from: payer,\n // validateCredential proved it equals the 32-byte challenge hash\n nonce: (credential.payload as Types.AuthorizationPayload).nonce as `0x${string}`,\n });\n\n // The facilitator check runs before the pipeline reserves the replay key,\n // so an outage throws the x402 provider's retryable error and uses up\n // nothing, and a refusal is an ordinary rejection\n const x402Verification = await settlement.verify(await toX402Context(context));\n if (x402Verification.status !== 'verified') {\n return rejected(requirement, x402Verification.rejectionReason ?? 'settlement_rejected');\n }\n // A different key would settle an authorization the pipeline did not reserve\n if (x402Verification.replayKey !== replayKey) {\n return rejected(requirement, 'settlement_mismatch');\n }\n\n return {\n status: 'verified',\n provider: 'mpp',\n payer,\n payee: recipient,\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n replayKey,\n };\n }\n\n // The same payment as an x402 requirement and `exact` submission\n async function toX402Context(\n context: PaymentVerificationContext,\n ): Promise<PaymentVerificationContext> {\n const { requestId, requirement, resource, submission } = context;\n const x402Requirement = await settlementRequirement({\n requestId,\n resource,\n amount: requirement.amount,\n currency: requirement.currency,\n requestedAt: clock.nowIso(),\n });\n return {\n requestId,\n resource,\n requirement: x402Requirement,\n submission: toX402Submission(x402Requirement, submission),\n };\n }\n\n async function settlementRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const x402 = await settlement.createRequirement(context);\n const extra = (x402.challenge.accepts[0]?.['extra'] ?? {}) as Record<string, unknown>;\n if (\n x402.network !== network ||\n !sameAddress(x402.asset, asset) ||\n !sameAddress(x402.destination, recipient) ||\n extra['name'] !== options.assetName ||\n extra['version'] !== options.assetVersion\n ) {\n throw configInvalid(\n 'MPP settlement provider must use the same network, asset, EIP-712 domain and recipient',\n );\n }\n return x402;\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requestId, requirement, resource, submission, verification } = context;\n if (verification.status !== 'verified' || verification.replayKey === undefined) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'MPP settle() called without a successful verify()',\n );\n }\n\n // verify() already ran the facilitator check, and x402 settle checks again\n // before broadcasting. A throw may follow a broadcast, so it propagates and\n // the pipeline marks the payment uncertain.\n const settled = await settlement.settle({\n ...(await toX402Context({ requestId, requirement, resource, submission })),\n verification: { ...verification, provider: 'x402' },\n });\n const result: PaymentResult = {\n ...settled,\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n replayKey: verification.replayKey,\n };\n if (settled.status !== 'settled' || settled.externalReference === undefined) return result;\n // Serialised for the HTTP route's `Payment-Receipt` header\n const receipt = Receipt.from({\n method: MPP_PROFILE.method,\n reference: settled.externalReference,\n status: 'success',\n timestamp: settled.settledAt ?? clock.nowIso(),\n });\n return { ...result, metadata: { ...settled.metadata, receipt: Receipt.serialize(receipt) } };\n }\n\n function health(): Promise<AdapterHealth> {\n return settlement.health();\n }\n\n return { name: 'mpp', descriptor: MPP_DESCRIPTOR, createRequirement, verify, settle, health };\n}\n\n// Compares the echoed challenge with the one issued for this request. Both\n// carry a valid HMAC by now, so any difference means the credential answers a\n// challenge issued for other terms. The final comparison catches a difference\n// in any request field the named checks do not cover.\nfunction bindingMismatch(\n echoed: Challenge.Challenge,\n issued: Challenge.Challenge,\n resourceId: string,\n): string | undefined {\n if (echoed.realm !== issued.realm) return 'wrong_realm';\n if (echoed.method !== issued.method || echoed.intent !== issued.intent) {\n return 'unsupported_method';\n }\n // Only the encoded `opaque` survives the credential round trip, not `meta`,\n // so compare it with the encoding of this resource's binding\n if (echoed.opaque !== PaymentRequest.serialize({ resource: resourceId })) {\n return 'wrong_resource';\n }\n const got = echoed.request as ChargeRequest;\n const want = issued.request as ChargeRequest;\n if (got.amount !== want.amount) return 'wrong_amount';\n if (!sameAddress(got.recipient, want.recipient)) return 'wrong_recipient';\n if (got.methodDetails?.chainId !== want.methodDetails?.chainId) return 'wrong_network';\n if (!sameAddress(got.currency, want.currency)) return 'wrong_asset';\n if (canonical(got.methodDetails) !== canonical(want.methodDetails)) {\n return 'unsupported_credential';\n }\n if (canonical(got) !== canonical(want)) return 'wrong_terms';\n return undefined;\n}\n\n// Rewrap the MPP authorization as the x402 `exact` payload expected by settlement\nfunction toX402Submission(\n x402Requirement: PaymentRequirement,\n submission: PaymentSubmission,\n): PaymentSubmission {\n const { signature, from, to, value, validAfter, validBefore, nonce } = Credential.deserialize(\n submission.payload,\n ).payload as Types.AuthorizationPayload;\n const payment = {\n x402Version: 2,\n accepted: x402Requirement.challenge.accepts[0],\n payload: { signature, authorization: { from, to, value, validAfter, validBefore, nonce } },\n };\n return { method: 'x402', payload: Buffer.from(JSON.stringify(payment)).toString('base64') };\n}\n\ninterface ChargeRequest {\n readonly amount?: string;\n readonly currency?: string;\n readonly recipient?: string;\n readonly methodDetails?: { readonly chainId?: number };\n}\n\n// The encoding mppx binds into the challenge HMAC, so key order cannot\n// produce a false mismatch\nfunction canonical(value: object | undefined): string {\n return value === undefined ? '' : PaymentRequest.serialize(value as PaymentRequest.Request);\n}\n\nfunction sameAddress(a: string | undefined, b: string | undefined): boolean {\n return a !== undefined && b !== undefined && isAddress(a) && isAddress(b)\n ? getAddress(a) === getAddress(b)\n : false;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/payments/mpp/descriptor.ts","../src/payments/mpp/provider.ts"],"names":[],"mappings":"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","file":"mpp.js","sourcesContent":["/**\n * Describes the MPP profile and its unsupported variants.\n *\n * The protocol name alone cannot identify a compatible intent, method and\n * extension set, so the descriptor lists both the target and its gaps.\n *\n * Importing the descriptor does not load `mppx`.\n */\nimport type { AdapterDescriptor } from '../../core/public-types';\nimport { PACKAGE_VERSION } from '../../version';\nimport { MPP_NETWORKS, MPP_PROFILE, MPP_SUPPORTED_SPEC } from './constants';\n\nexport const MPP_DESCRIPTOR: AdapterDescriptor = {\n name: 'mpp',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: MPP_SUPPORTED_SPEC,\n capabilities: [\n `intent=${MPP_PROFILE.intent}`,\n `method=${MPP_PROFILE.method}`,\n `credential=${MPP_PROFILE.credentialType}`,\n 'eip-3009',\n ...MPP_NETWORKS.map((network) => `network=${network}`),\n `asset=${MPP_PROFILE.assetSymbol}`,\n 'verify-before-settle',\n 'payment-receipt',\n ],\n // The pinned specs are -00 drafts and mppx is pre-1.0, so the wire format can still change\n status: 'experimental',\n unsupported: [\n // Name other methods as a class instead of maintaining a second list\n 'methods other than evm',\n // This profile supports only the EIP-3009 `authorization` credential\n 'credential=permit2',\n 'credential=transaction',\n 'credential=hash',\n // The draft allows splits only with permit2 credentials\n 'splits',\n 'intent=subscription',\n // A separate EVM draft, not an option of charge\n 'evm sessions',\n 'discovery extension',\n ],\n};\n","/**\n * MPP payment provider for the `charge` intent, the `evm` method and the\n * EIP-3009 `authorization` credential.\n *\n * It issues challenges and verifies credentials without moving funds: local\n * checks first, then a read-only check by an x402 facilitator. Settlement hands\n * the same signed authorization to that facilitator through an internal x402\n * provider built from these options. The MPP layer adds no signing key.\n */\nimport { Challenge, Credential, Errors, Method, PaymentRequest, Receipt } from 'mppx';\nimport { Methods, type Types } from 'mppx/evm';\nimport { charge } from 'mppx/evm/server';\nimport { getAddress, isAddress } from 'viem';\nimport {\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentSubmission,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core';\nimport { parseCanonicalAmount } from '../x402/amount';\nimport type { X402FacilitatorConfig } from '../x402/guardrails';\nimport { createX402PaymentProvider, DEFAULT_IDS } from '../x402/provider';\nimport { computeReplayKey } from '../x402/replay-key';\nimport {\n isMppNetwork,\n MPP_DEFAULT_NETWORK,\n MPP_MIN_CHALLENGE_SECRET_LENGTH,\n MPP_NETWORKS,\n MPP_PROFILE,\n MPP_SPEC_DRAFTS,\n} from './constants';\nimport { MPP_DESCRIPTOR } from './descriptor';\n\nconst DEFAULT_CHALLENGE_TTL_SECONDS = 300;\n\nexport interface MppProviderOptions {\n /** Merchant-controlled settlement destination. Never gateway-owned */\n readonly recipient: `0x${string}`;\n /** EIP-3009 token the charge is paid in */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'USDC' or 'MockUSDC' */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2' */\n readonly assetVersion: string;\n /** Value of each challenge's `realm`, such as the gateway's host */\n readonly realm: string;\n /** Key that binds each challenge to this gateway. Never logged or published */\n readonly challengeSecret: string;\n /** RPC endpoint of the settlement chain */\n readonly rpcUrl: string;\n /** The x402 facilitator that verifies and broadcasts the authorization */\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet. Never a default */\n readonly allowMainnet?: boolean;\n /** Required on mainnet when facilitator auth is `none` */\n readonly allowUnauthenticatedFacilitator?: boolean;\n readonly logger?: Logger;\n /**\n * Seconds a challenge stays valid, 300 by default. The mppx client signs its\n * authorization to expire at the same moment.\n */\n readonly challengeTtlSeconds?: number;\n /** CAIP-2 network; accepts `eip155:84532` or `eip155:8453` and defaults to the former */\n readonly network?: string;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\n// mppx reports a verification failure only as message text. The pinned\n// release's wording maps to stable reasons, and the tests cover every entry;\n// unmapped text becomes `authorization_invalid`.\nconst VERIFICATION_REASONS: readonly (readonly [string, string])[] = [\n ['EVM authorization challenge hash mismatch', 'wrong_nonce'],\n ['EVM authorization signature mismatch', 'invalid_signature'],\n ['EVM authorization is not valid yet', 'authorization_not_yet_valid'],\n ['EVM authorization has expired', 'authorization_expired'],\n ['EVM authorization source mismatch', 'source_mismatch'],\n ['EVM authorization amount mismatch', 'wrong_amount'],\n ['EVM authorization recipient mismatch', 'wrong_recipient'],\n];\n\nfunction configInvalid(message: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message);\n}\n\ntype MppChallengeOptions = Omit<\n MppProviderOptions,\n 'rpcUrl' | 'facilitator' | 'allowMainnet' | 'allowUnauthenticatedFacilitator' | 'logger'\n>;\n\nfunction validateOptions(options: MppChallengeOptions): void {\n if (!isAddress(options.recipient)) throw configInvalid('MPP recipient is not an EVM address');\n if (!isAddress(options.asset)) throw configInvalid('MPP asset is not an EVM address');\n if (options.assetName.length === 0 || options.assetVersion.length === 0) {\n throw configInvalid('MPP asset needs its EIP-712 domain name and version');\n }\n // mppx refuses CR or LF in the quoted realm parameter, so checking here fails\n // at construction instead of on every challenge\n if (options.realm.length === 0 || /[\\r\\n]/.test(options.realm)) {\n throw configInvalid('MPP realm must be a non-empty single-line string');\n }\n if (options.challengeSecret.length < MPP_MIN_CHALLENGE_SECRET_LENGTH) {\n throw configInvalid(\n `MPP challenge secret must have length at least ${MPP_MIN_CHALLENGE_SECRET_LENGTH}`,\n );\n }\n const ttl = options.challengeTtlSeconds;\n if (ttl !== undefined && (!Number.isInteger(ttl) || ttl <= 0)) {\n throw configInvalid('MPP challenge TTL must be a positive whole number of seconds');\n }\n if (options.network !== undefined && !isMppNetwork(options.network)) {\n throw configInvalid(`MPP network must be one of ${MPP_NETWORKS.join(', ')}`);\n }\n}\n\nfunction verificationReason(error: unknown): string {\n if (error instanceof Errors.PaymentExpiredError) return 'challenge_expired';\n if (error instanceof Errors.InvalidPayloadError) return 'invalid_payload';\n if (error instanceof Errors.InvalidChallengeError) return 'invalid_challenge';\n if (error instanceof Errors.VerificationFailedError) {\n const match = VERIFICATION_REASONS.find(([text]) => error.message.includes(text));\n if (match) return match[1];\n }\n return 'authorization_invalid';\n}\n\nexport function createMppPaymentProvider(options: MppProviderOptions): PaymentProvider {\n const { rpcUrl, facilitator, allowMainnet, allowUnauthenticatedFacilitator, logger, ...rest } =\n options;\n // Checked first so a bad MPP option is reported as one, not as an x402 error\n validateOptions(rest);\n // Built from the same terms, and never registered as a rail, so an MPP-only\n // deployment needs no x402 configuration\n const settlement = createX402PaymentProvider({\n network: options.network ?? MPP_DEFAULT_NETWORK,\n rpcUrl,\n asset: options.asset,\n assetName: options.assetName,\n assetVersion: options.assetVersion,\n assetDecimals: MPP_PROFILE.assetDecimals,\n payTo: options.recipient,\n facilitator,\n ...(allowMainnet !== undefined ? { allowMainnet } : {}),\n ...(allowUnauthenticatedFacilitator !== undefined ? { allowUnauthenticatedFacilitator } : {}),\n ...(logger !== undefined ? { logger } : {}),\n ...(options.clock !== undefined ? { clock: options.clock } : {}),\n });\n return createMppProviderWithSettlement(rest, settlement);\n}\n\n/** Internal seam: tests inject a settlement provider. Not exported from the `./mpp` entry */\nexport function createMppProviderWithSettlement(\n options: MppChallengeOptions,\n settlement: PaymentProvider,\n): PaymentProvider {\n validateOptions(options);\n if (settlement.name !== 'x402') {\n throw configInvalid('MPP settlement must be an x402 payment provider');\n }\n const network = options.network ?? MPP_DEFAULT_NETWORK;\n const chainId = Number(network.split(':')[1]);\n const clock = options.clock ?? systemClock;\n const ttlSeconds = options.challengeTtlSeconds ?? DEFAULT_CHALLENGE_TTL_SECONDS;\n const recipient = getAddress(options.recipient);\n const asset = getAddress(options.asset);\n const ids = options.ids ?? DEFAULT_IDS;\n // The settlement provider's terms are fixed at construction, so one passing\n // check covers every later challenge\n let settlementTermsChecked = false;\n\n // charge() requires a callback even though this provider never invokes the\n // mppx broadcast path. Settlement is delegated to the x402 provider.\n const method = charge({\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n authorization: { name: options.assetName, version: options.assetVersion },\n settle: async () => {\n throw new CommerceError('INTERNAL_ERROR', 'MPP direct broadcast is disabled');\n },\n });\n\n function rejected(requirement: PaymentRequirement, reason: string): PaymentResult {\n return {\n status: 'rejected',\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n rejectionReason: reason,\n };\n }\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n if (context.currency !== MPP_PROFILE.assetSymbol) {\n throw configInvalid(\n `Resource \"${context.resource.id}\" is priced in ${context.currency}, but MPP charges ${MPP_PROFILE.assetSymbol}`,\n );\n }\n // Strict parse first: mppx converts with viem's parseUnits, which rounds\n // excess precision instead of refusing it\n if (parseCanonicalAmount(context.amount, MPP_PROFILE.assetDecimals) <= 0n) {\n throw new CommerceError('PAYMENT_INVALID', `Amount \"${context.amount}\" must be above zero`, {\n details: { amount: context.amount },\n });\n }\n // Reject a mismatched settlement requirement before the buyer signs\n if (!settlementTermsChecked) {\n await settlementRequirement(context);\n settlementTermsChecked = true;\n }\n const expires = new Date(clock.now().getTime() + ttlSeconds * 1000);\n const challenge = Challenge.fromMethod(Methods.charge, {\n secretKey: options.challengeSecret,\n realm: options.realm,\n expires,\n // Bound by the challenge HMAC, so a challenge for one resource cannot pay\n // for another at the same price\n meta: { resource: context.resource.id },\n request: {\n amount: context.amount,\n currency: asset,\n recipient,\n chainId,\n decimals: MPP_PROFILE.assetDecimals,\n credentialTypes: [MPP_PROFILE.credentialType],\n },\n });\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'mpp',\n amount: context.amount,\n currency: context.currency,\n destination: recipient,\n network,\n asset,\n expiresAt: expires.toISOString(),\n challenge: {\n provider: 'mpp',\n version: MPP_SPEC_DRAFTS.core,\n accepts: [challenge],\n // Serialized here because the HTTP route, which sends it as\n // `WWW-Authenticate`, is in the main entry and cannot import mppx\n envelope: { wwwAuthenticate: Challenge.serialize(challenge) },\n },\n };\n }\n\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, resource, submission } = context;\n if (requirement.provider !== 'mpp' || requirement.challenge.provider !== 'mpp') {\n return rejected(requirement, 'wrong_provider');\n }\n const issued = requirement.challenge.accepts[0] as Challenge.Challenge | undefined;\n if (!issued) return rejected(requirement, 'missing_challenge');\n\n let credential: Credential.Credential;\n try {\n credential = Credential.deserialize(submission.payload);\n } catch {\n return rejected(requirement, 'malformed_credential');\n }\n const echoed = credential.challenge;\n\n // A valid HMAC means this gateway issued the challenge, not that it was\n // issued for this resource and price. The binding checks below close that gap.\n if (!Challenge.verify(echoed, { secretKey: options.challengeSecret })) {\n return rejected(requirement, 'challenge_not_issued');\n }\n const binding = bindingMismatch(echoed, issued, resource.id);\n if (binding) return rejected(requirement, binding);\n if (!echoed.expires || new Date(echoed.expires).getTime() <= clock.now().getTime()) {\n return rejected(requirement, 'challenge_expired');\n }\n if ((credential.payload as { type?: unknown } | null)?.type !== MPP_PROFILE.credentialType) {\n return rejected(requirement, 'unsupported_credential');\n }\n\n // Local checks only: signature recovery, nonce == challenge hash, the\n // validity window and payload terms. With no network call involved, any\n // failure here is a verdict on the credential, not an outage.\n let payer: `0x${string}`;\n try {\n const validation = await Method.validateCredential([method], credential);\n payer = getAddress((validation.details as { payer: string }).payer);\n } catch (error) {\n return rejected(requirement, verificationReason(error));\n }\n\n // Match x402's key so the same authorization collides across both rails\n const replayKey = computeReplayKey({\n chainId,\n asset,\n from: payer,\n // validateCredential proved it equals the 32-byte challenge hash\n nonce: (credential.payload as Types.AuthorizationPayload).nonce as `0x${string}`,\n });\n\n // The facilitator check runs before the pipeline reserves the replay key,\n // so an outage throws the x402 provider's retryable error and uses up\n // nothing, and a refusal is an ordinary rejection\n const x402Verification = await settlement.verify(\n await toX402Context(context, credential.payload as Types.AuthorizationPayload),\n );\n if (x402Verification.status !== 'verified') {\n return rejected(requirement, x402Verification.rejectionReason ?? 'settlement_rejected');\n }\n // A different key would settle an authorization the pipeline did not reserve\n if (x402Verification.replayKey !== replayKey) {\n return rejected(requirement, 'settlement_mismatch');\n }\n\n return {\n status: 'verified',\n provider: 'mpp',\n payer,\n payee: recipient,\n amount: requirement.amount,\n currency: requirement.currency,\n network,\n asset,\n replayKey,\n };\n }\n\n // The same payment as an x402 requirement and `exact` submission\n async function toX402Context(\n context: PaymentVerificationContext,\n authorization: Types.AuthorizationPayload,\n ): Promise<PaymentVerificationContext> {\n const { requestId, requirement, resource } = context;\n const x402Requirement = await settlementRequirement({\n requestId,\n resource,\n amount: requirement.amount,\n currency: requirement.currency,\n requestedAt: clock.nowIso(),\n });\n return {\n requestId,\n resource,\n requirement: x402Requirement,\n submission: toX402Submission(x402Requirement, authorization),\n };\n }\n\n async function settlementRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const x402 = await settlement.createRequirement(context);\n const extra = (x402.challenge.accepts[0]?.['extra'] ?? {}) as Record<string, unknown>;\n if (\n x402.network !== network ||\n !sameAddress(x402.asset, asset) ||\n !sameAddress(x402.destination, recipient) ||\n extra['name'] !== options.assetName ||\n extra['version'] !== options.assetVersion\n ) {\n throw configInvalid(\n 'MPP settlement provider must use the same network, asset, EIP-712 domain and recipient',\n );\n }\n return x402;\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requestId, requirement, resource, submission, verification } = context;\n if (verification.status !== 'verified' || verification.replayKey === undefined) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'MPP settle() called without a successful verify()',\n );\n }\n\n // verify() already ran the facilitator check, and the facilitator checks\n // again before broadcasting. A throw may follow a broadcast, so it\n // propagates and the pipeline marks the payment uncertain.\n const authorization = Credential.deserialize(submission.payload)\n .payload as Types.AuthorizationPayload;\n const settled = await settlement.settle({\n ...(await toX402Context({ requestId, requirement, resource, submission }, authorization)),\n verification: { ...verification, provider: 'x402' },\n });\n const result: PaymentResult = {\n ...settled,\n provider: 'mpp',\n amount: requirement.amount,\n currency: requirement.currency,\n replayKey: verification.replayKey,\n };\n if (settled.status !== 'settled' || settled.externalReference === undefined) return result;\n // Serialized for the HTTP route's `Payment-Receipt` header\n const receipt = Receipt.from({\n method: MPP_PROFILE.method,\n reference: settled.externalReference,\n status: 'success',\n timestamp: settled.settledAt ?? clock.nowIso(),\n });\n return { ...result, metadata: { ...settled.metadata, receipt: Receipt.serialize(receipt) } };\n }\n\n function health(): Promise<AdapterHealth> {\n return settlement.health();\n }\n\n return { name: 'mpp', descriptor: MPP_DESCRIPTOR, createRequirement, verify, settle, health };\n}\n\n// Compares the echoed challenge with the one issued for this request. Both\n// carry a valid HMAC by now, so any difference means the credential answers a\n// challenge issued for other terms. The final comparison catches a difference\n// in any request field the named checks do not cover.\nfunction bindingMismatch(\n echoed: Challenge.Challenge,\n issued: Challenge.Challenge,\n resourceId: string,\n): string | undefined {\n if (echoed.realm !== issued.realm) return 'wrong_realm';\n if (echoed.method !== issued.method || echoed.intent !== issued.intent) {\n return 'unsupported_method';\n }\n // Only the encoded `opaque` survives the credential round trip, not `meta`,\n // so compare it with the encoding of this resource's binding\n if (echoed.opaque !== PaymentRequest.serialize({ resource: resourceId })) {\n return 'wrong_resource';\n }\n const got = echoed.request as ChargeRequest;\n const want = issued.request as ChargeRequest;\n if (got.amount !== want.amount) return 'wrong_amount';\n if (!sameAddress(got.recipient, want.recipient)) return 'wrong_recipient';\n if (got.methodDetails?.chainId !== want.methodDetails?.chainId) return 'wrong_network';\n if (!sameAddress(got.currency, want.currency)) return 'wrong_asset';\n if (canonical(got.methodDetails) !== canonical(want.methodDetails)) {\n return 'unsupported_credential';\n }\n if (canonical(got) !== canonical(want)) return 'wrong_terms';\n return undefined;\n}\n\n// Rewrap the MPP authorization as the x402 `exact` payload expected by settlement\nfunction toX402Submission(\n x402Requirement: PaymentRequirement,\n authorization: Types.AuthorizationPayload,\n): PaymentSubmission {\n const { signature, from, to, value, validAfter, validBefore, nonce } = authorization;\n const payment = {\n x402Version: 2,\n accepted: x402Requirement.challenge.accepts[0],\n payload: { signature, authorization: { from, to, value, validAfter, validBefore, nonce } },\n };\n return { method: 'x402', payload: Buffer.from(JSON.stringify(payment)).toString('base64') };\n}\n\ninterface ChargeRequest {\n readonly amount?: string;\n readonly currency?: string;\n readonly recipient?: string;\n readonly methodDetails?: { readonly chainId?: number };\n}\n\n// The encoding mppx binds into the challenge HMAC, so key order cannot\n// produce a false mismatch\nfunction canonical(value: object | undefined): string {\n return value === undefined ? '' : PaymentRequest.serialize(value as PaymentRequest.Request);\n}\n\nfunction sameAddress(a: string | undefined, b: string | undefined): boolean {\n return a !== undefined && b !== undefined && isAddress(a) && isAddress(b)\n ? getAddress(a) === getAddress(b)\n : false;\n}\n"]}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import { I as IsoTimestamp, n as PaymentResult, r as ProtocolName, b as PaymentSubmission, m as PaymentRequirement, A as AdapterDescriptor, R as ResourceRegistry, L as Logger, C as Clock, e as IdGenerator, c as AdapterHealth } from './runtime-CiYbgGpi.js';
|
|
3
|
+
import { d as AuthorizationRecord, b as AuthorizationSubmission, a as AuthorizationRequirement } from './authorization-BpbWGGrf.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Canonical commerce events. FROZEN CONTRACT. Every event in one flow shares
|
|
7
|
+
* one `requestId`, which correlates logs, payment attempts, backend calls and
|
|
8
|
+
* receipts.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
declare const COMMERCE_EVENT_TYPES: readonly ["resource.discovered", "resource.requested", "payment.required", "payment.rejected", "payment.verified", "payment.settled", "authorization.verified", "authorization.rejected", "backend.called", "backend.failed", "resource.delivered"];
|
|
12
|
+
type CommerceEventType = (typeof COMMERCE_EVENT_TYPES)[number];
|
|
13
|
+
interface CommerceEvent {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly type: CommerceEventType;
|
|
16
|
+
readonly requestId: string;
|
|
17
|
+
readonly resourceId?: string;
|
|
18
|
+
readonly at: IsoTimestamp;
|
|
19
|
+
/** Protocol adapter that originated the request, e.g. 'mcp' or 'http' */
|
|
20
|
+
readonly adapter?: string;
|
|
21
|
+
readonly paymentProvider?: string;
|
|
22
|
+
readonly durationMs?: number;
|
|
23
|
+
readonly status?: 'ok' | 'error';
|
|
24
|
+
/** Non-secret, structured detail. Must never contain keys, headers or proofs */
|
|
25
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Sink for canonical events. `emit` must not throw: a sink failure must never
|
|
29
|
+
* fail an otherwise successful commerce flow.
|
|
30
|
+
*/
|
|
31
|
+
interface EventSink {
|
|
32
|
+
emit(event: CommerceEvent): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface CommerceReceipt {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly requestId: string;
|
|
38
|
+
readonly resourceId: string;
|
|
39
|
+
/** Absent for free resources */
|
|
40
|
+
readonly payment?: PaymentResult;
|
|
41
|
+
/**
|
|
42
|
+
* Present only when the resource required authorization. A method and a digest,
|
|
43
|
+
* so the receipt records that consent existed without storing the proof.
|
|
44
|
+
*/
|
|
45
|
+
readonly authorization?: AuthorizationRecord;
|
|
46
|
+
readonly deliveredAt: IsoTimestamp;
|
|
47
|
+
readonly backendStatus: number;
|
|
48
|
+
readonly durationMs?: number;
|
|
49
|
+
readonly protocol?: string;
|
|
50
|
+
/** Non-secret summary only, never a sensitive backend body */
|
|
51
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
52
|
+
}
|
|
53
|
+
/** Record of a single payment authorization seen by the gateway */
|
|
54
|
+
interface PaymentAttempt {
|
|
55
|
+
readonly id: string;
|
|
56
|
+
readonly requestId: string;
|
|
57
|
+
readonly resourceId: string;
|
|
58
|
+
readonly provider: string;
|
|
59
|
+
/** Unique across the store; see `PaymentResult.replayKey` */
|
|
60
|
+
readonly replayKey: string;
|
|
61
|
+
/**
|
|
62
|
+
* State of the authorization, as far as the gateway can prove it.
|
|
63
|
+
*
|
|
64
|
+
* `settlement-uncertain` means settlement was attempted and no verdict came
|
|
65
|
+
* back (RPC timeout, dropped connection, a facilitator that accepted the
|
|
66
|
+
* transfer and lost the response). The transfer may or may not have
|
|
67
|
+
* happened, so the attempt is unresolved rather than terminal and needs
|
|
68
|
+
* evidence from the chain, not a retry. `externalReference` holds the
|
|
69
|
+
* broadcast transaction hash when one is known.
|
|
70
|
+
*
|
|
71
|
+
* The execution pipeline never writes `failed`: a throw out of `settle()`
|
|
72
|
+
* never proves that nothing moved. It stays in the union because existing
|
|
73
|
+
* databases hold rows with that status.
|
|
74
|
+
*/
|
|
75
|
+
readonly status: 'reserved' | 'verified' | 'settled' | 'rejected' | 'failed' | 'settlement-uncertain';
|
|
76
|
+
readonly amount: string;
|
|
77
|
+
readonly currency: string;
|
|
78
|
+
readonly payer?: string;
|
|
79
|
+
readonly payee?: string;
|
|
80
|
+
readonly externalReference?: string;
|
|
81
|
+
readonly rejectionReason?: string;
|
|
82
|
+
readonly createdAt: IsoTimestamp;
|
|
83
|
+
readonly updatedAt: IsoTimestamp;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Canonical request/response model for the execution pipeline.
|
|
88
|
+
*
|
|
89
|
+
* FROZEN CONTRACT. Protocol adapters normalize into `CanonicalRequest` and map
|
|
90
|
+
* `ExecutionOutcome` (or a thrown `CommerceError`) back into their own wire
|
|
91
|
+
* format. Adapters must never call merchant backends directly.
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
interface CanonicalRequest {
|
|
95
|
+
/** Correlation id for the entire flow, generated at ingress. A client never chooses it */
|
|
96
|
+
readonly requestId: string;
|
|
97
|
+
readonly resourceId: string;
|
|
98
|
+
/** Raw resource input. The pipeline validates it against the resource schema */
|
|
99
|
+
readonly input: unknown;
|
|
100
|
+
readonly protocol: ProtocolName;
|
|
101
|
+
/** Payment proof, when the client is retrying after a challenge */
|
|
102
|
+
readonly payment?: PaymentSubmission;
|
|
103
|
+
/**
|
|
104
|
+
* Authorization proof, when the resource requires one. Neither it nor
|
|
105
|
+
* `payment` substitutes for the other: a resource requiring authorization
|
|
106
|
+
* needs both.
|
|
107
|
+
*/
|
|
108
|
+
readonly authorization?: AuthorizationSubmission;
|
|
109
|
+
readonly receivedAt: IsoTimestamp;
|
|
110
|
+
/**
|
|
111
|
+
* Stable name for the side-effecting operation, when the protocol has one.
|
|
112
|
+
* Passed on as `BackendRequest.idempotencyKey`.
|
|
113
|
+
*/
|
|
114
|
+
readonly idempotencyKey?: string;
|
|
115
|
+
/** Non-secret transport metadata, such as client id or user agent */
|
|
116
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
117
|
+
}
|
|
118
|
+
/** Successful delivery of a resource */
|
|
119
|
+
interface DeliveredOutcome {
|
|
120
|
+
readonly kind: 'delivered';
|
|
121
|
+
readonly requestId: string;
|
|
122
|
+
readonly resourceId: string;
|
|
123
|
+
readonly backendStatus: number;
|
|
124
|
+
readonly body: unknown;
|
|
125
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
126
|
+
readonly payment?: PaymentResult;
|
|
127
|
+
readonly receipt: CommerceReceipt;
|
|
128
|
+
readonly durationMs: number;
|
|
129
|
+
}
|
|
130
|
+
/** The resource costs money and the request carried no payment proof */
|
|
131
|
+
interface PaymentRequiredOutcome {
|
|
132
|
+
readonly kind: 'payment-required';
|
|
133
|
+
readonly requestId: string;
|
|
134
|
+
readonly resourceId: string;
|
|
135
|
+
readonly requirement: PaymentRequirement;
|
|
136
|
+
/** Authorization the buyer must also present on the retry, when the resource requires one */
|
|
137
|
+
readonly authorization?: readonly AuthorizationRequirement[];
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Result of a pipeline execution. Every other condition (unknown resource,
|
|
141
|
+
* invalid input, rejected payment, backend or storage failure) is a thrown
|
|
142
|
+
* `CommerceError`.
|
|
143
|
+
*/
|
|
144
|
+
type ExecutionOutcome = DeliveredOutcome | PaymentRequiredOutcome;
|
|
145
|
+
/**
|
|
146
|
+
* The single execution path every protocol adapter converges on.
|
|
147
|
+
*
|
|
148
|
+
* It signals in two ways. A missing payment is a normal return value
|
|
149
|
+
* (`PaymentRequiredOutcome`): an expected protocol step whose caller reads the
|
|
150
|
+
* challenge and retries with a proof. Everything else that goes wrong,
|
|
151
|
+
* including a rejected payment, is a thrown `CommerceError`. Adapters handle
|
|
152
|
+
* both:
|
|
153
|
+
*
|
|
154
|
+
* ```ts
|
|
155
|
+
* try {
|
|
156
|
+
* const outcome = await pipeline.execute(request);
|
|
157
|
+
* if (outcome.kind === 'payment-required') return toPaymentRequiredEnvelope(outcome);
|
|
158
|
+
* return renderDelivered(outcome);
|
|
159
|
+
* } catch (error) {
|
|
160
|
+
* return toErrorEnvelope(toCommerceError(error));
|
|
161
|
+
* }
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
interface ExecutionPipeline {
|
|
165
|
+
execute(request: CanonicalRequest): Promise<ExecutionOutcome>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Protocol adapter boundary. FROZEN CONTRACT.
|
|
170
|
+
*
|
|
171
|
+
* An adapter translates a protocol's wire format into a `CanonicalRequest`,
|
|
172
|
+
* hands it to the execution pipeline and maps the outcome back. It must not
|
|
173
|
+
* call merchant backends, implement payment logic or hold its own copy of the
|
|
174
|
+
* canonical model. A failure while starting or serving one adapter must not
|
|
175
|
+
* stop the others.
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
/** Everything an adapter is given. Nothing else is available to it */
|
|
179
|
+
interface ProtocolAdapterContext {
|
|
180
|
+
readonly pipeline: ExecutionPipeline;
|
|
181
|
+
readonly resources: ResourceRegistry;
|
|
182
|
+
readonly events: EventSink;
|
|
183
|
+
readonly logger: Logger;
|
|
184
|
+
readonly clock: Clock;
|
|
185
|
+
readonly ids: IdGenerator;
|
|
186
|
+
/** Externally reachable base URL of the gateway, from config */
|
|
187
|
+
readonly publicBaseUrl: string;
|
|
188
|
+
}
|
|
189
|
+
interface ProtocolAdapter {
|
|
190
|
+
readonly name: ProtocolName;
|
|
191
|
+
readonly descriptor: AdapterDescriptor;
|
|
192
|
+
start(context: ProtocolAdapterContext): Promise<void>;
|
|
193
|
+
health(): Promise<AdapterHealth>;
|
|
194
|
+
stop(): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* A protocol adapter served over HTTP. The gateway mounts `handleHttp` at
|
|
198
|
+
* `mountPath` with raw Node request and response objects, so adapters stay
|
|
199
|
+
* independent of the HTTP framework.
|
|
200
|
+
*
|
|
201
|
+
* Guarantee: `req` arrives with its body stream unread. The gateway suppresses
|
|
202
|
+
* every body parser on the mount, so an adapter whose SDK reads the body itself
|
|
203
|
+
* (MCP's Streamable HTTP transport) can do so. The adapter owns reading,
|
|
204
|
+
* size-limiting beyond the gateway's own cap, and parsing.
|
|
205
|
+
*
|
|
206
|
+
* The guarantee can break silently. Fastify prefers its exact-match
|
|
207
|
+
* `application/json` and `text/plain` parsers over a `'*'` wildcard, so a
|
|
208
|
+
* wildcard no-op alone lets the JSON parser drain the body and the adapter
|
|
209
|
+
* reads an empty stream. The MCP conformance suite drives `handleHttp` over a
|
|
210
|
+
* bare `node:http` server and cannot catch it, so any change to adapter mounting
|
|
211
|
+
* needs a test that POSTs a JSON body through the real gateway and asserts the
|
|
212
|
+
* adapter received it intact.
|
|
213
|
+
*/
|
|
214
|
+
interface HttpProtocolAdapter extends ProtocolAdapter {
|
|
215
|
+
/** Path prefix the gateway mounts this adapter at, e.g. '/mcp' */
|
|
216
|
+
readonly mountPath: string;
|
|
217
|
+
handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
218
|
+
/**
|
|
219
|
+
* Fixed paths this adapter owns outside its mount, for protocols whose
|
|
220
|
+
* specification pins a discovery URL (A2A's `/.well-known/agent-card.json`).
|
|
221
|
+
* The gateway mounts them with the same guarantees as `mountPath`: unread
|
|
222
|
+
* body, concurrency cap and failure isolation.
|
|
223
|
+
*/
|
|
224
|
+
readonly additionalHttpRoutes?: readonly AdapterHttpRoute[];
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* One fixed, method-scoped route owned by an adapter. Unlike `mountPath` it
|
|
228
|
+
* registers no wildcard and matches exactly the path given.
|
|
229
|
+
*/
|
|
230
|
+
interface AdapterHttpRoute {
|
|
231
|
+
readonly method: 'GET' | 'POST';
|
|
232
|
+
/** Absolute gateway path, e.g. '/.well-known/agent-card.json' */
|
|
233
|
+
readonly path: string;
|
|
234
|
+
handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
235
|
+
}
|
|
236
|
+
declare function isHttpProtocolAdapter(adapter: ProtocolAdapter): adapter is HttpProtocolAdapter;
|
|
237
|
+
|
|
238
|
+
export { type AdapterHttpRoute as A, type CommerceEvent as C, type DeliveredOutcome as D, type ExecutionPipeline as E, type HttpProtocolAdapter as H, type PaymentRequiredOutcome as P, type PaymentAttempt as a, type CommerceReceipt as b, type ProtocolAdapter as c, type ProtocolAdapterContext as d, COMMERCE_EVENT_TYPES as e, type CanonicalRequest as f, type CommerceEventType as g, type EventSink as h, type ExecutionOutcome as i, isHttpProtocolAdapter as j };
|