mppx 0.9.1 → 0.9.3
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/CHANGELOG.md +28 -0
- package/README.md +26 -0
- package/dist/Method.d.ts +2 -0
- package/dist/cli/Extension.d.ts +20 -0
- package/dist/cli/Extension.js +5 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.js +135 -135
- package/dist/cli/config.d.ts +4 -0
- package/dist/cli/config.js +1 -0
- package/dist/cli/internal.d.ts +3 -0
- package/dist/cli/internal.js +15 -2
- package/dist/cli/plugins/evm.js +2 -0
- package/dist/cli/plugins/index.d.ts +1 -0
- package/dist/cli/plugins/index.js +13 -13
- package/dist/cli/plugins/plugin.d.ts +2 -2
- package/dist/cli/plugins/x402.d.ts +3 -0
- package/dist/cli/plugins/x402.js +61 -0
- package/dist/cli/sessions/request.d.ts +1 -0
- package/dist/cli/sessions/request.js +1 -0
- package/dist/cli/validate/payment.js +14 -8
- package/dist/evm/client/Charge.d.ts +2 -2
- package/dist/evm/client/Charge.js +1 -1
- package/dist/evm/server/Charge.d.ts +7 -2
- package/dist/evm/server/Charge.js +28 -2
- package/dist/evm/server/Methods.d.ts +1 -1
- package/dist/internal/version.d.ts +5 -0
- package/dist/internal/version.js +6 -0
- package/dist/middlewares/internal/mppx.js +17 -3
- package/dist/server/Mppx.d.ts +7 -6
- package/dist/server/Mppx.js +84 -2
- package/dist/server/internal/html/config.js +1 -3
- package/dist/stripe/Methods.d.ts +24 -5
- package/dist/stripe/Methods.js +14 -11
- package/dist/stripe/client/Charge.d.ts +23 -5
- package/dist/stripe/client/Methods.d.ts +23 -5
- package/dist/stripe/internal/constants.d.ts +4 -0
- package/dist/stripe/internal/constants.js +2 -0
- package/dist/stripe/internal/parse-units.d.ts +8 -0
- package/dist/stripe/internal/parse-units.js +20 -0
- package/dist/stripe/internal/payment-intent.d.ts +39 -1
- package/dist/stripe/internal/payment-intent.js +16 -1
- package/dist/stripe/internal/types.d.ts +4 -0
- package/dist/stripe/server/Charge.d.ts +25 -5
- package/dist/stripe/server/Charge.js +35 -23
- package/dist/stripe/server/Methods.d.ts +8 -0
- package/dist/stripe/server/Methods.js +54 -9
- package/dist/stripe/server/internal/analytics.d.ts +6 -0
- package/dist/stripe/server/internal/analytics.js +16 -0
- package/dist/stripe/server/internal/hosted-fee-payer.d.ts +10 -0
- package/dist/stripe/server/internal/hosted-fee-payer.js +54 -0
- package/dist/stripe/server/internal/html.gen.d.ts +1 -1
- package/dist/stripe/server/internal/html.gen.js +1 -1
- package/dist/stripe/server/internal/record-payment.d.ts +4 -1
- package/dist/stripe/server/internal/record-payment.js +35 -5
- package/dist/tempo/client/Subscription.js +6 -2
- package/dist/tempo/internal/account.d.ts +1 -0
- package/dist/tempo/internal/fee-payer.d.ts +2 -0
- package/dist/tempo/internal/fee-payer.js +4 -0
- package/dist/tempo/internal/remote-fee-payer.d.ts +2 -0
- package/dist/tempo/server/Subscription.js +1 -0
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/session/client/SessionManager.d.ts +5 -0
- package/dist/tempo/session/client/SessionManager.js +16 -2
- package/dist/tempo/session/precompile/Chain.js +3 -0
- package/dist/tempo/subscription/KeyAuthorization.d.ts +7 -1
- package/dist/tempo/subscription/KeyAuthorization.js +21 -3
- package/dist/viem/Client.js +1 -0
- package/dist/x402/client/Exact.d.ts +2 -2
- package/dist/x402/client/Exact.js +1 -1
- package/dist/x402/server/EvmCharge.d.ts +2 -0
- package/dist/x402/server/EvmCharge.js +34 -26
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { type Address } from 'viem';
|
|
|
3
3
|
import * as Account from '../../../viem/Account.js';
|
|
4
4
|
import * as Client from '../../../viem/Client.js';
|
|
5
5
|
import { type ChannelStore } from '../client/ChannelStore.js';
|
|
6
|
+
import { type SessionContext } from '../client/CredentialState.js';
|
|
6
7
|
import { session as sessionPlugin } from '../client/Session.js';
|
|
7
8
|
import type { SessionReceipt } from '../precompile/Protocol.js';
|
|
8
9
|
import { deserializeSnapshot as deserializeSessionSnapshot, serializeSnapshot as serializeSessionSnapshot } from '../Snapshot.js';
|
|
@@ -48,6 +49,8 @@ export type PaymentResponse = Response & {
|
|
|
48
49
|
/** Local cumulative voucher authorization in raw token units. */
|
|
49
50
|
cumulative: bigint;
|
|
50
51
|
};
|
|
52
|
+
/** @internal Merges manager-wide context without allowing it to replace an operation's fields. */
|
|
53
|
+
export declare function mergeSessionCredentialContext(credentialContext: unknown, operationContext: SessionContext): SessionContext;
|
|
51
54
|
/**
|
|
52
55
|
* Creates a session manager that handles the full client payment lifecycle:
|
|
53
56
|
* channel open, incremental vouchers, SSE streaming, and channel close.
|
|
@@ -78,6 +81,8 @@ export declare namespace sessionManager {
|
|
|
78
81
|
escrow?: Address | undefined;
|
|
79
82
|
/** Fetch implementation used for HTTP probes, management posts, and paid retries. */
|
|
80
83
|
fetch?: typeof globalThis.fetch | undefined;
|
|
84
|
+
/** Base context supplied to every session credential created by the manager. */
|
|
85
|
+
credentialContext?: unknown;
|
|
81
86
|
/** Maximum deposit in human-readable units (e.g. `'10'` for 10 tokens). Converted to raw units via `decimals`. */
|
|
82
87
|
maxDeposit?: string | undefined;
|
|
83
88
|
/**
|
|
@@ -10,7 +10,7 @@ import * as Client from '../../../viem/Client.js';
|
|
|
10
10
|
import { charge as chargePlugin } from '../../client/Charge.js';
|
|
11
11
|
import * as defaults from '../../internal/defaults.js';
|
|
12
12
|
import { createChannelStore, entryKey } from '../client/ChannelStore.js';
|
|
13
|
-
import { hydrateSessionSnapshot } from '../client/CredentialState.js';
|
|
13
|
+
import { hydrateSessionSnapshot, sessionContextSchema, } from '../client/CredentialState.js';
|
|
14
14
|
import { session as sessionPlugin } from '../client/Session.js';
|
|
15
15
|
import * as Channel from '../precompile/Channel.js';
|
|
16
16
|
import { deserializeSessionReceipt } from '../precompile/Protocol.js';
|
|
@@ -60,6 +60,12 @@ function requestInitWithSessionHint(input, init, channelId) {
|
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
+
/** @internal Merges manager-wide context without allowing it to replace an operation's fields. */
|
|
64
|
+
export function mergeSessionCredentialContext(credentialContext, operationContext) {
|
|
65
|
+
if (credentialContext === undefined)
|
|
66
|
+
return operationContext;
|
|
67
|
+
return { ...sessionContextSchema.parse(credentialContext), ...operationContext };
|
|
68
|
+
}
|
|
63
69
|
function resolveSessionManagerConfig(parameters) {
|
|
64
70
|
const decimals = parameters.decimals ?? 6;
|
|
65
71
|
const WebSocket = parameters.webSocket ??
|
|
@@ -92,6 +98,9 @@ export function sessionManager(parameters) {
|
|
|
92
98
|
});
|
|
93
99
|
const getAccount = Account.getResolver({ account: parameters.account });
|
|
94
100
|
const runtime = createSessionManagerRuntime();
|
|
101
|
+
const credentialContext = parameters.credentialContext === undefined
|
|
102
|
+
? undefined
|
|
103
|
+
: mergeSessionCredentialContext(parameters.credentialContext, {});
|
|
95
104
|
const receipts = createSessionReceiptCoordinator({
|
|
96
105
|
getSocketSession: () => runtime.socketSession,
|
|
97
106
|
});
|
|
@@ -248,7 +257,10 @@ export function sessionManager(parameters) {
|
|
|
248
257
|
},
|
|
249
258
|
});
|
|
250
259
|
function createSessionCredential(challenge, context) {
|
|
251
|
-
return method.createCredential({
|
|
260
|
+
return method.createCredential({
|
|
261
|
+
challenge,
|
|
262
|
+
context: mergeSessionCredentialContext(credentialContext, context),
|
|
263
|
+
});
|
|
252
264
|
}
|
|
253
265
|
function updateSpentFromReceipt(receipt) {
|
|
254
266
|
applySessionReceiptToRuntime({
|
|
@@ -535,6 +547,8 @@ export function sessionManager(parameters) {
|
|
|
535
547
|
use.trackCreates = true;
|
|
536
548
|
const liveHint = runtime.channel?.opened ? runtime.channel.channelId : undefined;
|
|
537
549
|
let effectiveInit = requestInitWithSessionHint(input, init, liveHint);
|
|
550
|
+
if (credentialContext)
|
|
551
|
+
effectiveInit = { ...effectiveInit, context: credentialContext };
|
|
538
552
|
// Stored channels may be stale, so retry once after evicting the resumed entry.
|
|
539
553
|
let canRetryResumed = !previous.channel?.opened;
|
|
540
554
|
async function retryWithoutResumed() {
|
|
@@ -318,6 +318,7 @@ async function prepareFeePayerCallTransaction(client, parameters) {
|
|
|
318
318
|
account,
|
|
319
319
|
calls: [{ to, data }],
|
|
320
320
|
feePayer: true,
|
|
321
|
+
nonceKey: 'expiring',
|
|
321
322
|
...(feeToken ? { feeToken } : {}),
|
|
322
323
|
});
|
|
323
324
|
}
|
|
@@ -329,6 +330,8 @@ function sendPrecompileContractCall(client, parameters) {
|
|
|
329
330
|
...(account ? { account } : {}),
|
|
330
331
|
to,
|
|
331
332
|
data,
|
|
333
|
+
// Server processes can share a signer without sharing viem's concurrency detection.
|
|
334
|
+
nonceKey: 'expiring',
|
|
332
335
|
...(feePayer ? { feePayer } : {}),
|
|
333
336
|
...(feeToken ? { feeToken } : {}),
|
|
334
337
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Hex } from 'ox';
|
|
1
2
|
import { KeyAuthorization } from 'ox/tempo';
|
|
2
3
|
import { type Address } from 'viem';
|
|
3
4
|
import type * as Methods from '../Methods.js';
|
|
@@ -42,6 +43,8 @@ export declare function getSubscriptionRpcAllowedCalls(request: Pick<Subscriptio
|
|
|
42
43
|
readonly recipients: readonly [`0x${string}`];
|
|
43
44
|
}];
|
|
44
45
|
}];
|
|
46
|
+
/** Decodes the server-issued challenge identifier for use as a signed Tempo witness. */
|
|
47
|
+
export declare function getSubscriptionChallengeWitness(challengeId: string): Hex.Hex;
|
|
45
48
|
/**
|
|
46
49
|
* Creates and signs a Tempo key authorization for subscription payments when the account can sign
|
|
47
50
|
* arbitrary hashes locally.
|
|
@@ -53,6 +56,7 @@ export declare function signSubscriptionKeyAuthorization(parameters: {
|
|
|
53
56
|
hash: `0x${string}`;
|
|
54
57
|
}) => Promise<`0x${string}`>) | undefined;
|
|
55
58
|
};
|
|
59
|
+
challengeId: string;
|
|
56
60
|
chainId: number;
|
|
57
61
|
request: Pick<SubscriptionRequest, 'amount' | 'currency' | 'periodCount' | 'periodUnit' | 'recipient' | 'subscriptionExpires'>;
|
|
58
62
|
}): Promise<{
|
|
@@ -96,7 +100,7 @@ export declare function signSubscriptionKeyAuthorization(parameters: {
|
|
|
96
100
|
version?: undefined;
|
|
97
101
|
} | {
|
|
98
102
|
metadata: {
|
|
99
|
-
authenticatorData:
|
|
103
|
+
authenticatorData: Hex.Hex;
|
|
100
104
|
clientDataJSON: string;
|
|
101
105
|
};
|
|
102
106
|
signature: {
|
|
@@ -133,6 +137,7 @@ export declare function signSubscriptionKeyAuthorization(parameters: {
|
|
|
133
137
|
readonly recipients: readonly `0x${string}`[];
|
|
134
138
|
}[];
|
|
135
139
|
readonly type: "p256" | "secp256k1" | "webAuthn";
|
|
140
|
+
readonly witness: `0x${string}`;
|
|
136
141
|
} | undefined>;
|
|
137
142
|
/**
|
|
138
143
|
* Verifies that a subscription credential contains a key authorization scoped to the requested
|
|
@@ -140,6 +145,7 @@ export declare function signSubscriptionKeyAuthorization(parameters: {
|
|
|
140
145
|
*/
|
|
141
146
|
export declare function verifySubscriptionKeyAuthorization(parameters: {
|
|
142
147
|
accessKey?: SubscriptionAccessKey | undefined;
|
|
148
|
+
challengeId: string;
|
|
143
149
|
chainId: number;
|
|
144
150
|
payload: SubscriptionCredentialPayload;
|
|
145
151
|
request: SubscriptionRequest;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Base64, Hex } from 'ox';
|
|
1
2
|
import { KeyAuthorization, SignatureEnvelope } from 'ox/tempo';
|
|
2
3
|
import { isAddress, isAddressEqual } from 'viem';
|
|
3
4
|
import { VerificationFailedError } from '../../Errors.js';
|
|
@@ -104,16 +105,29 @@ export function getSubscriptionRpcAllowedCalls(request) {
|
|
|
104
105
|
},
|
|
105
106
|
];
|
|
106
107
|
}
|
|
108
|
+
/** Decodes the server-issued challenge identifier for use as a signed Tempo witness. */
|
|
109
|
+
export function getSubscriptionChallengeWitness(challengeId) {
|
|
110
|
+
try {
|
|
111
|
+
const witness = Hex.fromBytes(Base64.toBytes(challengeId));
|
|
112
|
+
if (Hex.size(witness) !== 32)
|
|
113
|
+
throw new Error('invalid challenge id size');
|
|
114
|
+
return witness;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
throw new VerificationFailedError({ reason: 'challenge id must encode 32 bytes' });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
107
120
|
/**
|
|
108
121
|
* Creates and signs a Tempo key authorization for subscription payments when the account can sign
|
|
109
122
|
* arbitrary hashes locally.
|
|
110
123
|
*/
|
|
111
124
|
export async function signSubscriptionKeyAuthorization(parameters) {
|
|
112
|
-
const { accessKey, account, chainId, request } = parameters;
|
|
125
|
+
const { accessKey, account, challengeId, chainId, request } = parameters;
|
|
113
126
|
if (typeof account.sign !== 'function')
|
|
114
127
|
return undefined;
|
|
115
128
|
const authorization = createUnsignedAuthorization({
|
|
116
129
|
accessKey,
|
|
130
|
+
challengeId,
|
|
117
131
|
chainId,
|
|
118
132
|
request,
|
|
119
133
|
});
|
|
@@ -135,7 +149,7 @@ export async function signSubscriptionKeyAuthorization(parameters) {
|
|
|
135
149
|
* token, recipient, amount, period, expiry, chain, and server-issued access key.
|
|
136
150
|
*/
|
|
137
151
|
export function verifySubscriptionKeyAuthorization(parameters) {
|
|
138
|
-
const { accessKey, chainId, payload, request } = parameters;
|
|
152
|
+
const { accessKey, challengeId, chainId, payload, request } = parameters;
|
|
139
153
|
if (payload.type !== 'keyAuthorization') {
|
|
140
154
|
throw new VerificationFailedError({ reason: 'invalid keyAuthorization payload' });
|
|
141
155
|
}
|
|
@@ -146,6 +160,9 @@ export function verifySubscriptionKeyAuthorization(parameters) {
|
|
|
146
160
|
authorization,
|
|
147
161
|
chainId,
|
|
148
162
|
});
|
|
163
|
+
if (authorization.witness?.toLowerCase() !== getSubscriptionChallengeWitness(challengeId)) {
|
|
164
|
+
throw new VerificationFailedError({ reason: 'keyAuthorization challenge mismatch' });
|
|
165
|
+
}
|
|
149
166
|
assertAuthorizationExpiry(authorization, request);
|
|
150
167
|
assertAuthorizationLimit(getSingleTokenLimit(authorization), request);
|
|
151
168
|
assertAuthorizationScopes(authorization.scopes, request);
|
|
@@ -159,7 +176,7 @@ export function verifySubscriptionKeyAuthorization(parameters) {
|
|
|
159
176
|
};
|
|
160
177
|
}
|
|
161
178
|
function createUnsignedAuthorization(parameters) {
|
|
162
|
-
const { accessKey, chainId, request } = parameters;
|
|
179
|
+
const { accessKey, challengeId, chainId, request } = parameters;
|
|
163
180
|
return KeyAuthorization.from({
|
|
164
181
|
address: normalizeAddress(accessKey.accessKeyAddress, 'accessKeyAddress'),
|
|
165
182
|
chainId: BigInt(chainId),
|
|
@@ -173,6 +190,7 @@ function createUnsignedAuthorization(parameters) {
|
|
|
173
190
|
],
|
|
174
191
|
scopes: getSubscriptionScopes(request),
|
|
175
192
|
type: accessKey.keyType,
|
|
193
|
+
witness: getSubscriptionChallengeWitness(challengeId),
|
|
176
194
|
});
|
|
177
195
|
}
|
|
178
196
|
function deserializeAuthorization(signature) {
|
package/dist/viem/Client.js
CHANGED
|
@@ -9,6 +9,7 @@ const knownTempoChains = {
|
|
|
9
9
|
/** Creates an HTTP transport for a configured remote fee-payer service. */
|
|
10
10
|
export function remoteFeePayerTransport(config, options = {}) {
|
|
11
11
|
return http(config.url, {
|
|
12
|
+
fetchFn: config.fetch,
|
|
12
13
|
fetchOptions: { headers: RemoteFeePayer.resolveHeaders(config) },
|
|
13
14
|
...options,
|
|
14
15
|
});
|
|
@@ -28,8 +28,8 @@ export type Signer = Account & {
|
|
|
28
28
|
signTypedData?: (parameters: any) => Promise<`0x${string}`>;
|
|
29
29
|
};
|
|
30
30
|
export type Config = {
|
|
31
|
-
/** Account used to sign exact EVM payment payloads. */
|
|
32
|
-
account
|
|
31
|
+
/** Account used to sign exact EVM payment payloads, unless supplied in credential context. */
|
|
32
|
+
account?: Account | undefined;
|
|
33
33
|
/** Optional token decimals used to parse `maxAmount` when currency metadata is not provided. */
|
|
34
34
|
decimals?: number | undefined;
|
|
35
35
|
/** Optional maximum display-unit amount the client is willing to pay. */
|
|
@@ -8,7 +8,7 @@ import * as Types from '../Types.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export async function createCredential(parameters) {
|
|
10
10
|
const account = (parameters.context?.account ?? parameters.config.account);
|
|
11
|
-
if (!account
|
|
11
|
+
if (!account?.signTypedData)
|
|
12
12
|
throw new Error('x402 exact requires a typed-data signer.');
|
|
13
13
|
const request = parameters.challenge.request;
|
|
14
14
|
const accepted = Types.toPaymentRequirements(request);
|
|
@@ -52,6 +52,8 @@ export declare function resolveOptions(parameters: {
|
|
|
52
52
|
export declare function createPath(config: ResolvedOptions): Path;
|
|
53
53
|
/** Settles a verified EVM authorization through an x402 facilitator. */
|
|
54
54
|
export declare function settleWithFacilitator(parameters: ResolvedOptions): SettleWithFacilitator;
|
|
55
|
+
/** Checks an EVM authorization with the facilitator without settling it. */
|
|
56
|
+
export declare function verifyWithFacilitator(parameters: ResolvedOptions, authorization: Parameters<SettleWithFacilitator>[0]): Promise<void>;
|
|
55
57
|
export type SettleWithFacilitator = (parameters: {
|
|
56
58
|
credential: Credential.Credential<Types.AuthorizationPayload>;
|
|
57
59
|
payload: Types.AuthorizationPayload;
|
|
@@ -174,34 +174,11 @@ export function createPath(config) {
|
|
|
174
174
|
}
|
|
175
175
|
/** Settles a verified EVM authorization through an x402 facilitator. */
|
|
176
176
|
export function settleWithFacilitator(parameters) {
|
|
177
|
-
const { facilitator
|
|
177
|
+
const { facilitator } = parameters;
|
|
178
178
|
if (!facilitator)
|
|
179
179
|
throw new Error('EVM authorization x402 requires `facilitator`.');
|
|
180
|
-
return async (
|
|
181
|
-
const paymentRequirements =
|
|
182
|
-
...parameters,
|
|
183
|
-
maxTimeoutSeconds,
|
|
184
|
-
});
|
|
185
|
-
const paymentPayload = {
|
|
186
|
-
accepted: paymentRequirements,
|
|
187
|
-
payload: {
|
|
188
|
-
authorization: {
|
|
189
|
-
from: payload.from,
|
|
190
|
-
nonce: payload.nonce,
|
|
191
|
-
to: payload.to,
|
|
192
|
-
validAfter: payload.validAfter,
|
|
193
|
-
validBefore: payload.validBefore,
|
|
194
|
-
value: payload.value,
|
|
195
|
-
},
|
|
196
|
-
signature: payload.signature,
|
|
197
|
-
},
|
|
198
|
-
x402Version: 2,
|
|
199
|
-
};
|
|
200
|
-
const verified = await facilitator.verify(paymentPayload, paymentRequirements);
|
|
201
|
-
if (!verified.isValid)
|
|
202
|
-
throw new VerificationFailedError({
|
|
203
|
-
reason: verified.invalidMessage ?? verified.invalidReason ?? 'EVM facilitator verify failed',
|
|
204
|
-
});
|
|
180
|
+
return async (authorization) => {
|
|
181
|
+
const { paymentPayload, paymentRequirements } = facilitatorPayment(parameters, authorization);
|
|
205
182
|
const settled = await facilitator.settle(paymentPayload, paymentRequirements);
|
|
206
183
|
if (!settled.success)
|
|
207
184
|
throw new VerificationFailedError({
|
|
@@ -212,6 +189,37 @@ export function settleWithFacilitator(parameters) {
|
|
|
212
189
|
};
|
|
213
190
|
};
|
|
214
191
|
}
|
|
192
|
+
/** Checks an EVM authorization with the facilitator without settling it. */
|
|
193
|
+
export async function verifyWithFacilitator(parameters, authorization) {
|
|
194
|
+
const { facilitator } = parameters;
|
|
195
|
+
if (!facilitator)
|
|
196
|
+
throw new Error('EVM authorization x402 requires `facilitator`.');
|
|
197
|
+
const { paymentPayload, paymentRequirements } = facilitatorPayment(parameters, authorization);
|
|
198
|
+
const verified = await facilitator.verify(paymentPayload, paymentRequirements);
|
|
199
|
+
if (!verified.isValid)
|
|
200
|
+
throw new VerificationFailedError({
|
|
201
|
+
reason: verified.invalidMessage ?? verified.invalidReason ?? 'EVM facilitator verify failed',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function facilitatorPayment(parameters, { payload, request }) {
|
|
205
|
+
const paymentRequirements = toPaymentRequirements(request, parameters);
|
|
206
|
+
const paymentPayload = {
|
|
207
|
+
accepted: paymentRequirements,
|
|
208
|
+
payload: {
|
|
209
|
+
authorization: {
|
|
210
|
+
from: payload.from,
|
|
211
|
+
nonce: payload.nonce,
|
|
212
|
+
to: payload.to,
|
|
213
|
+
validAfter: payload.validAfter,
|
|
214
|
+
validBefore: payload.validBefore,
|
|
215
|
+
value: payload.value,
|
|
216
|
+
},
|
|
217
|
+
signature: payload.signature,
|
|
218
|
+
},
|
|
219
|
+
x402Version: 2,
|
|
220
|
+
};
|
|
221
|
+
return { paymentPayload, paymentRequirements };
|
|
222
|
+
}
|
|
215
223
|
/** Returns whether a credential was converted from an x402 payment payload. */
|
|
216
224
|
export function isCredential(credential) {
|
|
217
225
|
return credential[x402Credential] === true;
|