mppx 0.8.3 → 0.8.5
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 +14 -0
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +2 -0
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/plugins/stripe.d.ts.map +1 -1
- package/dist/cli/plugins/stripe.js +32 -12
- package/dist/cli/plugins/stripe.js.map +1 -1
- package/dist/cli/utils.d.ts.map +1 -1
- package/dist/cli/utils.js +1 -1
- package/dist/cli/utils.js.map +1 -1
- package/dist/cli/validate/challenge.d.ts +14 -0
- package/dist/cli/validate/challenge.d.ts.map +1 -0
- package/dist/cli/validate/challenge.js +211 -0
- package/dist/cli/validate/challenge.js.map +1 -0
- package/dist/cli/validate/discovery.d.ts +10 -0
- package/dist/cli/validate/discovery.d.ts.map +1 -0
- package/dist/cli/validate/discovery.js +128 -0
- package/dist/cli/validate/discovery.js.map +1 -0
- package/dist/cli/validate/helpers.d.ts +33 -0
- package/dist/cli/validate/helpers.d.ts.map +1 -0
- package/dist/cli/validate/helpers.js +136 -0
- package/dist/cli/validate/helpers.js.map +1 -0
- package/dist/cli/validate/index.d.ts +17 -0
- package/dist/cli/validate/index.d.ts.map +1 -0
- package/dist/cli/validate/index.js +224 -0
- package/dist/cli/validate/index.js.map +1 -0
- package/dist/cli/validate/payment.d.ts +7 -0
- package/dist/cli/validate/payment.d.ts.map +1 -0
- package/dist/cli/validate/payment.js +381 -0
- package/dist/cli/validate/payment.js.map +1 -0
- package/dist/evm/client/Charge.d.ts +2 -2
- package/dist/evm/client/Charge.d.ts.map +1 -1
- package/dist/evm/client/Charge.js +11 -17
- package/dist/evm/client/Charge.js.map +1 -1
- package/dist/evm/server/Charge.d.ts +5 -5
- package/dist/evm/server/Charge.d.ts.map +1 -1
- package/dist/evm/server/Charge.js +15 -7
- package/dist/evm/server/Charge.js.map +1 -1
- package/dist/tempo/internal/auto-swap.d.ts.map +1 -1
- package/dist/tempo/internal/auto-swap.js +6 -1
- package/dist/tempo/internal/auto-swap.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/server/internal/html.gen.js.map +1 -1
- package/dist/x402/Assets.d.ts +40 -0
- package/dist/x402/Assets.d.ts.map +1 -1
- package/dist/x402/Assets.js +73 -0
- package/dist/x402/Assets.js.map +1 -1
- package/dist/x402/client/Exact.d.ts +2 -2
- package/dist/x402/client/Exact.d.ts.map +1 -1
- package/dist/x402/client/Exact.js +6 -13
- package/dist/x402/client/Exact.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/cli.test.ts +134 -29
- package/src/cli/cli.ts +2 -0
- package/src/cli/mcp.test.ts +1 -0
- package/src/cli/plugins/stripe.ts +31 -12
- package/src/cli/utils.test.ts +36 -2
- package/src/cli/utils.ts +2 -1
- package/src/cli/validate/challenge.ts +335 -0
- package/src/cli/validate/discovery.ts +120 -0
- package/src/cli/validate/helpers.ts +154 -0
- package/src/cli/validate/index.ts +348 -0
- package/src/cli/validate/payment.ts +488 -0
- package/src/cli/validate.test.ts +539 -0
- package/src/evm/PublicInterface.test-d.ts +15 -2
- package/src/evm/client/Charge.test.ts +248 -0
- package/src/evm/client/Charge.ts +12 -23
- package/src/evm/server/Charge.test.ts +140 -0
- package/src/evm/server/Charge.ts +19 -12
- package/src/tempo/internal/auto-swap.test.ts +26 -9
- package/src/tempo/internal/auto-swap.ts +15 -2
- package/src/tempo/server/internal/html.gen.ts +1 -1
- package/src/x402/Assets.test.ts +211 -0
- package/src/x402/Assets.ts +116 -0
- package/src/x402/client/Exact.test.ts +129 -0
- package/src/x402/client/Exact.ts +7 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.gen.js","sourceRoot":"","sources":["../../../../src/tempo/server/internal/html.gen.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"html.gen.js","sourceRoot":"","sources":["../../../../src/tempo/server/internal/html.gen.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,MAAM,CAAC,MAAM,IAAI,GAAG,swrpBAAswrpB,CAAA"}
|
package/dist/x402/Assets.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Token } from 'viem/tokens';
|
|
1
2
|
import type { Asset, EvmNetwork, ExactTransfer } from './Types.js';
|
|
2
3
|
declare const knownAsset: unique symbol;
|
|
3
4
|
/** Known x402 asset metadata. */
|
|
@@ -5,6 +6,10 @@ export type KnownAsset = Asset & {
|
|
|
5
6
|
readonly [knownAsset]: true;
|
|
6
7
|
network: EvmNetwork;
|
|
7
8
|
};
|
|
9
|
+
/** Viem token metadata from `viem/tokens`. */
|
|
10
|
+
export type ViemToken = Token;
|
|
11
|
+
/** Currency metadata accepted by EVM and x402 payment config. */
|
|
12
|
+
export type Currency = `0x${string}` | KnownAsset | ViemToken;
|
|
8
13
|
/** Creates typed x402 asset metadata for custom tokens. */
|
|
9
14
|
export declare function define(parameters: define.Parameters): KnownAsset;
|
|
10
15
|
export declare namespace define {
|
|
@@ -15,6 +20,21 @@ export declare namespace define {
|
|
|
15
20
|
transfer: ExactTransfer;
|
|
16
21
|
};
|
|
17
22
|
}
|
|
23
|
+
/** Creates x402 asset metadata from a `viem/tokens` token definition. */
|
|
24
|
+
export declare function fromToken(token: ViemToken, parameters: fromToken.Parameters): KnownAsset;
|
|
25
|
+
export declare namespace fromToken {
|
|
26
|
+
type Parameters = {
|
|
27
|
+
chainId: number;
|
|
28
|
+
transfer: Transfer;
|
|
29
|
+
};
|
|
30
|
+
type Transfer = (Omit<Extract<ExactTransfer, {
|
|
31
|
+
type: 'eip3009';
|
|
32
|
+
}>, 'name'> & {
|
|
33
|
+
name?: string | undefined;
|
|
34
|
+
}) | Extract<ExactTransfer, {
|
|
35
|
+
type: 'permit2';
|
|
36
|
+
}>;
|
|
37
|
+
}
|
|
18
38
|
/** Base network known assets. */
|
|
19
39
|
export declare const base: {
|
|
20
40
|
readonly USDC: KnownAsset;
|
|
@@ -25,5 +45,25 @@ export declare const baseSepolia: {
|
|
|
25
45
|
};
|
|
26
46
|
/** Returns true when a value is known x402 asset metadata. */
|
|
27
47
|
export declare function isAsset(value: unknown): value is KnownAsset;
|
|
48
|
+
/** Returns true when a value is a `viem/tokens` token definition. */
|
|
49
|
+
export declare function isToken(value: unknown): value is ViemToken;
|
|
50
|
+
/** Returns true when a currency is a raw address without chain metadata. */
|
|
51
|
+
export declare function isRawAddress(currency: Currency): currency is `0x${string}`;
|
|
52
|
+
/** Resolves currency metadata for an EVM network. */
|
|
53
|
+
export declare function resolve(currency: Currency, network: EvmNetwork): resolve.Result | undefined;
|
|
54
|
+
export declare namespace resolve {
|
|
55
|
+
type Result = {
|
|
56
|
+
address: `0x${string}`;
|
|
57
|
+
decimals?: number | undefined;
|
|
58
|
+
name?: string | undefined;
|
|
59
|
+
transfer?: ExactTransfer | undefined;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Returns true when a currency resolves to the accepted address on the network. */
|
|
63
|
+
export declare function matches(currency: Currency, acceptedCurrency: `0x${string}`, network: EvmNetwork): boolean;
|
|
64
|
+
/** Converts an EVM chain ID to a CAIP-2 network identifier. */
|
|
65
|
+
export declare function toNetwork(chainId: number): EvmNetwork;
|
|
66
|
+
/** Converts a CAIP-2 EVM network identifier to a chain ID. */
|
|
67
|
+
export declare function toChainId(network: EvmNetwork): number;
|
|
28
68
|
export {};
|
|
29
69
|
//# sourceMappingURL=Assets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Assets.d.ts","sourceRoot":"","sources":["../../src/x402/Assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Assets.d.ts","sourceRoot":"","sources":["../../src/x402/Assets.ts"],"names":[],"mappings":"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"}
|
package/dist/x402/Assets.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getAddress } from 'viem';
|
|
1
2
|
const knownAsset = Symbol('mppx.x402.asset');
|
|
2
3
|
/** Creates typed x402 asset metadata for custom tokens. */
|
|
3
4
|
export function define(parameters) {
|
|
@@ -9,6 +10,16 @@ export function define(parameters) {
|
|
|
9
10
|
transfer: parameters.transfer,
|
|
10
11
|
};
|
|
11
12
|
}
|
|
13
|
+
/** Creates x402 asset metadata from a `viem/tokens` token definition. */
|
|
14
|
+
export function fromToken(token, parameters) {
|
|
15
|
+
const resolved = token(parameters.chainId);
|
|
16
|
+
return define({
|
|
17
|
+
address: resolved.address,
|
|
18
|
+
decimals: resolved.decimals,
|
|
19
|
+
network: toNetwork(parameters.chainId),
|
|
20
|
+
transfer: withTokenDefaults(parameters.transfer, resolved),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
12
23
|
/** Base network known assets. */
|
|
13
24
|
export const base = {
|
|
14
25
|
USDC: define({
|
|
@@ -43,4 +54,66 @@ export function isAsset(value) {
|
|
|
43
54
|
return false;
|
|
44
55
|
return value[knownAsset] === true;
|
|
45
56
|
}
|
|
57
|
+
/** Returns true when a value is a `viem/tokens` token definition. */
|
|
58
|
+
export function isToken(value) {
|
|
59
|
+
return (typeof value === 'function' &&
|
|
60
|
+
typeof value.addresses === 'object' &&
|
|
61
|
+
typeof value.decimals === 'number');
|
|
62
|
+
}
|
|
63
|
+
/** Returns true when a currency is a raw address without chain metadata. */
|
|
64
|
+
export function isRawAddress(currency) {
|
|
65
|
+
return typeof currency === 'string';
|
|
66
|
+
}
|
|
67
|
+
/** Resolves currency metadata for an EVM network. */
|
|
68
|
+
export function resolve(currency, network) {
|
|
69
|
+
if (isAsset(currency)) {
|
|
70
|
+
if (currency.network !== network)
|
|
71
|
+
return undefined;
|
|
72
|
+
return {
|
|
73
|
+
address: currency.address,
|
|
74
|
+
decimals: currency.decimals,
|
|
75
|
+
transfer: currency.transfer,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (isToken(currency)) {
|
|
79
|
+
const address = currency.addresses[toChainId(network)];
|
|
80
|
+
if (!address)
|
|
81
|
+
return undefined;
|
|
82
|
+
return {
|
|
83
|
+
address,
|
|
84
|
+
decimals: currency.decimals,
|
|
85
|
+
name: currency.name,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
address: currency,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** Returns true when a currency resolves to the accepted address on the network. */
|
|
93
|
+
export function matches(currency, acceptedCurrency, network) {
|
|
94
|
+
const resolved = resolve(currency, network);
|
|
95
|
+
if (!resolved)
|
|
96
|
+
return false;
|
|
97
|
+
return getAddress(resolved.address) === getAddress(acceptedCurrency);
|
|
98
|
+
}
|
|
99
|
+
/** Converts an EVM chain ID to a CAIP-2 network identifier. */
|
|
100
|
+
export function toNetwork(chainId) {
|
|
101
|
+
return `eip155:${chainId}`;
|
|
102
|
+
}
|
|
103
|
+
/** Converts a CAIP-2 EVM network identifier to a chain ID. */
|
|
104
|
+
export function toChainId(network) {
|
|
105
|
+
return Number(network.slice('eip155:'.length));
|
|
106
|
+
}
|
|
107
|
+
function withTokenDefaults(transfer, token) {
|
|
108
|
+
if (transfer.type !== 'eip3009')
|
|
109
|
+
return transfer;
|
|
110
|
+
if (transfer.name)
|
|
111
|
+
return { ...transfer, name: transfer.name };
|
|
112
|
+
if (!token.name)
|
|
113
|
+
throw new Error('EIP-3009 token assets require a token name.');
|
|
114
|
+
return {
|
|
115
|
+
...transfer,
|
|
116
|
+
name: token.name,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
46
119
|
//# sourceMappingURL=Assets.js.map
|
package/dist/x402/Assets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Assets.js","sourceRoot":"","sources":["../../src/x402/Assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Assets.js","sourceRoot":"","sources":["../../src/x402/Assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,8 +31,8 @@ export type Config = {
|
|
|
31
31
|
/** Optional allowlist of supported EVM chain IDs. */
|
|
32
32
|
networks?: readonly number[] | undefined;
|
|
33
33
|
/** Optional allowlist of supported currencies. */
|
|
34
|
-
currencies?: readonly
|
|
34
|
+
currencies?: readonly Assets.Currency[] | undefined;
|
|
35
35
|
/** Legacy alias for `currencies`. */
|
|
36
|
-
assets?: readonly
|
|
36
|
+
assets?: readonly Assets.Currency[] | undefined;
|
|
37
37
|
};
|
|
38
38
|
//# sourceMappingURL=Exact.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Exact.d.ts","sourceRoot":"","sources":["../../../src/x402/client/Exact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC,OAAO,KAAK,KAAK,SAAS,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AAGtC,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AAEpC;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2D/F;AAED,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,KAAK,UAAU,GAAG;QAChB,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAClD,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAC9B,CAAA;CACF;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG;IAC7B,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAA;CAC5D,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAA;IAChB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACxC,kDAAkD;IAClD,UAAU,CAAC,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"Exact.d.ts","sourceRoot":"","sources":["../../../src/x402/client/Exact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGnC,OAAO,KAAK,KAAK,SAAS,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AAGtC,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AAEpC;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,gBAAgB,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2D/F;AAED,MAAM,CAAC,OAAO,WAAW,gBAAgB,CAAC;IACxC,KAAK,UAAU,GAAG;QAChB,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAClD,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAC9B,CAAA;CACF;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG;IAC7B,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAA;CAC5D,CAAA;AAED,MAAM,MAAM,MAAM,GAAG;IACnB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAA;IAChB,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,qDAAqD;IACrD,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACxC,kDAAkD;IAClD,UAAU,CAAC,EAAE,SAAS,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAA;IACnD,qCAAqC;IACrC,MAAM,CAAC,EAAE,SAAS,MAAM,CAAC,QAAQ,EAAE,GAAG,SAAS,CAAA;CAChD,CAAA"}
|
|
@@ -81,11 +81,11 @@ function assertPolicy(parameters, accepted) {
|
|
|
81
81
|
if (parameters.networks && !parameters.networks.includes(chainId))
|
|
82
82
|
throw new Error(`x402 exact chain ID is not allowed: ${chainId}.`);
|
|
83
83
|
const currencies = parameters.currencies ?? parameters.assets;
|
|
84
|
-
if (currencies?.some((currency) =>
|
|
84
|
+
if (currencies?.some((currency) => Assets.isRawAddress(currency)) && !parameters.networks?.length)
|
|
85
85
|
throw new Error('x402 exact raw currency allowlists require networks.');
|
|
86
86
|
if (currencies) {
|
|
87
87
|
const acceptedCurrency = getAddress(accepted.asset);
|
|
88
|
-
const allowed = currencies.some((currency) =>
|
|
88
|
+
const allowed = currencies.some((currency) => Assets.matches(currency, acceptedCurrency, accepted.network));
|
|
89
89
|
if (!allowed)
|
|
90
90
|
throw new Error(`x402 exact currency is not allowed: ${acceptedCurrency}.`);
|
|
91
91
|
}
|
|
@@ -100,20 +100,13 @@ function assertPolicy(parameters, accepted) {
|
|
|
100
100
|
throw new Error('x402 exact amount exceeds maxAmount.');
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
function addressOf(currency) {
|
|
104
|
-
return Assets.isAsset(currency) ? currency.address : currency;
|
|
105
|
-
}
|
|
106
|
-
function currencyMatches(currency, acceptedCurrency, network) {
|
|
107
|
-
if (getAddress(addressOf(currency)) !== acceptedCurrency)
|
|
108
|
-
return false;
|
|
109
|
-
return !Assets.isAsset(currency) || currency.network === network;
|
|
110
|
-
}
|
|
111
103
|
function decimalsOfAcceptedCurrency(parameters, accepted) {
|
|
112
104
|
const currencies = parameters.currencies ?? parameters.assets;
|
|
113
105
|
const acceptedCurrency = getAddress(accepted.asset);
|
|
114
|
-
const currency = currencies?.find((currency) =>
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
const currency = currencies?.find((currency) => Assets.matches(currency, acceptedCurrency, accepted.network));
|
|
107
|
+
const resolved = currency ? Assets.resolve(currency, accepted.network) : undefined;
|
|
108
|
+
if (resolved?.decimals !== undefined)
|
|
109
|
+
return resolved.decimals;
|
|
117
110
|
return parameters.decimals;
|
|
118
111
|
}
|
|
119
112
|
function withNonceSalt(extensions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Exact.js","sourceRoot":"","sources":["../../../src/x402/client/Exact.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Exact.js","sourceRoot":"","sources":["../../../src/x402/client/Exact.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/cli.test.ts
CHANGED
|
@@ -20,6 +20,7 @@ import * as Receipt from '../Receipt.js'
|
|
|
20
20
|
import * as Mppx_server from '../server/Mppx.js'
|
|
21
21
|
import { toNodeListener } from '../server/Mppx.js'
|
|
22
22
|
import * as Store from '../Store.js'
|
|
23
|
+
import { stripePreviewVersion } from '../stripe/internal/constants.js'
|
|
23
24
|
import { stripe as stripe_server } from '../stripe/server/Methods.js'
|
|
24
25
|
import { tempo } from '../tempo/server/Methods.js'
|
|
25
26
|
import { escrowAbi } from '../tempo/session/precompile/escrow.abi.js'
|
|
@@ -1403,40 +1404,144 @@ describe('stripe charge', () => {
|
|
|
1403
1404
|
}
|
|
1404
1405
|
})
|
|
1405
1406
|
|
|
1406
|
-
test(
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
realm: 'cli-test-stripe-live',
|
|
1416
|
-
secretKey: 'cli-test-secret-cli-test-secret-32',
|
|
1417
|
-
})
|
|
1407
|
+
test(
|
|
1408
|
+
'happy path: live key uses production SPT endpoint and seller business profile',
|
|
1409
|
+
{ timeout: 60_000 },
|
|
1410
|
+
async () => {
|
|
1411
|
+
const mockStripeClient = {
|
|
1412
|
+
paymentIntents: {
|
|
1413
|
+
create: async () => ({ id: 'pi_mock_cli_live_123', status: 'succeeded' }),
|
|
1414
|
+
},
|
|
1415
|
+
}
|
|
1418
1416
|
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1417
|
+
const server = Mppx_server.create({
|
|
1418
|
+
methods: [
|
|
1419
|
+
stripe_server.charge({
|
|
1420
|
+
client: mockStripeClient,
|
|
1421
|
+
networkId: 'profile_live_mock',
|
|
1422
|
+
paymentMethodTypes: ['card'],
|
|
1423
|
+
}),
|
|
1424
|
+
],
|
|
1425
|
+
realm: 'cli-test-stripe-live',
|
|
1426
|
+
secretKey: 'cli-test-secret-cli-test-secret-32',
|
|
1427
|
+
})
|
|
1426
1428
|
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1429
|
+
const appServer = await Http.createServer(async (req, res) => {
|
|
1430
|
+
const result = await Mppx_server.toNodeListener(
|
|
1431
|
+
server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
|
|
1432
|
+
)(req, res)
|
|
1433
|
+
if (result.status === 402) return
|
|
1434
|
+
res.end('paid')
|
|
1435
|
+
})
|
|
1436
|
+
|
|
1437
|
+
const { restore, stripeRequests } = mockSptFetch(
|
|
1438
|
+
'https://api.stripe.com/v1/shared_payment/issued_tokens',
|
|
1431
1439
|
)
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1440
|
+
|
|
1441
|
+
try {
|
|
1442
|
+
const { output } = await serve([appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'], {
|
|
1443
|
+
env: { MPPX_STRIPE_SECRET_KEY: 'sk_live_fake', MPPX_STRIPE_SPT_URL: undefined },
|
|
1444
|
+
})
|
|
1445
|
+
expect(output).toContain('paid')
|
|
1446
|
+
const stripeRequest = stripeRequests[0]
|
|
1447
|
+
expect(stripeRequest?.url).toBe('https://api.stripe.com/v1/shared_payment/issued_tokens')
|
|
1448
|
+
expect(stripeRequest?.body.get('seller_details[network_business_profile]')).toBe(
|
|
1449
|
+
'profile_live_mock',
|
|
1450
|
+
)
|
|
1451
|
+
expect(stripeRequest?.body.has('seller_details[network_id]')).toBe(false)
|
|
1452
|
+
expect(stripeRequest?.headers['Stripe-Version']).toBe(stripePreviewVersion)
|
|
1453
|
+
} finally {
|
|
1454
|
+
restore()
|
|
1455
|
+
appServer.close()
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
)
|
|
1459
|
+
|
|
1460
|
+
test(
|
|
1461
|
+
'happy path: test key uses test-helper SPT endpoint and network ID',
|
|
1462
|
+
{ timeout: 60_000 },
|
|
1463
|
+
async () => {
|
|
1464
|
+
const mockStripeClient = {
|
|
1465
|
+
paymentIntents: {
|
|
1466
|
+
create: async () => ({ id: 'pi_mock_cli_test_123', status: 'succeeded' }),
|
|
1467
|
+
},
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
const server = Mppx_server.create({
|
|
1471
|
+
methods: [
|
|
1472
|
+
stripe_server.charge({
|
|
1473
|
+
client: mockStripeClient,
|
|
1474
|
+
networkId: 'internal',
|
|
1475
|
+
paymentMethodTypes: ['card'],
|
|
1476
|
+
}),
|
|
1477
|
+
],
|
|
1478
|
+
realm: 'cli-test-stripe-testmode',
|
|
1479
|
+
secretKey: 'cli-test-secret-cli-test-secret-32',
|
|
1480
|
+
})
|
|
1481
|
+
|
|
1482
|
+
const appServer = await Http.createServer(async (req, res) => {
|
|
1483
|
+
const result = await Mppx_server.toNodeListener(
|
|
1484
|
+
server.charge({ amount: '1', currency: 'usd', decimals: 2 }),
|
|
1485
|
+
)(req, res)
|
|
1486
|
+
if (result.status === 402) return
|
|
1487
|
+
res.end('paid')
|
|
1488
|
+
})
|
|
1489
|
+
|
|
1490
|
+
const { restore, stripeRequests } = mockSptFetch(
|
|
1491
|
+
'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens',
|
|
1492
|
+
)
|
|
1493
|
+
|
|
1494
|
+
try {
|
|
1495
|
+
const { output } = await serve([appServer.url, '-s', '-M', 'paymentMethod=pm_card_visa'], {
|
|
1496
|
+
env: { MPPX_STRIPE_SECRET_KEY: 'sk_test_fake', MPPX_STRIPE_SPT_URL: undefined },
|
|
1497
|
+
})
|
|
1498
|
+
expect(output).toContain('paid')
|
|
1499
|
+
const stripeRequest = stripeRequests[0]
|
|
1500
|
+
expect(stripeRequest?.url).toBe(
|
|
1501
|
+
'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens',
|
|
1502
|
+
)
|
|
1503
|
+
expect(stripeRequest?.body.get('seller_details[network_id]')).toBe('internal')
|
|
1504
|
+
expect(stripeRequest?.body.has('seller_details[network_business_profile]')).toBe(false)
|
|
1505
|
+
expect(stripeRequest?.headers['Stripe-Version']).toBe(stripePreviewVersion)
|
|
1506
|
+
} finally {
|
|
1507
|
+
restore()
|
|
1508
|
+
appServer.close()
|
|
1509
|
+
}
|
|
1510
|
+
},
|
|
1511
|
+
)
|
|
1438
1512
|
})
|
|
1439
1513
|
|
|
1514
|
+
/**
|
|
1515
|
+
* Intercepts `globalThis.fetch` calls to `sptUrl`, recording each request and
|
|
1516
|
+
* responding with a mock SPT. Returns the recorded requests and a `restore`
|
|
1517
|
+
* function that reinstates the original fetch.
|
|
1518
|
+
*/
|
|
1519
|
+
function mockSptFetch(sptUrl: string) {
|
|
1520
|
+
const originalFetch = globalThis.fetch
|
|
1521
|
+
const stripeRequests: {
|
|
1522
|
+
body: URLSearchParams
|
|
1523
|
+
headers: Record<string, string>
|
|
1524
|
+
url: string
|
|
1525
|
+
}[] = []
|
|
1526
|
+
globalThis.fetch = (async (input, init) => {
|
|
1527
|
+
const url =
|
|
1528
|
+
typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url
|
|
1529
|
+
if (url === sptUrl) {
|
|
1530
|
+
stripeRequests.push({
|
|
1531
|
+
body: new URLSearchParams(init?.body as string),
|
|
1532
|
+
headers: (init?.headers ?? {}) as Record<string, string>,
|
|
1533
|
+
url,
|
|
1534
|
+
})
|
|
1535
|
+
return new Response(JSON.stringify({ id: 'spt_mock_cli_test' }), {
|
|
1536
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1537
|
+
status: 200,
|
|
1538
|
+
})
|
|
1539
|
+
}
|
|
1540
|
+
return originalFetch(input, init)
|
|
1541
|
+
}) as typeof fetch
|
|
1542
|
+
return { restore: () => (globalThis.fetch = originalFetch), stripeRequests }
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1440
1545
|
// ---------------------------------------------------------------------------
|
|
1441
1546
|
// account [action]
|
|
1442
1547
|
// Keychain tests are opt-in because macOS/Linux keychain commands can block on
|
package/src/cli/cli.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
resolveFundingNetwork,
|
|
41
41
|
resolveRpcUrl,
|
|
42
42
|
} from './utils.js'
|
|
43
|
+
import validate from './validate/index.js'
|
|
43
44
|
|
|
44
45
|
const packageJson = createRequire(import.meta.url)('../../package.json') as {
|
|
45
46
|
name: string
|
|
@@ -1575,5 +1576,6 @@ cli.command(discover)
|
|
|
1575
1576
|
cli.command(init)
|
|
1576
1577
|
cli.command(services)
|
|
1577
1578
|
cli.command(sign)
|
|
1579
|
+
cli.command(validate)
|
|
1578
1580
|
|
|
1579
1581
|
export default cli
|
package/src/cli/mcp.test.ts
CHANGED
|
@@ -194,6 +194,7 @@ test('tools/list exposes mppx commands with input and output schemas', async ()
|
|
|
194
194
|
'services_list',
|
|
195
195
|
'services_show',
|
|
196
196
|
'sign',
|
|
197
|
+
'validate',
|
|
197
198
|
])
|
|
198
199
|
expect(tools.find((tool: { name: string }) => tool.name === 'account_list').outputSchema).toEqual(
|
|
199
200
|
expect.objectContaining({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Errors, z } from 'incur'
|
|
2
2
|
|
|
3
3
|
import { stripe as stripeMethods } from '../../stripe/client/index.js'
|
|
4
|
+
import { stripePreviewVersion } from '../../stripe/internal/constants.js'
|
|
4
5
|
import { pc } from '../utils.js'
|
|
5
6
|
import { createPlugin } from './plugin.js'
|
|
6
7
|
|
|
@@ -30,13 +31,6 @@ export function stripe() {
|
|
|
30
31
|
message: 'MPPX_STRIPE_SECRET_KEY environment variable is required for Stripe payments.',
|
|
31
32
|
exitCode: 2,
|
|
32
33
|
})
|
|
33
|
-
if (!stripeSecretKey.startsWith('sk_test_'))
|
|
34
|
-
throw new Errors.IncurError({
|
|
35
|
-
code: 'UNSUPPORTED_MODE',
|
|
36
|
-
message:
|
|
37
|
-
'Stripe CLI payments are currently only supported in test mode (sk_test_... keys).',
|
|
38
|
-
exitCode: 2,
|
|
39
|
-
})
|
|
40
34
|
|
|
41
35
|
return {
|
|
42
36
|
tokenSymbol: currency?.toUpperCase() ?? '',
|
|
@@ -58,19 +52,35 @@ export function stripe() {
|
|
|
58
52
|
'usage_limits[max_amount]': amount,
|
|
59
53
|
'usage_limits[expires_at]': expiresAt.toString(),
|
|
60
54
|
})
|
|
61
|
-
|
|
55
|
+
const testMode = isTestKey(stripeSecretKey)
|
|
56
|
+
const sptUrl = (() => {
|
|
57
|
+
// Allow tests and custom deployments to target a specific SPT endpoint.
|
|
58
|
+
if (process.env.MPPX_STRIPE_SPT_URL) return process.env.MPPX_STRIPE_SPT_URL
|
|
59
|
+
// Preserve test-key behavior against Stripe's test-helper SPT endpoint.
|
|
60
|
+
if (testMode)
|
|
61
|
+
return 'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens'
|
|
62
|
+
// Live keys mint Shared Payment Tokens through the agent-side issued tokens API.
|
|
63
|
+
return 'https://api.stripe.com/v1/shared_payment/issued_tokens'
|
|
64
|
+
})()
|
|
65
|
+
if (networkId) {
|
|
66
|
+
// Live SPT issuance grants the token to the seller's Stripe business
|
|
67
|
+
// profile (`profile_...`); the test helper uses a plain network ID.
|
|
68
|
+
const sellerDetailsField = testMode
|
|
69
|
+
? 'seller_details[network_id]'
|
|
70
|
+
: 'seller_details[network_business_profile]'
|
|
71
|
+
body.set(sellerDetailsField, networkId)
|
|
72
|
+
}
|
|
62
73
|
if (metadata) {
|
|
63
74
|
for (const [key, value] of Object.entries(metadata)) {
|
|
64
75
|
body.set(`metadata[${key}]`, value)
|
|
65
76
|
}
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
const sptUrl =
|
|
69
|
-
process.env.MPPX_STRIPE_SPT_URL ??
|
|
70
|
-
'https://api.stripe.com/v1/test_helpers/shared_payment/granted_tokens'
|
|
71
79
|
const sptHeaders = {
|
|
72
80
|
Authorization: `Basic ${btoa(`${stripeSecretKey}:`)}`,
|
|
73
81
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
82
|
+
// SPT endpoints are in preview and require an explicit preview API version.
|
|
83
|
+
'Stripe-Version': stripePreviewVersion,
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
let response = await globalThis.fetch(sptUrl, {
|
|
@@ -80,7 +90,11 @@ export function stripe() {
|
|
|
80
90
|
})
|
|
81
91
|
if (!response.ok) {
|
|
82
92
|
const errorBody = (await response.json()) as { error: { message: string } }
|
|
93
|
+
// Retry without optional parameters only in test mode: the live
|
|
94
|
+
// issued-tokens endpoint requires `seller_details`, so a retry
|
|
95
|
+
// without it can never succeed.
|
|
83
96
|
if (
|
|
97
|
+
testMode &&
|
|
84
98
|
(metadata || networkId) &&
|
|
85
99
|
errorBody.error.message.includes('Received unknown parameter')
|
|
86
100
|
) {
|
|
@@ -122,7 +136,8 @@ export function stripe() {
|
|
|
122
136
|
|
|
123
137
|
formatReceiptField(key, value) {
|
|
124
138
|
if (key === 'reference' && typeof value === 'string' && value.startsWith('pi_')) {
|
|
125
|
-
const
|
|
139
|
+
const secretKey = process.env.MPPX_STRIPE_SECRET_KEY
|
|
140
|
+
const isTest = secretKey !== undefined && isTestKey(secretKey)
|
|
126
141
|
const url = `https://dashboard.stripe.com${isTest ? '/test' : ''}/payments/${value}`
|
|
127
142
|
return pc.link(url, value, true)
|
|
128
143
|
}
|
|
@@ -132,6 +147,10 @@ export function stripe() {
|
|
|
132
147
|
|
|
133
148
|
// --- Helpers ---
|
|
134
149
|
|
|
150
|
+
function isTestKey(secretKey: string) {
|
|
151
|
+
return secretKey.startsWith('sk_test_') || secretKey.startsWith('rk_test_')
|
|
152
|
+
}
|
|
153
|
+
|
|
135
154
|
function parseOptions<const schema extends z.ZodType>(
|
|
136
155
|
schema: schema,
|
|
137
156
|
rawOptions: unknown,
|
package/src/cli/utils.test.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { tempo as tempoMainnet, tempoModerato } from 'viem/tempo/chains'
|
|
2
|
-
import { afterEach, describe, expect, test } from 'vp/test'
|
|
2
|
+
import { afterEach, describe, expect, test, vi } from 'vp/test'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
fetchTokenInfo,
|
|
6
|
+
networkRpcUrls,
|
|
7
|
+
resolveChain,
|
|
8
|
+
resolveFundingNetwork,
|
|
9
|
+
resolveRpcUrl,
|
|
10
|
+
} from './utils.js'
|
|
5
11
|
|
|
6
12
|
describe('resolveRpcUrl', () => {
|
|
7
13
|
afterEach(() => {
|
|
@@ -97,3 +103,31 @@ describe('resolveChain', () => {
|
|
|
97
103
|
expect(chain.id).not.toBe(tempoModerato.id)
|
|
98
104
|
})
|
|
99
105
|
})
|
|
106
|
+
|
|
107
|
+
describe('fetchTokenInfo', () => {
|
|
108
|
+
afterEach(() => {
|
|
109
|
+
vi.doUnmock('viem/tempo')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test('uses 6 decimals when token metadata omits a numeric decimals value', async () => {
|
|
113
|
+
const token = '0x1111111111111111111111111111111111111111'
|
|
114
|
+
const account = '0x2222222222222222222222222222222222222222'
|
|
115
|
+
vi.doMock('viem/tempo', () => ({
|
|
116
|
+
Actions: {
|
|
117
|
+
token: {
|
|
118
|
+
getBalance: vi.fn(async () => ({ amount: 123n })),
|
|
119
|
+
getMetadata: vi.fn(async () => ({ decimals: undefined, symbol: 'TEST' })),
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
}))
|
|
123
|
+
|
|
124
|
+
const info = await fetchTokenInfo({} as never, token, account)
|
|
125
|
+
|
|
126
|
+
expect(info).toEqual({
|
|
127
|
+
balance: 123n,
|
|
128
|
+
decimals: 6,
|
|
129
|
+
symbol: 'TEST',
|
|
130
|
+
token,
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
})
|
package/src/cli/utils.ts
CHANGED
|
@@ -318,7 +318,8 @@ export async function fetchTokenInfo(
|
|
|
318
318
|
[usdc]: 'USDC',
|
|
319
319
|
}
|
|
320
320
|
const symbol = knownSymbols[token] ?? metadata.symbol
|
|
321
|
-
const decimals =
|
|
321
|
+
const decimals =
|
|
322
|
+
'decimals' in metadata && typeof metadata.decimals === 'number' ? metadata.decimals : 6
|
|
322
323
|
return { balance, symbol, decimals, token }
|
|
323
324
|
}
|
|
324
325
|
|