mppx 0.10.1 → 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 +13 -0
- package/dist/cli/cli.js +134 -134
- package/dist/cli/plugins/index.js +12 -12
- 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
|
@@ -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
|
*
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type * as Hex from 'ox/Hex';
|
|
2
|
+
import { type Address, type Client } from 'viem';
|
|
3
|
+
type Call = {
|
|
4
|
+
data?: Hex.Hex | undefined;
|
|
5
|
+
to?: Address | undefined;
|
|
6
|
+
value?: bigint | undefined;
|
|
7
|
+
};
|
|
8
|
+
type RouteCall = {
|
|
9
|
+
data: Hex.Hex;
|
|
10
|
+
to: Address;
|
|
11
|
+
};
|
|
12
|
+
type Route = {
|
|
13
|
+
calls: readonly [RouteCall, RouteCall];
|
|
14
|
+
settlementSender: Address;
|
|
15
|
+
transfers: readonly [{
|
|
16
|
+
amount: bigint;
|
|
17
|
+
memo: Hex.Hex;
|
|
18
|
+
recipient: Address;
|
|
19
|
+
}];
|
|
20
|
+
};
|
|
21
|
+
type Transfer = {
|
|
22
|
+
amount: bigint | string;
|
|
23
|
+
memo?: string | undefined;
|
|
24
|
+
recipient: Address;
|
|
25
|
+
};
|
|
26
|
+
/** Returns whether a first-party machine-token charge route is deployed on a chain. */
|
|
27
|
+
export declare function isSupported(chainId: number | undefined): boolean;
|
|
28
|
+
/** Returns whether a currency is the machine token for a supported chain. */
|
|
29
|
+
export declare function isMachineToken(parameters: {
|
|
30
|
+
chainId: number | undefined;
|
|
31
|
+
currency: Address;
|
|
32
|
+
}): boolean;
|
|
33
|
+
/** Resolves the canonical first-party settlement route for a compatible charge. */
|
|
34
|
+
export declare function getRoute(parameters: {
|
|
35
|
+
chainId: number | undefined;
|
|
36
|
+
currency: Address;
|
|
37
|
+
transfers: readonly Transfer[];
|
|
38
|
+
}): Route | undefined;
|
|
39
|
+
/** Builds and simulates the first-party settlement route. */
|
|
40
|
+
export declare function findRoute(client: Client, parameters: {
|
|
41
|
+
account: Address;
|
|
42
|
+
chainId: number;
|
|
43
|
+
currency: Address;
|
|
44
|
+
transfers: readonly Transfer[];
|
|
45
|
+
}): Promise<Route | undefined>;
|
|
46
|
+
/** Matches an exact first-party settlement route. */
|
|
47
|
+
export declare function matchRoute(parameters: {
|
|
48
|
+
calls: readonly Call[];
|
|
49
|
+
chainId: number | undefined;
|
|
50
|
+
currency: Address;
|
|
51
|
+
transfers: readonly Transfer[];
|
|
52
|
+
}): Route | undefined;
|
|
53
|
+
/** Returns the trusted sender that settles the configured charge route on a chain. */
|
|
54
|
+
export declare function getSettlementSender(chainId: number | undefined): Address | undefined;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=machine-token-charge.d.ts.map
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { decodeFunctionData, encodeFunctionData, isAddress, isAddressEqual, parseAbi, } from 'viem';
|
|
2
|
+
import { call, readContract } from 'viem/actions';
|
|
3
|
+
import { Abis, Actions } from 'viem/tempo';
|
|
4
|
+
import * as defaults from './defaults.js';
|
|
5
|
+
const machineTokenSwapperAbi = parseAbi([
|
|
6
|
+
'function swapTo(address inputToken,uint256 amount,address targetToken,address recipient,bytes32 memo)',
|
|
7
|
+
]);
|
|
8
|
+
function getDeployment(chainId) {
|
|
9
|
+
if (chainId === undefined)
|
|
10
|
+
return undefined;
|
|
11
|
+
return defaults.machineToken[chainId];
|
|
12
|
+
}
|
|
13
|
+
/** Returns whether a first-party machine-token charge route is deployed on a chain. */
|
|
14
|
+
export function isSupported(chainId) {
|
|
15
|
+
return !!getDeployment(chainId);
|
|
16
|
+
}
|
|
17
|
+
/** Returns whether a currency is the machine token for a supported chain. */
|
|
18
|
+
export function isMachineToken(parameters) {
|
|
19
|
+
const deployment = getDeployment(parameters.chainId);
|
|
20
|
+
return (!!deployment &&
|
|
21
|
+
isAddress(parameters.currency, { strict: false }) &&
|
|
22
|
+
isAddressEqual(parameters.currency, deployment.token));
|
|
23
|
+
}
|
|
24
|
+
/** Resolves the canonical first-party settlement route for a compatible charge. */
|
|
25
|
+
export function getRoute(parameters) {
|
|
26
|
+
const deployment = getDeployment(parameters.chainId);
|
|
27
|
+
const transfer = parameters.transfers.length === 1 ? parameters.transfers[0] : undefined;
|
|
28
|
+
if (!deployment || !transfer?.memo)
|
|
29
|
+
return undefined;
|
|
30
|
+
const amount = BigInt(transfer.amount);
|
|
31
|
+
const memo = transfer.memo;
|
|
32
|
+
return {
|
|
33
|
+
calls: [
|
|
34
|
+
{
|
|
35
|
+
data: encodeFunctionData({
|
|
36
|
+
abi: Abis.tip20,
|
|
37
|
+
functionName: 'approve',
|
|
38
|
+
args: [deployment.swap, amount],
|
|
39
|
+
}),
|
|
40
|
+
to: deployment.token,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
data: encodeFunctionData({
|
|
44
|
+
abi: machineTokenSwapperAbi,
|
|
45
|
+
functionName: 'swapTo',
|
|
46
|
+
args: [deployment.token, amount, parameters.currency, transfer.recipient, memo],
|
|
47
|
+
}),
|
|
48
|
+
to: deployment.swap,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
settlementSender: deployment.swap,
|
|
52
|
+
transfers: [{ amount, memo, recipient: transfer.recipient }],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Builds and simulates the first-party settlement route. */
|
|
56
|
+
export async function findRoute(client, parameters) {
|
|
57
|
+
const route = getRoute(parameters);
|
|
58
|
+
if (!route)
|
|
59
|
+
return undefined;
|
|
60
|
+
try {
|
|
61
|
+
const balance = await readContract(client, Actions.token.getBalance.call(client, {
|
|
62
|
+
account: parameters.account,
|
|
63
|
+
token: route.calls[0].to,
|
|
64
|
+
}));
|
|
65
|
+
if (balance < route.transfers[0].amount)
|
|
66
|
+
return undefined;
|
|
67
|
+
await call(client, { account: parameters.account, calls: route.calls });
|
|
68
|
+
return route;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Matches an exact first-party settlement route. */
|
|
75
|
+
export function matchRoute(parameters) {
|
|
76
|
+
const transfer = parameters.transfers.length === 1 ? parameters.transfers[0] : undefined;
|
|
77
|
+
const swap = parameters.calls[1];
|
|
78
|
+
if (!transfer || parameters.calls.length !== 2 || !swap?.data)
|
|
79
|
+
return undefined;
|
|
80
|
+
try {
|
|
81
|
+
const decoded = decodeFunctionData({ abi: machineTokenSwapperAbi, data: swap.data });
|
|
82
|
+
const route = getRoute({
|
|
83
|
+
...parameters,
|
|
84
|
+
transfers: [{ ...transfer, memo: transfer.memo ?? decoded.args[4] }],
|
|
85
|
+
});
|
|
86
|
+
if (!route)
|
|
87
|
+
return undefined;
|
|
88
|
+
if (parameters.calls.some((call, index) => {
|
|
89
|
+
const expected = route.calls[index];
|
|
90
|
+
return (!call.data ||
|
|
91
|
+
!call.to ||
|
|
92
|
+
!expected ||
|
|
93
|
+
(call.value ?? 0n) !== 0n ||
|
|
94
|
+
!isAddressEqual(call.to, expected.to) ||
|
|
95
|
+
call.data.toLowerCase() !== expected.data.toLowerCase());
|
|
96
|
+
}))
|
|
97
|
+
return undefined;
|
|
98
|
+
return route;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Returns the trusted sender that settles the configured charge route on a chain. */
|
|
105
|
+
export function getSettlementSender(chainId) {
|
|
106
|
+
return getDeployment(chainId)?.swap;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=machine-token-charge.js.map
|
|
@@ -45,6 +45,8 @@ export declare namespace charge {
|
|
|
45
45
|
} | undefined;
|
|
46
46
|
};
|
|
47
47
|
type Parameters = {
|
|
48
|
+
/** Enables first-party machine-token funding through the canonical swapper. */
|
|
49
|
+
machineTokenEnabled?: boolean | undefined;
|
|
48
50
|
/** Render payment page when Accept header is text/html (e.g. in browsers) */
|
|
49
51
|
html?: boolean | Html.Config | undefined;
|
|
50
52
|
/**
|
|
@@ -99,6 +101,7 @@ export declare namespace charge {
|
|
|
99
101
|
* relay broadcasts pull credentials, while it recognizes a push
|
|
100
102
|
* credential as already broadcast and returns its receipt without sending
|
|
101
103
|
* it again.
|
|
104
|
+
*
|
|
102
105
|
*/
|
|
103
106
|
relay?: RelayOptions | undefined;
|
|
104
107
|
/**
|