mppx 0.10.0 → 0.11.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/CHANGELOG.md +19 -0
- package/dist/cli/cli.js +134 -134
- package/dist/cli/plugins/index.js +12 -12
- package/dist/client/Mppx.d.ts +25 -12
- package/dist/client/Mppx.js +18 -7
- package/dist/client/internal/protocols/X402.js +0 -2
- package/dist/internal/version.d.ts +2 -2
- package/dist/internal/version.js +1 -1
- package/dist/stripe/server/Methods.js +11 -3
- package/dist/stripe/server/internal/analytics.d.ts +1 -0
- package/dist/stripe/server/internal/analytics.js +2 -2
- package/dist/stripe/server/internal/record-payment.js +2 -2
- package/dist/tempo/Methods.d.ts +5 -3
- package/dist/tempo/Methods.js +6 -5
- package/dist/tempo/client/Charge.d.ts +6 -4
- package/dist/tempo/client/Charge.js +61 -28
- package/dist/tempo/client/Methods.d.ts +5 -3
- package/dist/tempo/index.d.ts +2 -1
- package/dist/tempo/index.js +2 -1
- package/dist/tempo/internal/defaults.d.ts +11 -0
- package/dist/tempo/internal/defaults.js +11 -0
- package/dist/tempo/internal/machine-token-charge.d.ts +56 -0
- package/dist/tempo/internal/machine-token-charge.js +108 -0
- package/dist/tempo/server/Charge.d.ts +3 -0
- package/dist/tempo/server/Charge.js +68 -36
- package/dist/tempo/server/Methods.d.ts +9 -4
- package/dist/tempo/server/Methods.js +5 -2
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/package.json +1 -1
- package/dist/tempo/Tokens.d.ts +0 -13
- package/dist/tempo/Tokens.js +0 -13
package/dist/client/Mppx.d.ts
CHANGED
|
@@ -24,18 +24,23 @@ export type PreparedPayment<methods extends readonly Method.AnyClient[] = readon
|
|
|
24
24
|
/** Attaches a credential using the protocol that produced the selected challenge. */
|
|
25
25
|
setCredential: (request: Transport.RequestOf<transport>, credential: string) => Transport.RequestOf<transport>;
|
|
26
26
|
}>;
|
|
27
|
-
/**
|
|
28
|
-
export type PreparedRequest<methods extends readonly Method.AnyClient[]> = Readonly<
|
|
29
|
-
/** Exact request that
|
|
27
|
+
/** An HTTP request prepared together with its response and optional payment. */
|
|
28
|
+
export type PreparedRequest<methods extends readonly Method.AnyClient[], requirePayment extends boolean = false> = Readonly<{
|
|
29
|
+
/** Exact request that produced {@link response}. */
|
|
30
30
|
request: Request;
|
|
31
|
-
/**
|
|
31
|
+
/** Response returned for {@link request}. */
|
|
32
32
|
response: Response;
|
|
33
|
-
/** Redirects followed before receiving
|
|
33
|
+
/** Redirects followed before receiving {@link response}. */
|
|
34
34
|
redirects: readonly PreparedRequest.Redirect[];
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/** Selected payment when the response requires payment. */
|
|
36
|
+
payment: requirePayment extends true ? PreparedRequest.Payment<methods> : PreparedRequest.Payment<methods> | undefined;
|
|
37
37
|
}>;
|
|
38
38
|
export declare namespace PreparedRequest {
|
|
39
|
+
/** A request-bound payment that can be inspected or paid. */
|
|
40
|
+
type Payment<methods extends readonly Method.AnyClient[]> = Readonly<PreparedPayment<methods, Transport.Transport<RequestInit, Response>> & {
|
|
41
|
+
/** Creates and sends a credential to the prepared request without following redirects. */
|
|
42
|
+
pay: (context?: AnyContextFor<methods> | undefined) => Promise<Response>;
|
|
43
|
+
}>;
|
|
39
44
|
/** A redirect followed while discovering a payment challenge. */
|
|
40
45
|
type Redirect = Readonly<{
|
|
41
46
|
from: string;
|
|
@@ -70,11 +75,17 @@ export type Mppx<methods extends Methods = Methods, transport extends Transport.
|
|
|
70
75
|
*/
|
|
71
76
|
preparePayment: (response: Transport.ResponseOf<transport>, options?: preparePayment.Options<FlattenMethods<methods>, transport> | undefined) => Promise<PreparedPayment<FlattenMethods<methods>, transport>>;
|
|
72
77
|
/**
|
|
73
|
-
* Follows safe pre-payment redirects and
|
|
74
|
-
*
|
|
75
|
-
*
|
|
78
|
+
* Follows safe pre-payment redirects and returns the response with its exact request. When the
|
|
79
|
+
* response requires payment, prepares its selected challenge without creating a credential.
|
|
80
|
+
* Credential-bearing requests never follow redirects. Requires a runtime that exposes manual
|
|
81
|
+
* redirect responses; browsers return opaque redirects and are not supported.
|
|
76
82
|
*/
|
|
77
|
-
prepareRequest: transport extends Transport.Transport<RequestInit, Response> ?
|
|
83
|
+
prepareRequest: transport extends Transport.Transport<RequestInit, Response> ? {
|
|
84
|
+
<const requirePayment extends boolean>(input: RequestInfo | URL, init: RequestInit | undefined, options: prepareRequest.Options<FlattenMethods<methods>, requirePayment> & {
|
|
85
|
+
requirePayment: requirePayment;
|
|
86
|
+
}): Promise<PreparedRequest<FlattenMethods<methods>, requirePayment>>;
|
|
87
|
+
(input: RequestInfo | URL, init?: RequestInit | undefined, options?: prepareRequest.Options<FlattenMethods<methods>> | undefined): Promise<PreparedRequest<FlattenMethods<methods>>>;
|
|
88
|
+
} : never;
|
|
78
89
|
/** Creates a credential from a payment-required response by routing to the correct method. */
|
|
79
90
|
createCredential: (response: Transport.ResponseOf<transport>, context?: AnyContextFor<FlattenMethods<methods>> | undefined, options?: createCredential.Options<FlattenMethods<methods>, transport> | undefined) => Promise<string>;
|
|
80
91
|
/** Register a client event handler by canonical event name. */
|
|
@@ -116,9 +127,11 @@ export declare namespace preparePayment {
|
|
|
116
127
|
}
|
|
117
128
|
export declare namespace prepareRequest {
|
|
118
129
|
/** Options for preparing a request-bound payment. */
|
|
119
|
-
type Options<methods extends readonly Method.AnyClient[] = readonly Method.AnyClient[]> = Omit<preparePayment.Options<methods, Transport.Transport<RequestInit, Response>>, 'request'> & {
|
|
130
|
+
type Options<methods extends readonly Method.AnyClient[] = readonly Method.AnyClient[], requirePayment extends boolean = false> = Omit<preparePayment.Options<methods, Transport.Transport<RequestInit, Response>>, 'request'> & {
|
|
120
131
|
/** Maximum redirects followed before rejecting the request. @default 20 */
|
|
121
132
|
maxRedirects?: number | undefined;
|
|
133
|
+
/** Throw when the response does not require payment. @default false */
|
|
134
|
+
requirePayment?: requirePayment | undefined;
|
|
122
135
|
};
|
|
123
136
|
}
|
|
124
137
|
export declare namespace createCredential {
|
package/dist/client/Mppx.js
CHANGED
|
@@ -148,7 +148,7 @@ export function create(config) {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
async function prepareRequest(input, init, options) {
|
|
151
|
-
const { maxRedirects = 20, ...paymentOptions } = options ?? {};
|
|
151
|
+
const { maxRedirects = 20, requirePayment = false, ...paymentOptions } = options ?? {};
|
|
152
152
|
const preparedHttp = await prepareHttpRequest({
|
|
153
153
|
acceptPayment: acceptPayment.header,
|
|
154
154
|
acceptPaymentPolicy,
|
|
@@ -159,8 +159,16 @@ export function create(config) {
|
|
|
159
159
|
signer: attestationSigner,
|
|
160
160
|
});
|
|
161
161
|
const requestInit = requestToInit(preparedHttp.replayRequest, preparedHttp.body);
|
|
162
|
-
if (!(await transport.isPaymentRequired(preparedHttp.response, requestInit)))
|
|
163
|
-
|
|
162
|
+
if (!(await transport.isPaymentRequired(preparedHttp.response, requestInit))) {
|
|
163
|
+
if (requirePayment)
|
|
164
|
+
throw new Error('Response does not require payment.');
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
payment: undefined,
|
|
167
|
+
request: preparedHttp.request,
|
|
168
|
+
response: preparedHttp.response,
|
|
169
|
+
redirects: preparedHttp.redirects,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
164
172
|
const payment = (await preparePayment(preparedHttp.response, {
|
|
165
173
|
...paymentOptions,
|
|
166
174
|
request: requestInit,
|
|
@@ -176,12 +184,9 @@ export function create(config) {
|
|
|
176
184
|
});
|
|
177
185
|
return payment.createCredential(context);
|
|
178
186
|
});
|
|
179
|
-
|
|
187
|
+
const preparedPayment = Object.freeze({
|
|
180
188
|
...payment,
|
|
181
189
|
createCredential: createRequestCredential,
|
|
182
|
-
request: preparedHttp.request,
|
|
183
|
-
response: preparedHttp.response,
|
|
184
|
-
redirects: preparedHttp.redirects,
|
|
185
190
|
async pay(context) {
|
|
186
191
|
const credential = await createRequestCredential(context);
|
|
187
192
|
const paidInit = payment.setCredential(requestToInit(preparedHttp.replayRequest, preparedHttp.body), credential);
|
|
@@ -191,6 +196,12 @@ export function create(config) {
|
|
|
191
196
|
});
|
|
192
197
|
},
|
|
193
198
|
});
|
|
199
|
+
return Object.freeze({
|
|
200
|
+
payment: preparedPayment,
|
|
201
|
+
request: preparedHttp.request,
|
|
202
|
+
response: preparedHttp.response,
|
|
203
|
+
redirects: preparedHttp.redirects,
|
|
204
|
+
});
|
|
194
205
|
}
|
|
195
206
|
return {
|
|
196
207
|
fetch,
|
|
@@ -17,8 +17,6 @@ export function x402() {
|
|
|
17
17
|
if (!header)
|
|
18
18
|
return [];
|
|
19
19
|
const paymentRequired = x402_Header.decodePaymentRequiredEnvelope(header);
|
|
20
|
-
if (response.url && paymentRequired.resource.url !== response.url)
|
|
21
|
-
throw new Error('x402 payment-required resource does not match response URL.');
|
|
22
20
|
return paymentRequired.accepts.flatMap((rawAccepted, index) => {
|
|
23
21
|
const parsed = x402_Types.PaymentRequirementsSchema.safeParse(rawAccepted);
|
|
24
22
|
if (!parsed.success)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Current mppx package version. */
|
|
2
|
-
export declare const version = "0.
|
|
2
|
+
export declare const version = "0.11.0";
|
|
3
3
|
/** Canonical SDK identifier for this mppx release. */
|
|
4
|
-
export declare const sdkIdentifier = "mppx/0.
|
|
4
|
+
export declare const sdkIdentifier = "mppx/0.11.0";
|
|
5
5
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/internal/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by scripts/sync-version.ts.
|
|
2
2
|
/** Current mppx package version. */
|
|
3
|
-
export const version = '0.
|
|
3
|
+
export const version = '0.11.0';
|
|
4
4
|
/** Canonical SDK identifier for this mppx release. */
|
|
5
5
|
export const sdkIdentifier = `mppx/${version}`;
|
|
6
6
|
//# sourceMappingURL=version.js.map
|
|
@@ -121,13 +121,21 @@ export function stripe(parameters) {
|
|
|
121
121
|
}));
|
|
122
122
|
}
|
|
123
123
|
function makeTempoSession(params) {
|
|
124
|
-
const { recipient, ...rest } = params;
|
|
124
|
+
const { recipient, onSessionSettlement, ...rest } = params;
|
|
125
125
|
return tempoSession({
|
|
126
126
|
currency: tempoCurrency,
|
|
127
127
|
recipient,
|
|
128
128
|
...(!livemode && { testnet: true }),
|
|
129
129
|
...(hostedTempoFeePayer && { feePayer: hostedTempoFeePayer }),
|
|
130
130
|
...rest,
|
|
131
|
+
async onSessionSettlement(context) {
|
|
132
|
+
await tempoPaymentHandler({
|
|
133
|
+
intent: 'session',
|
|
134
|
+
receipt: { reference: context.txHash },
|
|
135
|
+
request: { amount: context.delta.toString() },
|
|
136
|
+
});
|
|
137
|
+
await onSessionSettlement?.(context);
|
|
138
|
+
},
|
|
131
139
|
});
|
|
132
140
|
}
|
|
133
141
|
function makeBaseCharge(params) {
|
|
@@ -283,7 +291,7 @@ function customRails(additional) {
|
|
|
283
291
|
}
|
|
284
292
|
function createPaymentSuccessHandler(client, network, connect, metadata) {
|
|
285
293
|
return (params) => {
|
|
286
|
-
const { challenge, receipt, request, requestInput } = params;
|
|
294
|
+
const { challenge, intent, receipt, request, requestInput } = params;
|
|
287
295
|
if (receipt?.reference && request?.amount) {
|
|
288
296
|
const paymentIntentOptionsInput = requestInput?.paymentIntentOptions;
|
|
289
297
|
const paymentIntentOptions = typeof paymentIntentOptionsInput === 'function' ? undefined : paymentIntentOptionsInput;
|
|
@@ -300,7 +308,7 @@ function createPaymentSuccessHandler(client, network, connect, metadata) {
|
|
|
300
308
|
reference: receipt.reference,
|
|
301
309
|
amount: String(request.amount),
|
|
302
310
|
...(connect && { connect }),
|
|
303
|
-
analyticsMetadata: buildAnalytics({ challenge }),
|
|
311
|
+
analyticsMetadata: buildAnalytics({ challenge, intent }),
|
|
304
312
|
...(Object.keys(resolvedPaymentIntentOptions).length > 0 && {
|
|
305
313
|
paymentIntentOptions: resolvedPaymentIntentOptions,
|
|
306
314
|
}),
|
|
@@ -2,5 +2,6 @@ import type * as Challenge from '../../../Challenge.js';
|
|
|
2
2
|
/** Builds Stripe metadata used to identify and analyze MPP payments. */
|
|
3
3
|
export declare function buildAnalytics(parameters: {
|
|
4
4
|
challenge?: Pick<Challenge.Challenge, 'id' | 'intent'> | undefined;
|
|
5
|
+
intent?: string | undefined;
|
|
5
6
|
}): Record<string, string>;
|
|
6
7
|
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -2,13 +2,13 @@ import { sdkIdentifier } from '../../../internal/version.js';
|
|
|
2
2
|
import { machinePaymentMetadata } from '../../internal/constants.js';
|
|
3
3
|
/** Builds Stripe metadata used to identify and analyze MPP payments. */
|
|
4
4
|
export function buildAnalytics(parameters) {
|
|
5
|
-
const { challenge } = parameters;
|
|
5
|
+
const { challenge, intent = challenge?.intent } = parameters;
|
|
6
6
|
const metadata = {
|
|
7
7
|
...machinePaymentMetadata,
|
|
8
8
|
mpp_sdk: sdkIdentifier,
|
|
9
|
+
...(intent && { mpp_intent: intent }),
|
|
9
10
|
...(challenge && {
|
|
10
11
|
mpp_challenge_id: challenge.id,
|
|
11
|
-
mpp_intent: challenge.intent,
|
|
12
12
|
}),
|
|
13
13
|
};
|
|
14
14
|
return Object.fromEntries(Object.entries(metadata).map(([key, value]) => [key, [...value].slice(0, 500).join('')]));
|
|
@@ -13,9 +13,9 @@ export function recordCryptoPayment(client, parameters) {
|
|
|
13
13
|
const { network, reference, amount, connect, analyticsMetadata, paymentIntentOptions } = parameters;
|
|
14
14
|
const { customer, hooks, metadata, receipt_email } = paymentIntentOptions ?? {};
|
|
15
15
|
const { stripeNetworkName, tokenDecimals } = NETWORK_CONFIG[network];
|
|
16
|
-
const amountCents =
|
|
16
|
+
const amountCents = Number(BigInt(amount) / 10n ** BigInt(tokenDecimals - 2));
|
|
17
17
|
if (amountCents < 1) {
|
|
18
|
-
console.warn(`[stripe] skipping PI recording: ${amount} raw units on ${network}
|
|
18
|
+
console.warn(`[stripe] skipping PI recording: ${amount} raw units on ${network} floors to ${amountCents} cents (below Stripe minimum)`);
|
|
19
19
|
return Promise.resolve();
|
|
20
20
|
}
|
|
21
21
|
const requiredParams = {
|
package/dist/tempo/Methods.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare const charge: {
|
|
|
35
35
|
}, z.core.$strip>], "type">;
|
|
36
36
|
};
|
|
37
37
|
request: z.ZodMiniPipe<z.ZodMiniObject<{
|
|
38
|
+
machineTokenEnabled: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
38
39
|
amount: z.ZodMiniString<string>;
|
|
39
40
|
chainId: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
40
41
|
currency: z.ZodMiniString<string>;
|
|
@@ -42,7 +43,7 @@ export declare const charge: {
|
|
|
42
43
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
43
44
|
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
44
45
|
feePayer: z.ZodMiniOptional<z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniCustom<Account, Account>]>, z.ZodMiniTransform<boolean, boolean | Account>>>;
|
|
45
|
-
memo: z.ZodMiniOptional<z.
|
|
46
|
+
memo: z.ZodMiniOptional<z.ZodMiniNever>;
|
|
46
47
|
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
47
48
|
splits: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniObject<{
|
|
48
49
|
amount: z.ZodMiniString<string>;
|
|
@@ -60,9 +61,9 @@ export declare const charge: {
|
|
|
60
61
|
recipient?: string | undefined;
|
|
61
62
|
amount: string;
|
|
62
63
|
methodDetails?: {
|
|
64
|
+
machineTokenEnabled?: boolean | undefined;
|
|
63
65
|
chainId?: number | undefined;
|
|
64
66
|
feePayer?: boolean | undefined;
|
|
65
|
-
memo?: string | undefined;
|
|
66
67
|
splits?: {
|
|
67
68
|
memo?: string | undefined;
|
|
68
69
|
recipient: `0x${string}`;
|
|
@@ -71,6 +72,7 @@ export declare const charge: {
|
|
|
71
72
|
supportedModes?: ("pull" | "push")[] | undefined;
|
|
72
73
|
} | undefined;
|
|
73
74
|
}, {
|
|
75
|
+
machineTokenEnabled?: boolean | undefined;
|
|
74
76
|
amount: string;
|
|
75
77
|
chainId?: number | undefined;
|
|
76
78
|
currency: string;
|
|
@@ -78,7 +80,7 @@ export declare const charge: {
|
|
|
78
80
|
description?: string | undefined;
|
|
79
81
|
externalId?: string | undefined;
|
|
80
82
|
feePayer?: boolean | undefined;
|
|
81
|
-
memo?:
|
|
83
|
+
memo?: undefined;
|
|
82
84
|
recipient?: string | undefined;
|
|
83
85
|
splits?: {
|
|
84
86
|
amount: string;
|
package/dist/tempo/Methods.js
CHANGED
|
@@ -82,6 +82,7 @@ export const charge = Method.from({
|
|
|
82
82
|
},
|
|
83
83
|
request: z.pipe(z
|
|
84
84
|
.object({
|
|
85
|
+
machineTokenEnabled: z.optional(z.boolean()),
|
|
85
86
|
amount: z.amount(),
|
|
86
87
|
chainId: z.optional(z.number()),
|
|
87
88
|
currency: z.string(),
|
|
@@ -89,7 +90,7 @@ export const charge = Method.from({
|
|
|
89
90
|
description: z.optional(z.string()),
|
|
90
91
|
externalId: z.optional(z.string()),
|
|
91
92
|
feePayer: z.optional(z.pipe(z.union([z.boolean(), z.custom()]), z.transform((v) => (typeof v === 'object' ? true : v)))),
|
|
92
|
-
memo: z.optional(z.
|
|
93
|
+
memo: z.optional(z.never()),
|
|
93
94
|
recipient: z.optional(z.string()),
|
|
94
95
|
splits: z.optional(z.array(split).check(z.minLength(1), z.maxLength(10))),
|
|
95
96
|
supportedModes: z.optional(z.array(z.enum(chargeModes)).check(z.minLength(1))),
|
|
@@ -101,19 +102,19 @@ export const charge = Method.from({
|
|
|
101
102
|
const splitTotal = splits.reduce((sum, split) => sum + parseUnits(split.amount, decimals), 0n);
|
|
102
103
|
return (splits.every((split) => parseUnits(split.amount, decimals) > 0n) &&
|
|
103
104
|
splitTotal < totalAmount);
|
|
104
|
-
}, 'Invalid splits')), z.transform(({ amount, chainId, decimals, feePayer, memo, splits, supportedModes, ...rest }) => ({
|
|
105
|
+
}, 'Invalid splits')), z.transform(({ machineTokenEnabled, amount, chainId, decimals, feePayer, memo: _memo, splits, supportedModes, ...rest }) => ({
|
|
105
106
|
...rest,
|
|
106
107
|
amount: parseUnits(amount, decimals).toString(),
|
|
107
|
-
...(
|
|
108
|
+
...(machineTokenEnabled !== undefined ||
|
|
109
|
+
chainId !== undefined ||
|
|
108
110
|
feePayer !== undefined ||
|
|
109
|
-
memo !== undefined ||
|
|
110
111
|
splits !== undefined ||
|
|
111
112
|
supportedModes !== undefined
|
|
112
113
|
? {
|
|
113
114
|
methodDetails: {
|
|
115
|
+
...(machineTokenEnabled !== undefined && { machineTokenEnabled }),
|
|
114
116
|
...(chainId !== undefined && { chainId }),
|
|
115
117
|
...(feePayer !== undefined && { feePayer }),
|
|
116
|
-
...(memo !== undefined && { memo }),
|
|
117
118
|
...(splits !== undefined && {
|
|
118
119
|
splits: splits.map((split) => ({
|
|
119
120
|
...split,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Address } from 'viem';
|
|
2
2
|
import * as Method from '../../Method.js';
|
|
3
3
|
import * as Account from '../../viem/Account.js';
|
|
4
4
|
import * as Client from '../../viem/Client.js';
|
|
@@ -42,6 +42,7 @@ export declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
|
42
42
|
}, z.core.$strip>], "type">;
|
|
43
43
|
};
|
|
44
44
|
request: z.ZodMiniPipe<z.ZodMiniObject<{
|
|
45
|
+
machineTokenEnabled: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
45
46
|
amount: z.ZodMiniString<string>;
|
|
46
47
|
chainId: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
47
48
|
currency: z.ZodMiniString<string>;
|
|
@@ -49,7 +50,7 @@ export declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
|
49
50
|
description: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
50
51
|
externalId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
51
52
|
feePayer: z.ZodMiniOptional<z.ZodMiniPipe<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniCustom<import("viem").Account, import("viem").Account>]>, z.ZodMiniTransform<boolean, boolean | import("viem").Account>>>;
|
|
52
|
-
memo: z.ZodMiniOptional<z.
|
|
53
|
+
memo: z.ZodMiniOptional<z.ZodMiniNever>;
|
|
53
54
|
recipient: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
54
55
|
splits: z.ZodMiniOptional<z.ZodMiniArray<z.ZodMiniObject<{
|
|
55
56
|
amount: z.ZodMiniString<string>;
|
|
@@ -67,9 +68,9 @@ export declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
|
67
68
|
recipient?: string | undefined;
|
|
68
69
|
amount: string;
|
|
69
70
|
methodDetails?: {
|
|
71
|
+
machineTokenEnabled?: boolean | undefined;
|
|
70
72
|
chainId?: number | undefined;
|
|
71
73
|
feePayer?: boolean | undefined;
|
|
72
|
-
memo?: string | undefined;
|
|
73
74
|
splits?: {
|
|
74
75
|
memo?: string | undefined;
|
|
75
76
|
recipient: `0x${string}`;
|
|
@@ -78,6 +79,7 @@ export declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
|
78
79
|
supportedModes?: ("pull" | "push")[] | undefined;
|
|
79
80
|
} | undefined;
|
|
80
81
|
}, {
|
|
82
|
+
machineTokenEnabled?: boolean | undefined;
|
|
81
83
|
amount: string;
|
|
82
84
|
chainId?: number | undefined;
|
|
83
85
|
currency: string;
|
|
@@ -85,7 +87,7 @@ export declare function charge(parameters?: charge.Parameters): Method.Client<{
|
|
|
85
87
|
description?: string | undefined;
|
|
86
88
|
externalId?: string | undefined;
|
|
87
89
|
feePayer?: boolean | undefined;
|
|
88
|
-
memo?:
|
|
90
|
+
memo?: undefined;
|
|
89
91
|
recipient?: string | undefined;
|
|
90
92
|
splits?: {
|
|
91
93
|
amount: string;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isAddressEqual } from 'viem';
|
|
2
1
|
import { prepareTransactionRequest, sendCallsSync, sendTransactionSync, signTypedData, signTransaction, } from 'viem/actions';
|
|
3
2
|
import { Actions } from 'viem/tempo';
|
|
4
3
|
import { tempo as tempo_chain } from 'viem/tempo/chains';
|
|
@@ -12,9 +11,9 @@ import * as AutoSwap from '../internal/auto-swap.js';
|
|
|
12
11
|
import * as Charge_internal from '../internal/charge.js';
|
|
13
12
|
import * as defaults from '../internal/defaults.js';
|
|
14
13
|
import { defaultFeeTokens, resolveFeeToken } from '../internal/fee-token.js';
|
|
14
|
+
import * as MachineTokenCharge from '../internal/machine-token-charge.js';
|
|
15
15
|
import * as Proof from '../internal/proof.js';
|
|
16
16
|
import * as Methods from '../Methods.js';
|
|
17
|
-
import { mach } from '../Tokens.js';
|
|
18
17
|
const chargeContextSchema = z.object({
|
|
19
18
|
account: z.optional(z.custom()),
|
|
20
19
|
autoSwap: z.optional(z.custom()),
|
|
@@ -98,9 +97,12 @@ export function charge(parameters = {}) {
|
|
|
98
97
|
});
|
|
99
98
|
}
|
|
100
99
|
const currency = request.currency;
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
const isMachineTokenCurrency = MachineTokenCharge.isMachineToken({ chainId, currency });
|
|
101
|
+
const memo = Attribution.encode({
|
|
102
|
+
challengeId: challenge.id,
|
|
103
|
+
clientId,
|
|
104
|
+
serverId: challenge.realm,
|
|
105
|
+
});
|
|
104
106
|
const transfers = Charge_internal.getTransfers({
|
|
105
107
|
amount,
|
|
106
108
|
methodDetails: {
|
|
@@ -116,14 +118,66 @@ export function charge(parameters = {}) {
|
|
|
116
118
|
token: currency,
|
|
117
119
|
}));
|
|
118
120
|
const autoSwap = AutoSwap.resolve(context?.autoSwap ?? parameters.autoSwap, AutoSwap.defaultCurrencies);
|
|
119
|
-
const
|
|
121
|
+
const machineTokenEnabled = methodDetails?.machineTokenEnabled === true;
|
|
122
|
+
const resolveAccount = async (calls) => (await parameters.resolveAccount?.({
|
|
120
123
|
account: defaultAccount,
|
|
121
124
|
chainId,
|
|
122
125
|
operation: {
|
|
123
126
|
kind: 'executeCalls',
|
|
124
|
-
...(
|
|
127
|
+
...(calls ? { calls } : {}),
|
|
125
128
|
},
|
|
126
129
|
})) ?? defaultAccount;
|
|
130
|
+
const machineTokenCandidate = machineTokenEnabled
|
|
131
|
+
? MachineTokenCharge.getRoute({ chainId, currency, transfers })
|
|
132
|
+
: undefined;
|
|
133
|
+
let account = defaultAccount;
|
|
134
|
+
let machineTokenRoute;
|
|
135
|
+
if (machineTokenCandidate) {
|
|
136
|
+
const machineTokenAccount = await (async () => {
|
|
137
|
+
try {
|
|
138
|
+
return await resolveAccount(machineTokenCandidate.calls);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// A machine-token route is optional. A scoped account that cannot
|
|
142
|
+
// execute it may still be able to satisfy the direct payment.
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
})();
|
|
146
|
+
if (machineTokenAccount) {
|
|
147
|
+
machineTokenRoute = await MachineTokenCharge.findRoute(client, {
|
|
148
|
+
account: machineTokenAccount.address,
|
|
149
|
+
chainId,
|
|
150
|
+
currency,
|
|
151
|
+
transfers,
|
|
152
|
+
});
|
|
153
|
+
if (machineTokenRoute)
|
|
154
|
+
account = machineTokenAccount;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
let swapCalls;
|
|
158
|
+
if (!machineTokenRoute) {
|
|
159
|
+
account = await resolveAccount(autoSwap ? undefined : transferCalls);
|
|
160
|
+
swapCalls = autoSwap
|
|
161
|
+
? await AutoSwap.findCalls(client, {
|
|
162
|
+
account: account.address,
|
|
163
|
+
amountOut: BigInt(amount),
|
|
164
|
+
tokenOut: currency,
|
|
165
|
+
tokenIn: autoSwap.tokenIn,
|
|
166
|
+
slippage: autoSwap.slippage,
|
|
167
|
+
})
|
|
168
|
+
: undefined;
|
|
169
|
+
}
|
|
170
|
+
const calls = machineTokenRoute?.calls ?? [...(swapCalls ?? []), ...transferCalls];
|
|
171
|
+
const allowedFeeTokens = defaultFeeTokens(chainId);
|
|
172
|
+
const feeToken = machineTokenRoute || isMachineTokenCurrency
|
|
173
|
+
? await resolveFeeToken({
|
|
174
|
+
account: account.address,
|
|
175
|
+
allowedTokens: allowedFeeTokens,
|
|
176
|
+
candidateTokens: allowedFeeTokens,
|
|
177
|
+
client,
|
|
178
|
+
prioritizeCandidates: true,
|
|
179
|
+
})
|
|
180
|
+
: undefined;
|
|
127
181
|
const mode = (() => {
|
|
128
182
|
const explicitMode = context?.mode ?? parameters.mode;
|
|
129
183
|
if (explicitMode) {
|
|
@@ -136,27 +190,6 @@ export function charge(parameters = {}) {
|
|
|
136
190
|
return preferredMode;
|
|
137
191
|
return supportedModes[0];
|
|
138
192
|
})();
|
|
139
|
-
const swapCalls = autoSwap
|
|
140
|
-
? await AutoSwap.findCalls(client, {
|
|
141
|
-
account: account.address,
|
|
142
|
-
amountOut: BigInt(amount),
|
|
143
|
-
tokenOut: currency,
|
|
144
|
-
tokenIn: autoSwap.tokenIn,
|
|
145
|
-
slippage: autoSwap.slippage,
|
|
146
|
-
})
|
|
147
|
-
: undefined;
|
|
148
|
-
const calls = [...(swapCalls ?? []), ...transferCalls];
|
|
149
|
-
const machAddress = mach.addresses[chainId];
|
|
150
|
-
const allowedFeeTokens = defaultFeeTokens(chainId);
|
|
151
|
-
const feeToken = machAddress && isAddressEqual(currency, machAddress)
|
|
152
|
-
? await resolveFeeToken({
|
|
153
|
-
account: account.address,
|
|
154
|
-
allowedTokens: allowedFeeTokens,
|
|
155
|
-
candidateTokens: allowedFeeTokens,
|
|
156
|
-
client,
|
|
157
|
-
prioritizeCandidates: true,
|
|
158
|
-
})
|
|
159
|
-
: undefined;
|
|
160
193
|
const validBefore = (() => {
|
|
161
194
|
const defaultExpiry = Math.floor(Date.now() / 1000) + 25;
|
|
162
195
|
if (!challenge.expires)
|
|
@@ -37,6 +37,7 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
37
37
|
}, import("zod/v4/core").$strip>], "type">;
|
|
38
38
|
};
|
|
39
39
|
request: import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniObject<{
|
|
40
|
+
machineTokenEnabled: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniBoolean<boolean>>;
|
|
40
41
|
amount: import("zod/mini").ZodMiniString<string>;
|
|
41
42
|
chainId: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNumber<number>>;
|
|
42
43
|
currency: import("zod/mini").ZodMiniString<string>;
|
|
@@ -44,7 +45,7 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
44
45
|
description: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
45
46
|
externalId: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
46
47
|
feePayer: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniPipe<import("zod/mini").ZodMiniUnion<readonly [import("zod/mini").ZodMiniBoolean<boolean>, import("zod/mini").ZodMiniCustom<import("viem").Account, import("viem").Account>]>, import("zod/mini").ZodMiniTransform<boolean, boolean | import("viem").Account>>>;
|
|
47
|
-
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").
|
|
48
|
+
memo: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniNever>;
|
|
48
49
|
recipient: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniString<string>>;
|
|
49
50
|
splits: import("zod/mini").ZodMiniOptional<import("zod/mini").ZodMiniArray<import("zod/mini").ZodMiniObject<{
|
|
50
51
|
amount: import("zod/mini").ZodMiniString<string>;
|
|
@@ -62,9 +63,9 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
62
63
|
recipient?: string | undefined;
|
|
63
64
|
amount: string;
|
|
64
65
|
methodDetails?: {
|
|
66
|
+
machineTokenEnabled?: boolean | undefined;
|
|
65
67
|
chainId?: number | undefined;
|
|
66
68
|
feePayer?: boolean | undefined;
|
|
67
|
-
memo?: string | undefined;
|
|
68
69
|
splits?: {
|
|
69
70
|
memo?: string | undefined;
|
|
70
71
|
recipient: `0x${string}`;
|
|
@@ -73,6 +74,7 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
73
74
|
supportedModes?: ("pull" | "push")[] | undefined;
|
|
74
75
|
} | undefined;
|
|
75
76
|
}, {
|
|
77
|
+
machineTokenEnabled?: boolean | undefined;
|
|
76
78
|
amount: string;
|
|
77
79
|
chainId?: number | undefined;
|
|
78
80
|
currency: string;
|
|
@@ -80,7 +82,7 @@ export declare function tempo(parameters?: tempo.Parameters): readonly [import("
|
|
|
80
82
|
description?: string | undefined;
|
|
81
83
|
externalId?: string | undefined;
|
|
82
84
|
feePayer?: boolean | undefined;
|
|
83
|
-
memo?:
|
|
85
|
+
memo?: undefined;
|
|
84
86
|
recipient?: string | undefined;
|
|
85
87
|
splits?: {
|
|
86
88
|
amount: string;
|
package/dist/tempo/index.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export * as Methods from './Methods.js';
|
|
|
3
3
|
export * as Session from './session/index.js';
|
|
4
4
|
export * as SessionLegacy from './legacy/index.js';
|
|
5
5
|
export * as Subscription from './subscription/index.js';
|
|
6
|
-
|
|
6
|
+
/** Canonical first-party machine-token deployments by Tempo chain ID. */
|
|
7
|
+
export { machineToken as machineTokenDeployments } from './internal/defaults.js';
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/tempo/index.js
CHANGED
|
@@ -3,5 +3,6 @@ export * as Methods from './Methods.js';
|
|
|
3
3
|
export * as Session from './session/index.js';
|
|
4
4
|
export * as SessionLegacy from './legacy/index.js';
|
|
5
5
|
export * as Subscription from './subscription/index.js';
|
|
6
|
-
|
|
6
|
+
/** Canonical first-party machine-token deployments by Tempo chain ID. */
|
|
7
|
+
export { machineToken as machineTokenDeployments } from './internal/defaults.js';
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -16,6 +16,17 @@ export declare const currency: {
|
|
|
16
16
|
readonly 4217: "0x20C000000000000000000000b9537d11c60E8b50";
|
|
17
17
|
readonly 42431: "0x20c0000000000000000000000000000000000000";
|
|
18
18
|
};
|
|
19
|
+
/** Immutable canonical first-party machine-token deployments used by charge routes. */
|
|
20
|
+
export declare const machineToken: Readonly<{
|
|
21
|
+
readonly 4217: Readonly<{
|
|
22
|
+
swap: "0xF72E5107c32C655ffA7539a3C8e97B7C3cE16A3F";
|
|
23
|
+
token: "0x20c000000000000000000000f37de3740ADec032";
|
|
24
|
+
}>;
|
|
25
|
+
readonly 42431: Readonly<{
|
|
26
|
+
swap: "0xd05f8EdFBB54Da0d765C9fE9b2B3f7d2E3a8C466";
|
|
27
|
+
token: "0x20c000000000000000000000f37de3740ADec032";
|
|
28
|
+
}>;
|
|
29
|
+
}>;
|
|
19
30
|
/**
|
|
20
31
|
* Default token decimals for TIP-20 stablecoins (e.g. pathUSD, USDC).
|
|
21
32
|
*
|
|
@@ -14,6 +14,17 @@ export const currency = {
|
|
|
14
14
|
[chainId.mainnet]: tokens.usdc,
|
|
15
15
|
[chainId.testnet]: tokens.pathUsd,
|
|
16
16
|
};
|
|
17
|
+
/** Immutable canonical first-party machine-token deployments used by charge routes. */
|
|
18
|
+
export const machineToken = Object.freeze({
|
|
19
|
+
[chainId.mainnet]: Object.freeze({
|
|
20
|
+
swap: '0xF72E5107c32C655ffA7539a3C8e97B7C3cE16A3F',
|
|
21
|
+
token: '0x20c000000000000000000000f37de3740ADec032',
|
|
22
|
+
}),
|
|
23
|
+
[chainId.testnet]: Object.freeze({
|
|
24
|
+
swap: '0xd05f8EdFBB54Da0d765C9fE9b2B3f7d2E3a8C466',
|
|
25
|
+
token: '0x20c000000000000000000000f37de3740ADec032',
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
17
28
|
/**
|
|
18
29
|
* Default token decimals for TIP-20 stablecoins (e.g. pathUSD, USDC).
|
|
19
30
|
*
|