@faremeter/payment-evm 0.10.3 → 0.11.1
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/dist/src/exact/client.d.ts.map +1 -1
- package/dist/src/exact/client.js +4 -2
- package/dist/src/exact/common.d.ts +12 -0
- package/dist/src/exact/common.d.ts.map +1 -1
- package/dist/src/exact/common.js +5 -1
- package/dist/src/exact/facilitator.d.ts +3 -2
- package/dist/src/exact/facilitator.d.ts.map +1 -1
- package/dist/src/exact/facilitator.js +5 -24
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/exact/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/exact/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAYhC,UAAU,gBAAgB;IACxB,KAAK,EAAE;QACL,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE;QACP,aAAa,EAAE,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/B,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAClC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;KACpB,CAAC;CACH;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,gBAAgB,EACxB,IAAI,GAAE,wBAA6B,GAClC,cAAc,CAqGhB"}
|
package/dist/src/exact/client.js
CHANGED
|
@@ -2,15 +2,17 @@ import { randomBytes } from "crypto";
|
|
|
2
2
|
import { lookupX402Network, findAssetInfo, } from "@faremeter/info/evm";
|
|
3
3
|
import { isAddress } from "viem";
|
|
4
4
|
import { type } from "arktype";
|
|
5
|
-
import {
|
|
5
|
+
import { EIP712_TYPES, eip712Domain, } from "./constants.js";
|
|
6
|
+
import { generateMatcher } from "./common.js";
|
|
6
7
|
export function createPaymentHandler(wallet, opts = {}) {
|
|
7
8
|
const x402Network = lookupX402Network(wallet.chain.id);
|
|
8
9
|
const assetInfo = findAssetInfo(x402Network, opts.asset ?? "USDC");
|
|
9
10
|
if (!assetInfo) {
|
|
10
11
|
throw new Error(`Couldn't look up USDC information on network '${x402Network}'`);
|
|
11
12
|
}
|
|
13
|
+
const { isMatchingRequirement } = generateMatcher(x402Network, assetInfo.address);
|
|
12
14
|
return async function handlePayment(context, accepts) {
|
|
13
|
-
const compatibleRequirements = accepts.filter(
|
|
15
|
+
const compatibleRequirements = accepts.filter(isMatchingRequirement);
|
|
14
16
|
return compatibleRequirements.map((requirements) => ({
|
|
15
17
|
requirements,
|
|
16
18
|
exec: async () => {
|
|
@@ -15,4 +15,16 @@ export declare function generateForwarderDomain(chainId: number, domainInfo: {
|
|
|
15
15
|
name: string;
|
|
16
16
|
verifyingContract: `0x${string}`;
|
|
17
17
|
};
|
|
18
|
+
export declare function generateMatcher(network: string, asset: string): {
|
|
19
|
+
matchTuple: import("arktype/internal/methods/object.ts").ObjectType<{
|
|
20
|
+
scheme: (In: string) => import("arktype/internal/attributes.ts").To<Lowercase<string>>;
|
|
21
|
+
network: (In: string) => import("arktype/internal/attributes.ts").To<Lowercase<string>>;
|
|
22
|
+
asset: (In: string) => import("arktype/internal/attributes.ts").To<Lowercase<string>>;
|
|
23
|
+
}, {}>;
|
|
24
|
+
isMatchingRequirement: (req: {
|
|
25
|
+
scheme: string;
|
|
26
|
+
network: string;
|
|
27
|
+
asset: string;
|
|
28
|
+
}) => boolean;
|
|
29
|
+
};
|
|
18
30
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/exact/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/exact/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAQ9C,wBAAsB,cAAc,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,GAAG;;;;;GA8BX;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE;IACV,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,KAAK,MAAM,EAAE,CAAC;CAClC;;aAHU,MAAM;UACT,MAAM;uBACO,KAAK,MAAM,EAAE;EAOnC;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;;;;;;;;EAE7D"}
|
package/dist/src/exact/common.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { generateRequirementsMatcher } from "@faremeter/types/x402";
|
|
2
|
+
import { TRANSFER_WITH_AUTHORIZATION_ABI, X402_EXACT_SCHEME, } from "./constants.js";
|
|
2
3
|
export async function generateDomain(publicClient, chainId, asset) {
|
|
3
4
|
// Read domain parameters from chain
|
|
4
5
|
let tokenName;
|
|
@@ -34,3 +35,6 @@ export function generateForwarderDomain(chainId, domainInfo) {
|
|
|
34
35
|
chainId,
|
|
35
36
|
};
|
|
36
37
|
}
|
|
38
|
+
export function generateMatcher(network, asset) {
|
|
39
|
+
return generateRequirementsMatcher([X402_EXACT_SCHEME], [network], [asset]);
|
|
40
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type ChainInfo } from "@faremeter/types/evm";
|
|
1
2
|
import { type FacilitatorHandler } from "@faremeter/types/facilitator";
|
|
2
|
-
import type {
|
|
3
|
+
import type { Transport } from "viem";
|
|
3
4
|
import { type KnownX402Network, type AssetNameOrContractInfo } from "@faremeter/info/evm";
|
|
4
5
|
type CreateFacilitatorHandlerOpts = {
|
|
5
6
|
network?: KnownX402Network;
|
|
6
7
|
transport?: Transport;
|
|
7
8
|
};
|
|
8
|
-
export declare function createFacilitatorHandler(chain:
|
|
9
|
+
export declare function createFacilitatorHandler(chain: ChainInfo, privateKey: string, assetNameOrInfo: AssetNameOrContractInfo, opts?: CreateFacilitatorHandlerOpts): Promise<FacilitatorHandler>;
|
|
9
10
|
export {};
|
|
10
11
|
//# sourceMappingURL=facilitator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facilitator.d.ts","sourceRoot":"","sources":["../../../src/exact/facilitator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"facilitator.d.ts","sourceRoot":"","sources":["../../../src/exact/facilitator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,MAAM,CAAC;AAYpD,OAAO,EAEL,KAAK,gBAAgB,EAErB,KAAK,uBAAuB,EAC7B,MAAM,qBAAqB,CAAC;AAgC7B,KAAK,4BAA4B,GAAG;IAClC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AACF,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,uBAAuB,EACxC,IAAI,GAAE,4BAAiC,GACtC,OAAO,CAAC,kBAAkB,CAAC,CA0R7B"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isValidationError, caseInsensitiveLiteral } from "@faremeter/types";
|
|
2
1
|
import { isPrivateKey } from "@faremeter/types/evm";
|
|
3
2
|
import {} from "@faremeter/types/facilitator";
|
|
4
3
|
import { type } from "arktype";
|
|
@@ -6,7 +5,7 @@ import { createPublicClient, createWalletClient, http, verifyTypedData, encodeFu
|
|
|
6
5
|
import { privateKeyToAccount } from "viem/accounts";
|
|
7
6
|
import { lookupX402Network, findAssetInfo, } from "@faremeter/info/evm";
|
|
8
7
|
import { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, } from "./constants.js";
|
|
9
|
-
import { generateDomain, generateForwarderDomain } from "./common.js";
|
|
8
|
+
import { generateMatcher, generateDomain, generateForwarderDomain, } from "./common.js";
|
|
10
9
|
function errorResponse(msg) {
|
|
11
10
|
return {
|
|
12
11
|
success: false,
|
|
@@ -15,7 +14,6 @@ function errorResponse(msg) {
|
|
|
15
14
|
networkId: null,
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
|
-
const usedNonces = new Set();
|
|
19
17
|
function parseSignature(signature) {
|
|
20
18
|
const sig = signature.slice(2); // Remove 0x
|
|
21
19
|
const r = `0x${sig.slice(0, 64)}`;
|
|
@@ -38,12 +36,10 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
38
36
|
const transport = opts.transport ?? http(chain.rpcUrls.default.http[0]);
|
|
39
37
|
const account = privateKeyToAccount(privateKey);
|
|
40
38
|
const publicClient = createPublicClient({
|
|
41
|
-
chain,
|
|
42
39
|
transport,
|
|
43
40
|
});
|
|
44
41
|
const walletClient = createWalletClient({
|
|
45
42
|
account,
|
|
46
|
-
chain,
|
|
47
43
|
transport,
|
|
48
44
|
});
|
|
49
45
|
let domain;
|
|
@@ -69,13 +65,7 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
69
65
|
throw new Error(`On chain contract name (${domain.name}) doesn't match configured asset name (${assetInfo.contractName})`);
|
|
70
66
|
}
|
|
71
67
|
}
|
|
72
|
-
const
|
|
73
|
-
scheme: caseInsensitiveLiteral(X402_EXACT_SCHEME),
|
|
74
|
-
network: caseInsensitiveLiteral(network),
|
|
75
|
-
});
|
|
76
|
-
const checkTupleAndAsset = checkTuple.and({
|
|
77
|
-
asset: caseInsensitiveLiteral(asset),
|
|
78
|
-
});
|
|
68
|
+
const { isMatchingRequirement } = generateMatcher(network, asset);
|
|
79
69
|
const getSupported = () => {
|
|
80
70
|
return [
|
|
81
71
|
Promise.resolve({
|
|
@@ -86,9 +76,7 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
86
76
|
];
|
|
87
77
|
};
|
|
88
78
|
const getRequirements = async (req) => {
|
|
89
|
-
return req
|
|
90
|
-
.filter((x) => !isValidationError(checkTupleAndAsset(x)))
|
|
91
|
-
.map((x) => ({
|
|
79
|
+
return req.filter(isMatchingRequirement).map((x) => ({
|
|
92
80
|
...x,
|
|
93
81
|
asset,
|
|
94
82
|
maxTimeoutSeconds: 300,
|
|
@@ -102,8 +90,7 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
102
90
|
}));
|
|
103
91
|
};
|
|
104
92
|
const handleSettle = async (requirements, payment) => {
|
|
105
|
-
|
|
106
|
-
if (isValidationError(tupleMatches)) {
|
|
93
|
+
if (!isMatchingRequirement(requirements)) {
|
|
107
94
|
return null; // Not for us, let another handler try
|
|
108
95
|
}
|
|
109
96
|
// For the exact scheme with EIP-3009, validate the authorization payload
|
|
@@ -134,11 +121,6 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
134
121
|
if (!isAddress(authorization.from)) {
|
|
135
122
|
return errorResponse("Invalid from address");
|
|
136
123
|
}
|
|
137
|
-
// Check nonce hasn't been used (local check)
|
|
138
|
-
const nonceKey = `${authorization.from}-${authorization.nonce}`;
|
|
139
|
-
if (usedNonces.has(nonceKey)) {
|
|
140
|
-
return errorResponse("Nonce already used");
|
|
141
|
-
}
|
|
142
124
|
// Check on-chain nonce status
|
|
143
125
|
let onChainUsed;
|
|
144
126
|
try {
|
|
@@ -235,7 +217,7 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
235
217
|
to: useForwarder ? domain.verifyingContract : asset,
|
|
236
218
|
data,
|
|
237
219
|
account: acct,
|
|
238
|
-
chain:
|
|
220
|
+
chain: null,
|
|
239
221
|
});
|
|
240
222
|
const serializedTransaction = await walletClient.signTransaction(request);
|
|
241
223
|
const txHash = await publicClient.sendRawTransaction({
|
|
@@ -247,7 +229,6 @@ export async function createFacilitatorHandler(chain, privateKey, assetNameOrInf
|
|
|
247
229
|
if (receipt.status !== "success") {
|
|
248
230
|
return errorResponse("Transaction failed");
|
|
249
231
|
}
|
|
250
|
-
usedNonces.add(nonceKey);
|
|
251
232
|
return {
|
|
252
233
|
success: true,
|
|
253
234
|
error: null,
|