@devlab.group/agent-commerce 2.0.0 → 2.2.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 +137 -56
- package/dist/ap2.d.ts +2 -2
- package/dist/ap2.js +4 -3
- package/dist/ap2.js.map +1 -1
- package/dist/{authorization-BpbWGGrf.d.ts → authorization-CMkIuAkO.d.ts} +1 -1
- package/dist/chunk-2CJNA7MS.js +8 -0
- package/dist/chunk-2CJNA7MS.js.map +1 -0
- package/dist/{chunk-CKJRITWY.js → chunk-5ZYXBCDX.js} +3 -3
- package/dist/{chunk-CKJRITWY.js.map → chunk-5ZYXBCDX.js.map} +1 -1
- package/dist/{chunk-3LUJHVKX.js → chunk-6Z2H53CG.js} +5 -4
- package/dist/chunk-6Z2H53CG.js.map +1 -0
- package/dist/{chunk-53WXXIPR.js → chunk-7ZMMXZ4G.js} +6 -10
- package/dist/chunk-7ZMMXZ4G.js.map +1 -0
- package/dist/{chunk-HOZA3IWP.js → chunk-ES3V6ECS.js} +16 -6
- package/dist/chunk-ES3V6ECS.js.map +1 -0
- package/dist/chunk-HNRDZLSN.js +1398 -0
- package/dist/chunk-HNRDZLSN.js.map +1 -0
- package/dist/{chunk-SYEGCNJZ.js → chunk-IEW7NSP2.js} +23 -5
- package/dist/chunk-IEW7NSP2.js.map +1 -0
- package/dist/chunk-KA2AX5FH.js +44 -0
- package/dist/chunk-KA2AX5FH.js.map +1 -0
- package/dist/chunk-Y4RE3XYF.js +581 -0
- package/dist/chunk-Y4RE3XYF.js.map +1 -0
- package/dist/cli/ap2-MBMQHFX4.js +678 -0
- package/dist/cli/ap2-MBMQHFX4.js.map +1 -0
- package/dist/cli/chunk-2ZZOGI5I.js +1352 -0
- package/dist/cli/chunk-2ZZOGI5I.js.map +1 -0
- package/dist/cli/chunk-3EQBCFZY.js +53 -0
- package/dist/cli/chunk-3EQBCFZY.js.map +1 -0
- package/dist/cli/chunk-3M6U7ILB.js +8 -0
- package/dist/cli/chunk-3M6U7ILB.js.map +1 -0
- package/dist/cli/chunk-3MGAJ5FX.js +70 -0
- package/dist/cli/chunk-3MGAJ5FX.js.map +1 -0
- package/dist/cli/chunk-5K4XEAZV.js +113 -0
- package/dist/cli/chunk-5K4XEAZV.js.map +1 -0
- package/dist/cli/chunk-7JNYFUT3.js +256 -0
- package/dist/cli/chunk-7JNYFUT3.js.map +1 -0
- package/dist/cli/chunk-AA3FIEAR.js +27 -0
- package/dist/cli/chunk-AA3FIEAR.js.map +1 -0
- package/dist/cli/chunk-FHCFR2GS.js +17 -0
- package/dist/cli/chunk-FHCFR2GS.js.map +1 -0
- package/dist/cli/chunk-FRMLWGSS.js +8 -0
- package/dist/cli/chunk-FRMLWGSS.js.map +1 -0
- package/dist/cli/chunk-KLX2YZDG.js +1400 -0
- package/dist/cli/chunk-KLX2YZDG.js.map +1 -0
- package/dist/cli/chunk-NSPPEF5M.js +334 -0
- package/dist/cli/chunk-NSPPEF5M.js.map +1 -0
- package/dist/cli/chunk-OSTCU6ZK.js +44 -0
- package/dist/cli/chunk-OSTCU6ZK.js.map +1 -0
- package/dist/cli/chunk-QQ3WY5L3.js +271 -0
- package/dist/cli/chunk-QQ3WY5L3.js.map +1 -0
- package/dist/cli/chunk-RWVPYAKC.js +1742 -0
- package/dist/cli/chunk-RWVPYAKC.js.map +1 -0
- package/dist/cli/chunk-SPAYKVUP.js +118 -0
- package/dist/cli/chunk-SPAYKVUP.js.map +1 -0
- package/dist/cli/chunk-SS3QFF5N.js +614 -0
- package/dist/cli/chunk-SS3QFF5N.js.map +1 -0
- package/dist/cli/chunk-TPC4EJLT.js +11 -0
- package/dist/cli/chunk-TPC4EJLT.js.map +1 -0
- package/dist/cli/config-4IBGVFSP.js +11 -0
- package/dist/cli/config-4IBGVFSP.js.map +1 -0
- package/dist/cli/index.js +822 -3392
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-CNWQ2MOE.js +559 -0
- package/dist/cli/mcp-CNWQ2MOE.js.map +1 -0
- package/dist/cli/near-5AY3HWYF.js +58 -0
- package/dist/cli/near-5AY3HWYF.js.map +1 -0
- package/dist/cli/provider-4BQDH56Y.js +396 -0
- package/dist/cli/provider-4BQDH56Y.js.map +1 -0
- package/dist/cli/run-5MB2D45X.js +7286 -0
- package/dist/cli/run-5MB2D45X.js.map +1 -0
- package/dist/cli/svm-3MMYFPC7.js +33 -0
- package/dist/cli/svm-3MMYFPC7.js.map +1 -0
- package/dist/cli/x402-NKR3WQDQ.js +96 -0
- package/dist/cli/x402-NKR3WQDQ.js.map +1 -0
- package/dist/{constants-BSBRlKRR.d.ts → constants-nackLItD.d.ts} +2 -1
- package/dist/index.d.ts +61 -40
- package/dist/index.js +2642 -2205
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +3 -3
- package/dist/mcp.js +15 -20
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +12 -5
- package/dist/mpp.js +69 -65
- package/dist/mpp.js.map +1 -1
- package/dist/near-D6C42VPE.js +58 -0
- package/dist/near-D6C42VPE.js.map +1 -0
- package/dist/networks-olfflCI_.d.ts +38 -0
- package/dist/{protocol-adapter-DonxfAwa.d.ts → protocol-adapter-CfxU8Z2T.d.ts} +2 -2
- package/dist/{runtime-CiYbgGpi.d.ts → runtime-7vLNYvmU.d.ts} +25 -3
- package/dist/svm-QEUAUNPQ.js +33 -0
- package/dist/svm-QEUAUNPQ.js.map +1 -0
- package/dist/x402.d.ts +76 -64
- package/dist/x402.js +13 -4
- package/dist/x402.js.map +1 -1
- package/package.json +22 -2
- package/dist/chunk-3LUJHVKX.js.map +0 -1
- package/dist/chunk-53WXXIPR.js.map +0 -1
- package/dist/chunk-HOZA3IWP.js.map +0 -1
- package/dist/chunk-RKBGCPCK.js +0 -733
- package/dist/chunk-RKBGCPCK.js.map +0 -1
- package/dist/chunk-SYEGCNJZ.js.map +0 -1
- package/dist/chunk-TWRUNWDR.js +0 -265
- package/dist/chunk-TWRUNWDR.js.map +0 -1
- package/dist/{payment-flow-DCS882tR.d.ts → guardrails-CX_jYXvZ.d.ts} +8 -8
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';\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 'authorization-flow',\n 'upfront-flow',\n 'payment-receipt',\n // HTTP request bodies only; MCP and A2A carry the proof in the body\n 'challenge-digest-binding',\n ],\n // The pinned specs are drafts and mppx is pre-1.0; the wire format may 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 *\n * Settlement follows a successful backend call unless the payment flow is\n * `upfront`. The drafts require a confirmed transaction before a\n * `Payment-Receipt`, not before the backend runs.\n */\nimport { Challenge, Credential, Errors, Method, PaymentRequest, Receipt } from 'mppx';\nimport { Methods, type Types } from 'mppx/evm';\nimport { charge } from 'mppx/evm/server';\nimport { createPublicClient, getAddress, http, isAddress, parseAbi } 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 { SETTLE_AFTER_BACKEND_METADATA_KEY } from '../../core/execution/settlement-order';\nimport { parseCanonicalAmount } from '../x402/amount';\nimport type { X402FacilitatorConfig } from '../x402/guardrails';\nimport { X402_DEFAULT_PAYMENT_FLOW, type X402PaymentFlow } from '../x402/payment-flow';\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';\nimport { CONTENT_DIGEST_METADATA_KEY } from './transport';\n\nconst DEFAULT_CHALLENGE_TTL_SECONDS = 300;\n\n// The x402 SDK's verify reason for an EIP-3009 nonce already spent on chain\nconst NONCE_ALREADY_USED = 'invalid_exact_evm_nonce_already_used';\n\nconst AUTHORIZATION_STATE_ABI = parseAbi([\n 'function authorizationState(address authorizer, bytes32 nonce) view returns (bool)',\n]);\nconst NONCE_READ_TIMEOUT_MS = 5_000;\n\n/** Whether the token contract has recorded `nonce` as used by `payer` */\nexport type NonceUsedReader = (payer: `0x${string}`, nonce: `0x${string}`) => Promise<boolean>;\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 /** Same flow values as x402; `authorization` settles after the backend */\n readonly paymentFlow?: X402PaymentFlow;\n /** Per-resource overrides of `paymentFlow`, keyed by resource id */\n readonly resourcePaymentFlows?: Readonly<Record<string, X402PaymentFlow>>;\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 // One attempt: the read only names the reason for a refusal already decided\n const chain = createPublicClient({\n transport: http(rpcUrl, { timeout: NONCE_READ_TIMEOUT_MS, retryCount: 0 }),\n });\n const nonceUsed: NonceUsedReader = (payer, nonce) =>\n chain.readContract({\n address: options.asset,\n abi: AUTHORIZATION_STATE_ABI,\n functionName: 'authorizationState',\n args: [payer, nonce],\n });\n return createMppProviderWithSettlement(rest, settlement, nonceUsed);\n}\n\n/**\n * Internal seam: tests inject a settlement provider and the nonce reader. Not\n * exported from the `./mpp` entry.\n */\nexport function createMppProviderWithSettlement(\n options: MppChallengeOptions,\n settlement: PaymentProvider,\n nonceUsed?: NonceUsedReader,\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 paymentFlow =\n options.resourcePaymentFlows?.[context.resource.id] ??\n options.paymentFlow ??\n X402_DEFAULT_PAYMENT_FLOW;\n // mppx signs `validBefore` at this expiry. Under `authorization`, the\n // backend must finish before then for settlement to proceed.\n const expires = new Date(clock.now().getTime() + ttlSeconds * 1000);\n const digest = context.metadata?.[CONTENT_DIGEST_METADATA_KEY];\n const challenge = Challenge.fromMethod(Methods.charge, {\n secretKey: options.challengeSecret,\n realm: options.realm,\n expires,\n // Present for an HTTP request with a body. MCP and A2A carry the proof\n // in the body itself, so their challenges bind none.\n ...(typeof digest === 'string' ? { digest } : {}),\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 // Build both carrier forms here because the HTTP route and MCP\n // adapter cannot import mppx: a header value for HTTP and challenge\n // objects for MCP\n envelope: { wwwAuthenticate: Challenge.serialize(challenge), challenges: [challenge] },\n },\n metadata: { [SETTLE_AFTER_BACKEND_METADATA_KEY]: paymentFlow === 'authorization' },\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 = decodeCredential(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 // validateCredential proved it equals the 32-byte challenge hash\n const nonce = (credential.payload as Types.AuthorizationPayload).nonce as `0x${string}`;\n // Match x402's key so the same authorization collides across both rails\n const replayKey = computeReplayKey({ chainId, asset, from: payer, nonce });\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 // A spent challenge-hash nonce means the challenge was used. Check\n // the token when the facilitator reports only a simulation failure;\n // keep its reason if the token read fails.\n const reason = x402Verification.rejectionReason;\n const spent =\n reason === NONCE_ALREADY_USED ||\n ((await nonceUsed?.(payer, nonce).catch(() => false)) ?? false);\n return rejected(\n requirement,\n spent ? 'challenge_already_used' : (reason ?? 'settlement_rejected'),\n );\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 credential = decodeCredential(submission.payload);\n const authorization = credential.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 // Include the EVM method's `challengeId` and `chainId` in the receipt\n // sent through the HTTP `Payment-Receipt` header\n const fields: Receipt.Receipt & { challengeId: string; chainId: number } = {\n method: MPP_PROFILE.method,\n reference: settled.externalReference,\n status: 'success',\n timestamp: settled.settledAt ?? clock.nowIso(),\n challengeId: credential.challenge.id,\n chainId,\n };\n const receipt = Receipt.from(fields);\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// Accept the HTTP `Authorization: Payment ...` value or a JSON credential\n// from MCP `_meta`. Serialize the object for mppx deserialization\nfunction decodeCredential(payload: string): Credential.Credential {\n const serialized = payload.trimStart().startsWith('{')\n ? Credential.serialize(JSON.parse(payload) as Credential.Credential)\n : payload;\n return Credential.deserialize(serialized);\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 // `issued` was built for the request carrying this credential, so a\n // different body, or none, fails here. A challenge without a digest binds\n // no body, as the core draft reads it.\n if (echoed.digest !== undefined && echoed.digest !== issued.digest) {\n return 'body_digest_mismatch';\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/payments/mpp/descriptor.ts","../src/payments/mpp/credential.ts","../src/payments/mpp/options.ts","../src/payments/mpp/provider.ts"],"names":["isAddress","getAddress"],"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 'authorization-flow',\n 'upfront-flow',\n 'payment-receipt',\n // HTTP request bodies only; MCP and A2A carry the proof in the body\n 'challenge-digest-binding',\n ],\n // The pinned specs are drafts and mppx is pre-1.0; the wire format may 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","// Reading an MPP credential: its decoding, its binding to the challenge, and the x402 proof it carries\nimport { type Challenge, Credential, Errors, PaymentRequest } from 'mppx';\nimport type { Types } from 'mppx/evm';\nimport { getAddress, isAddress } from 'viem';\nimport type { PaymentRequirement, PaymentSubmission } from '../../core';\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\nexport function 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\n// Accept the HTTP `Authorization: Payment ...` value or a JSON credential\n// from MCP `_meta`. Serialize the object for mppx deserialization\nexport function decodeCredential(payload: string): Credential.Credential {\n const serialized = payload.trimStart().startsWith('{')\n ? Credential.serialize(JSON.parse(payload) as Credential.Credential)\n : payload;\n return Credential.deserialize(serialized);\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.\nexport function 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 // `issued` was built for the request carrying this credential, so a\n // different body, or none, fails here. A challenge without a digest binds\n // no body, as the core draft reads it.\n if (echoed.digest !== undefined && echoed.digest !== issued.digest) {\n return 'body_digest_mismatch';\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\nexport function 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\nexport function 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","// The MPP provider's options, checked once at construction\nimport { isAddress } from 'viem';\nimport { type Clock, CommerceError, type IdGenerator, type Logger } from '../../core';\nimport type { X402FacilitatorConfig } from '../x402/guardrails';\nimport type { X402PaymentFlow } from '../x402/payment-flow';\nimport { isMppNetwork, MPP_MIN_CHALLENGE_SECRET_LENGTH, MPP_NETWORKS } from './constants';\n\n/** Whether the token contract has recorded `nonce` as used by `payer` */\nexport type NonceUsedReader = (payer: `0x${string}`, nonce: `0x${string}`) => Promise<boolean>;\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 /**\n * CAIP-2 network: `eip155:31337` (local Anvil), `eip155:84532` (Base\n * Sepolia, the default) or `eip155:8453` (Base)\n */\n readonly network?: string;\n /**\n * Same flow values as x402. The default, `upfront`, settles before the\n * backend; `authorization` settles after it\n */\n readonly paymentFlow?: X402PaymentFlow;\n /** Per-resource overrides of `paymentFlow`, keyed by resource id */\n readonly resourcePaymentFlows?: Readonly<Record<string, X402PaymentFlow>>;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\nexport function configInvalid(message: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message);\n}\n\nexport type MppChallengeOptions = Omit<\n MppProviderOptions,\n 'rpcUrl' | 'facilitator' | 'allowMainnet' | 'allowUnauthenticatedFacilitator' | 'logger'\n>;\n\nexport function 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","/**\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 *\n * Under the default `upfront` flow settlement precedes the backend call; under\n * `authorization` it follows a successful one. The drafts require a confirmed\n * transaction before a `Payment-Receipt`.\n */\nimport { Challenge, type Credential, Method, Receipt } from 'mppx';\nimport { Methods, type Types } from 'mppx/evm';\nimport { charge } from 'mppx/evm/server';\nimport { createPublicClient, getAddress, http, parseAbi } from 'viem';\nimport {\n type AdapterHealth,\n CommerceError,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core';\nimport { SETTLE_AFTER_BACKEND_METADATA_KEY } from '../../core/execution/settlement-order';\nimport { parseCanonicalAmount } from '../x402/amount';\nimport { createX402PaymentProvider, DEFAULT_IDS } from '../x402/provider';\nimport { computeReplayKey } from '../x402/replay-key';\nimport {\n MPP_DEFAULT_NETWORK,\n MPP_DEFAULT_PAYMENT_FLOW,\n MPP_PROFILE,\n MPP_SPEC_DRAFTS,\n} from './constants';\nimport {\n bindingMismatch,\n decodeCredential,\n sameAddress,\n toX402Submission,\n verificationReason,\n} from './credential';\nimport { MPP_DESCRIPTOR } from './descriptor';\nimport {\n configInvalid,\n type MppChallengeOptions,\n type MppProviderOptions,\n type NonceUsedReader,\n validateOptions,\n} from './options';\nimport { CONTENT_DIGEST_METADATA_KEY } from './transport';\n\nconst DEFAULT_CHALLENGE_TTL_SECONDS = 300;\n\n// The x402 SDK's verify reason for an EIP-3009 nonce already spent on chain\nconst NONCE_ALREADY_USED = 'invalid_exact_evm_nonce_already_used';\n\nconst AUTHORIZATION_STATE_ABI = parseAbi([\n 'function authorizationState(address authorizer, bytes32 nonce) view returns (bool)',\n]);\n\nconst NONCE_READ_TIMEOUT_MS = 5_000;\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 // One attempt: the read only names the reason for a refusal already decided\n const chain = createPublicClient({\n transport: http(rpcUrl, { timeout: NONCE_READ_TIMEOUT_MS, retryCount: 0 }),\n });\n const nonceUsed: NonceUsedReader = (payer, nonce) =>\n chain.readContract({\n address: options.asset,\n abi: AUTHORIZATION_STATE_ABI,\n functionName: 'authorizationState',\n args: [payer, nonce],\n });\n return createMppProviderWithSettlement(rest, settlement, nonceUsed);\n}\n\n/**\n * Internal seam: tests inject a settlement provider and the nonce reader. Not\n * exported from the `./mpp` entry.\n */\nexport function createMppProviderWithSettlement(\n options: MppChallengeOptions,\n settlement: PaymentProvider,\n nonceUsed?: NonceUsedReader,\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 paymentFlow =\n options.resourcePaymentFlows?.[context.resource.id] ??\n options.paymentFlow ??\n MPP_DEFAULT_PAYMENT_FLOW;\n // mppx signs `validBefore` at this expiry. Under `authorization`, the\n // backend must finish before then for settlement to proceed.\n const expires = new Date(clock.now().getTime() + ttlSeconds * 1000);\n const digest = context.metadata?.[CONTENT_DIGEST_METADATA_KEY];\n const challenge = Challenge.fromMethod(Methods.charge, {\n secretKey: options.challengeSecret,\n realm: options.realm,\n expires,\n // Present for an HTTP request with a body. MCP and A2A carry the proof\n // in the body itself, so their challenges bind none.\n ...(typeof digest === 'string' ? { digest } : {}),\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 // Build both carrier forms here because the HTTP route and MCP\n // adapter cannot import mppx: a header value for HTTP and challenge\n // objects for MCP\n envelope: { wwwAuthenticate: Challenge.serialize(challenge), challenges: [challenge] },\n },\n metadata: { [SETTLE_AFTER_BACKEND_METADATA_KEY]: paymentFlow === 'authorization' },\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 = decodeCredential(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 // validateCredential proved it equals the 32-byte challenge hash\n const nonce = (credential.payload as Types.AuthorizationPayload).nonce as `0x${string}`;\n // Match x402's key so the same authorization collides across both rails\n const replayKey = computeReplayKey({ chainId, asset, from: payer, nonce });\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 // A spent challenge-hash nonce means the challenge was used. Check\n // the token when the facilitator reports only a simulation failure;\n // keep its reason if the token read fails.\n const reason = x402Verification.rejectionReason;\n const spent =\n reason === NONCE_ALREADY_USED ||\n ((await nonceUsed?.(payer, nonce).catch(() => false)) ?? false);\n return rejected(\n requirement,\n spent ? 'challenge_already_used' : (reason ?? 'settlement_rejected'),\n );\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 credential = decodeCredential(submission.payload);\n const authorization = credential.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 // Include the EVM method's `challengeId` and `chainId` in the receipt\n // sent through the HTTP `Payment-Receipt` header\n const fields: Receipt.Receipt & { challengeId: string; chainId: number } = {\n method: MPP_PROFILE.method,\n reference: settled.externalReference,\n status: 'success',\n timestamp: settled.settledAt ?? clock.nowIso(),\n challengeId: credential.challenge.id,\n chainId,\n };\n const receipt = Receipt.from(fields);\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\nexport type { MppProviderOptions, NonceUsedReader } from './options';\n"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { computeNearReplayKey } from './chunk-KA2AX5FH.js';
|
|
2
|
+
import { isRecord } from './chunk-2CJNA7MS.js';
|
|
3
|
+
import { decodeSignedDelegateB64, parseFtTransferArgs } from '@x402/near';
|
|
4
|
+
|
|
5
|
+
var MAX_SIGNED_DELEGATE_BASE64 = 4096;
|
|
6
|
+
var ONE_YOCTO = 1n;
|
|
7
|
+
function inspectNearPayload(payload, terms) {
|
|
8
|
+
const encoded = isRecord(payload) ? payload["signedDelegateAction"] : void 0;
|
|
9
|
+
if (typeof encoded !== "string" || encoded.length > MAX_SIGNED_DELEGATE_BASE64) {
|
|
10
|
+
return "invalid_exact_near_payload_shape";
|
|
11
|
+
}
|
|
12
|
+
let delegate;
|
|
13
|
+
try {
|
|
14
|
+
delegate = decodeSignedDelegateB64(encoded).delegate;
|
|
15
|
+
} catch {
|
|
16
|
+
return "invalid_exact_near_payload_signed_delegate_action";
|
|
17
|
+
}
|
|
18
|
+
if (!isCanonical(encoded)) return "invalid_exact_near_payload_signed_delegate_action";
|
|
19
|
+
if (delegate.actionCount !== 1) return "invalid_exact_near_payload_action_count";
|
|
20
|
+
const call = delegate.functionCall;
|
|
21
|
+
if (!call) return "invalid_exact_near_payload_action_kind";
|
|
22
|
+
if (call.methodName !== "ft_transfer") return "invalid_exact_near_payload_method_name";
|
|
23
|
+
if (delegate.receiverId !== terms.asset) {
|
|
24
|
+
return "invalid_exact_near_payload_token_contract_mismatch";
|
|
25
|
+
}
|
|
26
|
+
let args;
|
|
27
|
+
try {
|
|
28
|
+
args = parseFtTransferArgs(call.args);
|
|
29
|
+
} catch {
|
|
30
|
+
return "invalid_exact_near_payload_ft_transfer_args";
|
|
31
|
+
}
|
|
32
|
+
if (args.receiver_id !== terms.payTo) return "invalid_exact_near_payload_recipient_mismatch";
|
|
33
|
+
if (args.amount !== terms.amount) return "invalid_exact_near_payload_amount_mismatch";
|
|
34
|
+
if (call.deposit !== ONE_YOCTO) return "invalid_exact_near_payload_attached_deposit";
|
|
35
|
+
return {
|
|
36
|
+
payer: delegate.senderId,
|
|
37
|
+
replayKey: computeNearReplayKey({
|
|
38
|
+
network: terms.network,
|
|
39
|
+
senderId: delegate.senderId,
|
|
40
|
+
publicKey: delegate.publicKey,
|
|
41
|
+
nonce: delegate.nonce
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function isCanonical(encoded) {
|
|
46
|
+
const bytes = Buffer.from(encoded, "base64");
|
|
47
|
+
if (bytes.toString("base64") !== encoded) return false;
|
|
48
|
+
try {
|
|
49
|
+
decodeSignedDelegateB64(bytes.subarray(0, bytes.length - 1).toString("base64"));
|
|
50
|
+
return false;
|
|
51
|
+
} catch {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export { inspectNearPayload };
|
|
57
|
+
//# sourceMappingURL=near-D6C42VPE.js.map
|
|
58
|
+
//# sourceMappingURL=near-D6C42VPE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payments/x402/near.ts"],"names":[],"mappings":";;;;AAeA,IAAM,0BAAA,GAA6B,IAAA;AAEnC,IAAM,SAAA,GAAY,EAAA;AAeX,SAAS,kBAAA,CACd,SACA,KAAA,EACiE;AACjE,EAAA,MAAM,UAAU,QAAA,CAAS,OAAO,CAAA,GAAI,OAAA,CAAQ,sBAAsB,CAAA,GAAI,MAAA;AACtE,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,CAAQ,SAAS,0BAAA,EAA4B;AAC9E,IAAA,OAAO,kCAAA;AAAA,EACT;AACA,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,uBAAA,CAAwB,OAAO,CAAA,CAAE,QAAA;AAAA,EAC9C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,mDAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,WAAA,CAAY,OAAO,CAAA,EAAG,OAAO,mDAAA;AAClC,EAAA,IAAI,QAAA,CAAS,WAAA,KAAgB,CAAA,EAAG,OAAO,yCAAA;AACvC,EAAA,MAAM,OAAO,QAAA,CAAS,YAAA;AACtB,EAAA,IAAI,CAAC,MAAM,OAAO,wCAAA;AAClB,EAAA,IAAI,IAAA,CAAK,UAAA,KAAe,aAAA,EAAe,OAAO,wCAAA;AAC9C,EAAA,IAAI,QAAA,CAAS,UAAA,KAAe,KAAA,CAAM,KAAA,EAAO;AACvC,IAAA,OAAO,oDAAA;AAAA,EACT;AACA,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,mBAAA,CAAoB,KAAK,IAAI,CAAA;AAAA,EACtC,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,6CAAA;AAAA,EACT;AACA,EAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,KAAA,CAAM,KAAA,EAAO,OAAO,+CAAA;AAC7C,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,KAAA,CAAM,MAAA,EAAQ,OAAO,4CAAA;AACzC,EAAA,IAAI,IAAA,CAAK,OAAA,KAAY,SAAA,EAAW,OAAO,6CAAA;AACvC,EAAA,OAAO;AAAA,IACL,OAAO,QAAA,CAAS,QAAA;AAAA,IAChB,WAAW,oBAAA,CAAqB;AAAA,MAC9B,SAAS,KAAA,CAAM,OAAA;AAAA,MACf,UAAU,QAAA,CAAS,QAAA;AAAA,MACnB,WAAW,QAAA,CAAS,SAAA;AAAA,MACpB,OAAO,QAAA,CAAS;AAAA,KACjB;AAAA,GACH;AACF;AAOA,SAAS,YAAY,OAAA,EAA0B;AAC7C,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAC3C,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,QAAQ,CAAA,KAAM,SAAS,OAAO,KAAA;AACjD,EAAA,IAAI;AACF,IAAA,uBAAA,CAAwB,KAAA,CAAM,SAAS,CAAA,EAAG,KAAA,CAAM,SAAS,CAAC,CAAA,CAAE,QAAA,CAAS,QAAQ,CAAC,CAAA;AAC9E,IAAA,OAAO,KAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF","file":"near-D6C42VPE.js","sourcesContent":["/**\n * NEAR `exact` payload inspection: bounded decoding of the NEP-366 signed\n * delegate action, the transfer it authorizes and its replay identity. The\n * provider loads this module only for a NEAR offer, so other deployments never\n * import `@x402/near`.\n *\n * The facilitator checks the signature, the access key and its nonce, the\n * delegate window and chain state. The gateway checks the transfer the buyer\n * signed against the offer, so a proof for other terms never reaches it.\n */\nimport { decodeSignedDelegateB64, parseFtTransferArgs } from '@x402/near';\nimport { isRecord } from '../../core/is-record';\nimport { computeNearReplayKey } from './replay-key';\n\n// One `ft_transfer` delegate is a few hundred bytes; this bounds the decoder\nconst MAX_SIGNED_DELEGATE_BASE64 = 4096;\n// NEP-141 requires exactly one yoctoNEAR on `ft_transfer`\nconst ONE_YOCTO = 1n;\n\nexport interface NearTransferTerms {\n readonly network: string;\n /** The NEP-141 token contract the delegate must call */\n readonly asset: string;\n readonly payTo: string;\n /** Atomic units, as the offer states them */\n readonly amount: string;\n}\n\n/**\n * Returns the payer and replay key if the NEAR `exact` payload matches the\n * offer, or a refusal reason using the SDK facilitator's codes.\n */\nexport function inspectNearPayload(\n payload: unknown,\n terms: NearTransferTerms,\n): { readonly payer: string; readonly replayKey: string } | string {\n const encoded = isRecord(payload) ? payload['signedDelegateAction'] : undefined;\n if (typeof encoded !== 'string' || encoded.length > MAX_SIGNED_DELEGATE_BASE64) {\n return 'invalid_exact_near_payload_shape';\n }\n let delegate: ReturnType<typeof decodeSignedDelegateB64>['delegate'];\n try {\n delegate = decodeSignedDelegateB64(encoded).delegate;\n } catch {\n return 'invalid_exact_near_payload_signed_delegate_action';\n }\n if (!isCanonical(encoded)) return 'invalid_exact_near_payload_signed_delegate_action';\n if (delegate.actionCount !== 1) return 'invalid_exact_near_payload_action_count';\n const call = delegate.functionCall;\n if (!call) return 'invalid_exact_near_payload_action_kind';\n if (call.methodName !== 'ft_transfer') return 'invalid_exact_near_payload_method_name';\n if (delegate.receiverId !== terms.asset) {\n return 'invalid_exact_near_payload_token_contract_mismatch';\n }\n let args: ReturnType<typeof parseFtTransferArgs>;\n try {\n args = parseFtTransferArgs(call.args);\n } catch {\n return 'invalid_exact_near_payload_ft_transfer_args';\n }\n if (args.receiver_id !== terms.payTo) return 'invalid_exact_near_payload_recipient_mismatch';\n if (args.amount !== terms.amount) return 'invalid_exact_near_payload_amount_mismatch';\n if (call.deposit !== ONE_YOCTO) return 'invalid_exact_near_payload_attached_deposit';\n return {\n payer: delegate.senderId,\n replayKey: computeNearReplayKey({\n network: terms.network,\n senderId: delegate.senderId,\n publicKey: delegate.publicKey,\n nonce: delegate.nonce,\n }),\n };\n}\n\n/**\n * One delegate, one encoding: canonical base64, and no bytes after the signed\n * delegate. The SDK decoder ignores such bytes, so the check decodes the\n * payload without its last byte: a canonical encoding then runs short.\n */\nfunction isCanonical(encoded: string): boolean {\n const bytes = Buffer.from(encoded, 'base64');\n if (bytes.toString('base64') !== encoded) return false;\n try {\n decodeSignedDelegateB64(bytes.subarray(0, bytes.length - 1).toString('base64'));\n return false;\n } catch {\n return true;\n }\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
type NetworkKind = 'testnet' | 'mainnet';
|
|
2
|
+
/** An EVM network the x402 provider can settle on */
|
|
3
|
+
interface NetworkProfile {
|
|
4
|
+
/** CAIP-2 identifier, e.g. `eip155:84532` */
|
|
5
|
+
readonly id: string;
|
|
6
|
+
/** Signed into the buyer's EIP-712 domain */
|
|
7
|
+
readonly chainId: number;
|
|
8
|
+
readonly displayName: string;
|
|
9
|
+
readonly kind: NetworkKind;
|
|
10
|
+
/** The local Anvil dev chain, where the in-process facilitator runs */
|
|
11
|
+
readonly local?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Default USDC deployment and EIP-712 domain. A public network's offers
|
|
14
|
+
* settle only in it; the local chain has none and names its mock token.
|
|
15
|
+
*
|
|
16
|
+
* `name` is the signed EIP-712 domain name, not the symbol, and deployments
|
|
17
|
+
* differ: `"USDC"` on Base Sepolia, `"USD Coin"` on Base.
|
|
18
|
+
*/
|
|
19
|
+
readonly canonicalAsset?: {
|
|
20
|
+
readonly symbol: string;
|
|
21
|
+
readonly address: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly version: string;
|
|
24
|
+
readonly decimals: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** A merchant-declared EVM network, from `payments.x402.networks` */
|
|
28
|
+
interface CustomNetworkDeclaration {
|
|
29
|
+
readonly kind: NetworkKind;
|
|
30
|
+
readonly displayName: string;
|
|
31
|
+
}
|
|
32
|
+
type CustomNetworks = Readonly<Record<string, CustomNetworkDeclaration>>;
|
|
33
|
+
/** The built-in EVM networks the x402 provider settles on without a declaration */
|
|
34
|
+
declare const SUPPORTED_NETWORK_IDS: readonly string[];
|
|
35
|
+
/** What a deployment is: the local dev chain, or a public testnet or mainnet */
|
|
36
|
+
type DeploymentMode = 'local' | 'testnet' | 'mainnet';
|
|
37
|
+
|
|
38
|
+
export { type CustomNetworks as C, type DeploymentMode as D, type NetworkProfile as N, SUPPORTED_NETWORK_IDS as S };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { I as IsoTimestamp,
|
|
3
|
-
import { d as AuthorizationRecord, b as AuthorizationSubmission, a as AuthorizationRequirement } from './authorization-
|
|
2
|
+
import { I as IsoTimestamp, o as PaymentResult, s as ProtocolName, b as PaymentSubmission, n as PaymentRequirement, A as AdapterDescriptor, R as ResourceRegistry, L as Logger, C as Clock, e as IdGenerator, c as AdapterHealth } from './runtime-7vLNYvmU.js';
|
|
3
|
+
import { d as AuthorizationRecord, b as AuthorizationSubmission, a as AuthorizationRequirement } from './authorization-CMkIuAkO.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Canonical commerce events. FROZEN CONTRACT. Every event in one flow shares
|
|
@@ -42,6 +42,16 @@ interface AdapterHealth {
|
|
|
42
42
|
readonly detail?: string;
|
|
43
43
|
readonly checkedAt: IsoTimestamp;
|
|
44
44
|
readonly durationMs?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Results per checked part, such as each x402 offer. Names and statuses
|
|
47
|
+
* may be published; exclude diagnostic detail.
|
|
48
|
+
*/
|
|
49
|
+
readonly components?: readonly AdapterHealthComponent[];
|
|
50
|
+
}
|
|
51
|
+
/** One part of an {@link AdapterHealth} result */
|
|
52
|
+
interface AdapterHealthComponent {
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly status: 'pass' | 'warn' | 'fail';
|
|
45
55
|
}
|
|
46
56
|
/** Describes an adapter's supported surface for diagnostics */
|
|
47
57
|
interface AdapterDescriptor {
|
|
@@ -180,8 +190,12 @@ interface PaymentRequirement {
|
|
|
180
190
|
readonly provider: PaymentMethodName;
|
|
181
191
|
readonly amount: DecimalAmount;
|
|
182
192
|
readonly currency: string;
|
|
183
|
-
/**
|
|
184
|
-
|
|
193
|
+
/**
|
|
194
|
+
* Merchant-controlled settlement destination, never a gateway-owned wallet.
|
|
195
|
+
* Multi-offer challenges omit this, `network` and `asset`; selection
|
|
196
|
+
* supplies the chosen offer's terms.
|
|
197
|
+
*/
|
|
198
|
+
readonly destination?: string;
|
|
185
199
|
readonly network?: string;
|
|
186
200
|
readonly asset?: string;
|
|
187
201
|
readonly expiresAt?: IsoTimestamp;
|
|
@@ -256,6 +270,14 @@ interface PaymentProvider {
|
|
|
256
270
|
* paid request, including one that already carries a proof to verify.
|
|
257
271
|
*/
|
|
258
272
|
createRequirement(context: PaymentContext): Promise<PaymentRequirement>;
|
|
273
|
+
/**
|
|
274
|
+
* Selects a proof's offer before verification, returning its destination,
|
|
275
|
+
* network, asset and metadata while preserving `id` and the full `challenge`.
|
|
276
|
+
* Verification, authorization, replay reservation and settlement use the result.
|
|
277
|
+
* This hook must not verify, reserve or settle. If no unique offer matches,
|
|
278
|
+
* return the original requirement for `verify` to reject.
|
|
279
|
+
*/
|
|
280
|
+
selectRequirement?(context: PaymentVerificationContext): Promise<PaymentRequirement>;
|
|
259
281
|
/**
|
|
260
282
|
* Validate a submitted proof against the requirement. Must return `rejected`
|
|
261
283
|
* or throw a `CommerceError` rather than an untyped error, and must never
|
|
@@ -300,4 +322,4 @@ interface IdGenerator {
|
|
|
300
322
|
}
|
|
301
323
|
declare const systemClock: Clock;
|
|
302
324
|
|
|
303
|
-
export { type AdapterDescriptor as A, type BackendHandler as B, type Clock as C, type DecimalAmount as D, type IsoTimestamp as I, type JsonSchema as J, type Logger as L, NOOP_LOGGER as N, type PaymentMethodName as P, type ResourceRegistry as R, type CommerceResource as a, type PaymentSubmission as b, type AdapterHealth as c, type PaymentProvider as d, type IdGenerator as e, type
|
|
325
|
+
export { type AdapterDescriptor as A, type BackendHandler as B, type Clock as C, type DecimalAmount as D, type IsoTimestamp as I, type JsonSchema as J, type Logger as L, NOOP_LOGGER as N, type PaymentMethodName as P, type ResourceRegistry as R, type CommerceResource as a, type PaymentSubmission as b, type AdapterHealth as c, type PaymentProvider as d, type IdGenerator as e, type AdapterHealthComponent as f, type AuthorizationMethodName as g, type BackendMethod as h, DEFAULT_BACKEND_TIMEOUT_MS as i, PAYMENT_METHOD_NAMES as j, PROTOCOL_NAMES as k, type PaymentChallenge as l, type PaymentContext as m, type PaymentRequirement as n, type PaymentResult as o, type PaymentSettlementContext as p, type PaymentVerificationContext as q, type Pricing as r, type ProtocolName as s, systemClock as t };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { computeSvmReplayKey } from './chunk-KA2AX5FH.js';
|
|
2
|
+
import { isRecord } from './chunk-2CJNA7MS.js';
|
|
3
|
+
import { getAddressEncoder, getProgramDerivedAddress, address } from '@solana/kit';
|
|
4
|
+
import { transactionMessageHash, decodeTransactionFromPayload } from '@x402/svm';
|
|
5
|
+
|
|
6
|
+
var MAX_TRANSACTION_BASE64 = 1644;
|
|
7
|
+
var ASSOCIATED_TOKEN_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
8
|
+
async function associatedTokenAccount(owner, mint, tokenProgram) {
|
|
9
|
+
const encoder = getAddressEncoder();
|
|
10
|
+
const [account] = await getProgramDerivedAddress({
|
|
11
|
+
programAddress: address(ASSOCIATED_TOKEN_PROGRAM),
|
|
12
|
+
seeds: [owner, tokenProgram, mint].map((key) => encoder.encode(address(key)))
|
|
13
|
+
});
|
|
14
|
+
return account;
|
|
15
|
+
}
|
|
16
|
+
function svmReplayKey(payload, network) {
|
|
17
|
+
if (!isRecord(payload)) return "invalid_exact_svm_payload_transaction";
|
|
18
|
+
const transaction = payload["transaction"];
|
|
19
|
+
if (typeof transaction !== "string" || transaction.length > MAX_TRANSACTION_BASE64) {
|
|
20
|
+
return "invalid_exact_svm_payload_transaction";
|
|
21
|
+
}
|
|
22
|
+
let messageHash;
|
|
23
|
+
try {
|
|
24
|
+
messageHash = transactionMessageHash(decodeTransactionFromPayload({ transaction }));
|
|
25
|
+
} catch {
|
|
26
|
+
return "invalid_exact_svm_payload_transaction_could_not_be_decoded";
|
|
27
|
+
}
|
|
28
|
+
return { replayKey: computeSvmReplayKey({ network, messageHash }) };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { associatedTokenAccount, svmReplayKey };
|
|
32
|
+
//# sourceMappingURL=svm-QEUAUNPQ.js.map
|
|
33
|
+
//# sourceMappingURL=svm-QEUAUNPQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payments/x402/svm.ts"],"names":[],"mappings":";;;;;AAgBA,IAAM,sBAAA,GAAyB,IAAA;AAE/B,IAAM,wBAAA,GAA2B,8CAAA;AAMjC,eAAsB,sBAAA,CACpB,KAAA,EACA,IAAA,EACA,YAAA,EACiB;AACjB,EAAA,MAAM,UAAU,iBAAA,EAAkB;AAClC,EAAA,MAAM,CAAC,OAAO,CAAA,GAAI,MAAM,wBAAA,CAAyB;AAAA,IAC/C,cAAA,EAAgB,QAAQ,wBAAwB,CAAA;AAAA,IAChD,KAAA,EAAO,CAAC,KAAA,EAAO,YAAA,EAAc,IAAI,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ,OAAA,CAAQ,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAC;AAAA,GAC7E,CAAA;AACD,EAAA,OAAO,OAAA;AACT;AAMO,SAAS,YAAA,CAAa,SAAkB,OAAA,EAAiD;AAC9F,EAAA,IAAI,CAAC,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,uCAAA;AAC/B,EAAA,MAAM,WAAA,GAAc,QAAQ,aAAa,CAAA;AACzC,EAAA,IAAI,OAAO,WAAA,KAAgB,QAAA,IAAY,WAAA,CAAY,SAAS,sBAAA,EAAwB;AAClF,IAAA,OAAO,uCAAA;AAAA,EACT;AACA,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI;AACF,IAAA,WAAA,GAAc,sBAAA,CAAuB,4BAAA,CAA6B,EAAE,WAAA,EAAa,CAAC,CAAA;AAAA,EACpF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,4DAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAE,SAAA,EAAW,mBAAA,CAAoB,EAAE,OAAA,EAAS,WAAA,EAAa,CAAA,EAAE;AACpE","file":"svm-QEUAUNPQ.js","sourcesContent":["/**\n * Solana `exact` payload inspection: bounded decoding and the replay identity.\n * The provider loads this module only for a Solana offer, so an EVM-only\n * deployment never imports `@x402/svm` or `@solana/kit`.\n *\n * The facilitator checks the transaction itself: the fee payer, signatures,\n * instruction layout, mint, recipient token account and amount, and a\n * simulation. Its smart-wallet path accepts layouts the gateway could not\n * parse, so the gateway does not read the transfer.\n */\nimport { address, getAddressEncoder, getProgramDerivedAddress } from '@solana/kit';\nimport { decodeTransactionFromPayload, transactionMessageHash } from '@x402/svm';\nimport { isRecord } from '../../core/is-record';\nimport { computeSvmReplayKey } from './replay-key';\n\n// A Solana transaction fits a 1232-byte packet, which is 1644 base64 characters\nconst MAX_TRANSACTION_BASE64 = 1644;\n\nconst ASSOCIATED_TOKEN_PROGRAM = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';\n\n/**\n * The associated token account of `owner` for `mint`, where the SDK client\n * sends a Solana `exact` payment. Its transaction cannot create the account.\n */\nexport async function associatedTokenAccount(\n owner: string,\n mint: string,\n tokenProgram: string,\n): Promise<string> {\n const encoder = getAddressEncoder();\n const [account] = await getProgramDerivedAddress({\n programAddress: address(ASSOCIATED_TOKEN_PROGRAM),\n seeds: [owner, tokenProgram, mint].map((key) => encoder.encode(address(key))),\n });\n return account;\n}\n\n/**\n * Returns the Solana `exact` replay key, or an SDK refusal reason for a\n * missing, oversized or undecodable transaction.\n */\nexport function svmReplayKey(payload: unknown, network: string): { replayKey: string } | string {\n if (!isRecord(payload)) return 'invalid_exact_svm_payload_transaction';\n const transaction = payload['transaction'];\n if (typeof transaction !== 'string' || transaction.length > MAX_TRANSACTION_BASE64) {\n return 'invalid_exact_svm_payload_transaction';\n }\n let messageHash: string;\n try {\n messageHash = transactionMessageHash(decodeTransactionFromPayload({ transaction }));\n } catch {\n return 'invalid_exact_svm_payload_transaction_could_not_be_decoded';\n }\n return { replayKey: computeSvmReplayKey({ network, messageHash }) };\n}\n"]}
|
package/dist/x402.d.ts
CHANGED
|
@@ -1,38 +1,8 @@
|
|
|
1
|
-
import { X as X402PaymentFlow, a as X402FacilitatorConfig } from './
|
|
2
|
-
export { F as FacilitatorAuth } from './
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/** CAIP-2 identifier, e.g. `eip155:84532` */
|
|
7
|
-
readonly id: string;
|
|
8
|
-
/** Signed into the buyer's EIP-712 domain */
|
|
9
|
-
readonly chainId: number;
|
|
10
|
-
readonly displayName: string;
|
|
11
|
-
readonly kind: 'testnet' | 'mainnet';
|
|
12
|
-
/**
|
|
13
|
-
* The USDC deployment this network settles in, with the EIP-712 domain the
|
|
14
|
-
* token reports. Enforced on mainnet only, since a testnet may use a mock
|
|
15
|
-
* token.
|
|
16
|
-
*
|
|
17
|
-
* `name` is the signed EIP-712 domain name, not the symbol, and the two
|
|
18
|
-
* deployments differ: `"USDC"` on Base Sepolia, `"USD Coin"` on Base. The
|
|
19
|
-
* values were read back from the contracts.
|
|
20
|
-
*/
|
|
21
|
-
readonly canonicalAsset?: {
|
|
22
|
-
readonly symbol: string;
|
|
23
|
-
readonly address: string;
|
|
24
|
-
readonly name: string;
|
|
25
|
-
readonly version: string;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
declare const SUPPORTED_NETWORK_IDS: readonly string[];
|
|
29
|
-
/**
|
|
30
|
-
* What a deployment is, as opposed to the network it names. `local` comes from
|
|
31
|
-
* the facilitator: the in-process facilitator makes a deployment local whatever
|
|
32
|
-
* CAIP-2 id it is configured with, which lets diagnostics show `eip155:84532`
|
|
33
|
-
* without claiming public Base Sepolia.
|
|
34
|
-
*/
|
|
35
|
-
type DeploymentMode = 'local' | 'testnet' | 'mainnet';
|
|
1
|
+
import { X as X402PaymentFlow, a as X402FacilitatorConfig } from './guardrails-CX_jYXvZ.js';
|
|
2
|
+
export { F as FacilitatorAuth } from './guardrails-CX_jYXvZ.js';
|
|
3
|
+
import { C as CustomNetworks } from './networks-olfflCI_.js';
|
|
4
|
+
export { D as DeploymentMode, N as NetworkProfile, S as SUPPORTED_NETWORK_IDS } from './networks-olfflCI_.js';
|
|
5
|
+
import { L as Logger, C as Clock, e as IdGenerator, d as PaymentProvider } from './runtime-7vLNYvmU.js';
|
|
36
6
|
|
|
37
7
|
/**
|
|
38
8
|
* Client-side payment helper: builds and EIP-712-signs an x402 v2 `exact`/EVM
|
|
@@ -62,34 +32,11 @@ interface CreatePaymentProofOptions {
|
|
|
62
32
|
/** Returns the base64 `PAYMENT-SIGNATURE` value to send back to the gateway */
|
|
63
33
|
declare function createPaymentProof(options: CreatePaymentProofOptions): Promise<string>;
|
|
64
34
|
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
-
* `transferWithAuthorization`.
|
|
68
|
-
*
|
|
69
|
-
* `verify()` never moves funds. `settle()` does, and throws unless it is handed
|
|
70
|
-
* a successful verification. Both run through a facilitator (see
|
|
71
|
-
* `facilitator.ts`): the SDK's own `x402Facilitator` in this process, or a
|
|
72
|
-
* remote HTTP facilitator.
|
|
73
|
-
*/
|
|
35
|
+
/** EIP-3009 `transferWithAuthorization`, or Permit2 with a prior token allowance */
|
|
36
|
+
type X402AssetTransferMethod = 'eip3009' | 'permit2';
|
|
74
37
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
* CAIP-2 network identifier, e.g. `eip155:84532`. The chain id it carries is
|
|
78
|
-
* part of the EIP-712 domain the buyer signs, so it is read from this value
|
|
79
|
-
* rather than defaulted.
|
|
80
|
-
*/
|
|
81
|
-
readonly network: string;
|
|
82
|
-
/** RPC endpoint. Local chain: http://127.0.0.1:8545 */
|
|
83
|
-
readonly rpcUrl: string;
|
|
84
|
-
/** ERC-20 (EIP-3009) asset address used for settlement */
|
|
85
|
-
readonly asset: `0x${string}`;
|
|
86
|
-
/** EIP-712 domain name of the asset, e.g. 'MockUSDC' */
|
|
87
|
-
readonly assetName: string;
|
|
88
|
-
/** EIP-712 domain version of the asset, e.g. '2' */
|
|
89
|
-
readonly assetVersion: string;
|
|
90
|
-
readonly assetDecimals: number;
|
|
91
|
-
/** Merchant-controlled settlement destination. Never a gateway-owned wallet */
|
|
92
|
-
readonly payTo: `0x${string}`;
|
|
38
|
+
/** A single offer and the settings every offer shares */
|
|
39
|
+
interface X402ProviderOptions extends X402OfferOptions {
|
|
93
40
|
readonly maxTimeoutSeconds?: number;
|
|
94
41
|
/**
|
|
95
42
|
* When the payment settles relative to the backend call. Defaults to
|
|
@@ -99,6 +46,11 @@ interface X402ProviderOptions {
|
|
|
99
46
|
readonly paymentFlow?: X402PaymentFlow;
|
|
100
47
|
/** Per-resource overrides of `paymentFlow`, keyed by resource id */
|
|
101
48
|
readonly resourcePaymentFlows?: Readonly<Record<string, X402PaymentFlow>>;
|
|
49
|
+
/**
|
|
50
|
+
* The media type each resource's challenge declares as `resource.mimeType`,
|
|
51
|
+
* keyed by resource id. Defaults to `application/json`.
|
|
52
|
+
*/
|
|
53
|
+
readonly resourceMimeTypes?: Readonly<Record<string, string>>;
|
|
102
54
|
/**
|
|
103
55
|
* Which facilitator verifies and broadcasts. `local` runs one in this process
|
|
104
56
|
* against a dev chain, and its `signerPrivateKey` pays gas there, usually
|
|
@@ -110,10 +62,70 @@ interface X402ProviderOptions {
|
|
|
110
62
|
readonly allowMainnet?: boolean;
|
|
111
63
|
/** Required on mainnet when facilitator auth is `none` */
|
|
112
64
|
readonly allowUnauthenticatedFacilitator?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Offer overrides by resource id, sharing the provider's facilitator and
|
|
67
|
+
* settings. Each list replaces the provider's offers for that resource.
|
|
68
|
+
*/
|
|
69
|
+
readonly resourceOffers?: Readonly<Record<string, readonly X402OfferOptions[]>>;
|
|
70
|
+
/**
|
|
71
|
+
* Custom EVM networks keyed by CAIP-2 ID; `network` may select one, and
|
|
72
|
+
* its `kind` determines mainnet guardrails
|
|
73
|
+
*/
|
|
74
|
+
readonly customNetworks?: CustomNetworks;
|
|
113
75
|
readonly logger?: Logger;
|
|
114
76
|
readonly clock?: Clock;
|
|
115
77
|
readonly ids?: IdGenerator;
|
|
116
78
|
}
|
|
117
|
-
|
|
79
|
+
/** Settlement network, token and merchant payee for one offer */
|
|
80
|
+
interface X402OfferOptions {
|
|
81
|
+
/**
|
|
82
|
+
* CAIP-2 network identifier, e.g. `eip155:8453`. An EVM chain id it carries
|
|
83
|
+
* is part of the EIP-712 domain the buyer signs, so it is read from this
|
|
84
|
+
* value rather than defaulted.
|
|
85
|
+
*/
|
|
86
|
+
readonly network: string;
|
|
87
|
+
/** RPC endpoint of that network, for health checks and a local facilitator */
|
|
88
|
+
readonly rpcUrl: string;
|
|
89
|
+
/** ERC-20 contract or Solana mint used for settlement */
|
|
90
|
+
readonly asset: string;
|
|
91
|
+
/** EIP-712 domain name of the asset, e.g. 'USDC'; required for EIP-3009 */
|
|
92
|
+
readonly assetName?: string;
|
|
93
|
+
/** EIP-712 domain version of the asset, e.g. '2'; required for EIP-3009 */
|
|
94
|
+
readonly assetVersion?: string;
|
|
95
|
+
readonly assetDecimals: number;
|
|
96
|
+
/**
|
|
97
|
+
* Merchant-controlled settlement destination, never a gateway-owned wallet.
|
|
98
|
+
* On Solana it is the wallet; the transfer goes to its token account.
|
|
99
|
+
*/
|
|
100
|
+
readonly payTo: string;
|
|
101
|
+
/**
|
|
102
|
+
* EVM only: `eip3009` (the default) or `permit2`. A Permit2 buyer approves
|
|
103
|
+
* the Permit2 contract for the token beforehand; the gateway never sends
|
|
104
|
+
* approvals.
|
|
105
|
+
*/
|
|
106
|
+
readonly assetTransferMethod?: X402AssetTransferMethod;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Offers for each paid resource, using one facilitator. The proof selects
|
|
110
|
+
* the offer the buyer pays.
|
|
111
|
+
*/
|
|
112
|
+
interface X402MultiOfferProviderOptions extends Omit<X402ProviderOptions, keyof X402OfferOptions> {
|
|
113
|
+
readonly offers: readonly X402OfferOptions[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* x402 payment provider: protocol v2, `exact` scheme. On EVM the buyer signs an
|
|
118
|
+
* EIP-3009 `transferWithAuthorization` or a Permit2 transfer through the x402
|
|
119
|
+
* exact proxy; on Solana, a token transfer whose fee the facilitator pays; on
|
|
120
|
+
* NEAR, a delegated NEP-141 `ft_transfer` that the facilitator's relayer
|
|
121
|
+
* submits.
|
|
122
|
+
*
|
|
123
|
+
* `verify()` never moves funds. `settle()` does, and throws unless it is handed
|
|
124
|
+
* a successful verification. Both run through a facilitator (see
|
|
125
|
+
* `../facilitator.ts`): the SDK's own `x402Facilitator` in this process, or a
|
|
126
|
+
* remote HTTP facilitator.
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
declare function createX402PaymentProvider(options: X402ProviderOptions | X402MultiOfferProviderOptions): PaymentProvider;
|
|
118
130
|
|
|
119
|
-
export { type CreatePaymentProofOptions, type
|
|
131
|
+
export { type CreatePaymentProofOptions, type X402AssetTransferMethod, X402FacilitatorConfig, type X402MultiOfferProviderOptions, type X402OfferOptions, X402PaymentFlow, type X402ProviderOptions, createPaymentProof, createX402PaymentProvider, createX402PaymentProvider as x402 };
|
package/dist/x402.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { chainIdFromCaip2 } from './chunk-
|
|
2
|
-
export { createX402PaymentProvider, createX402PaymentProvider as x402 } from './chunk-
|
|
3
|
-
export { SUPPORTED_NETWORK_IDS } from './chunk-
|
|
4
|
-
import { CommerceError } from './chunk-
|
|
1
|
+
import { chainIdFromCaip2 } from './chunk-HNRDZLSN.js';
|
|
2
|
+
export { createX402PaymentProvider, createX402PaymentProvider as x402 } from './chunk-HNRDZLSN.js';
|
|
3
|
+
export { SUPPORTED_NETWORK_IDS } from './chunk-Y4RE3XYF.js';
|
|
4
|
+
import { CommerceError } from './chunk-7ZMMXZ4G.js';
|
|
5
|
+
import './chunk-KA2AX5FH.js';
|
|
6
|
+
import './chunk-2CJNA7MS.js';
|
|
5
7
|
import { PaymentRequirementsV2Schema } from '@x402/core/schemas';
|
|
6
8
|
import { getAddress, toHex } from 'viem';
|
|
7
9
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
@@ -19,6 +21,13 @@ var TRANSFER_WITH_AUTHORIZATION_TYPES = {
|
|
|
19
21
|
};
|
|
20
22
|
async function createPaymentProof(options) {
|
|
21
23
|
const requirements = PaymentRequirementsV2Schema.parse(options.accepts);
|
|
24
|
+
const method = requirements.extra?.["assetTransferMethod"];
|
|
25
|
+
if (method !== void 0 && method !== "eip3009") {
|
|
26
|
+
throw new CommerceError(
|
|
27
|
+
"INPUT_INVALID",
|
|
28
|
+
`createPaymentProof: signs EIP-3009 only, and this offer uses "${String(method)}"; sign it with the SDK's x402Client`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
22
31
|
if (!requirements.extra || typeof requirements.extra["name"] !== "string" || typeof requirements.extra["version"] !== "string") {
|
|
23
32
|
throw new CommerceError(
|
|
24
33
|
"INPUT_INVALID",
|