@faremeter/payment-evm 0.6.0 → 0.7.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.
@@ -44,7 +44,7 @@ export function createPaymentHandler(wallet) {
44
44
  throw new Error(`Invalid EIP-712 domain parameters: ${extraResult.summary}`);
45
45
  }
46
46
  const domain = {
47
- name: extraResult.name ?? assetInfo.name,
47
+ name: extraResult.name ?? assetInfo.contractName,
48
48
  version: extraResult.version ?? "2",
49
49
  chainId: extraResult.chainId ?? networkInfo.chainId,
50
50
  verifyingContract: (() => {
@@ -0,0 +1,8 @@
1
+ import type { PublicClient, Hex } from "viem";
2
+ export declare function generateDomain(publicClient: PublicClient, chainId: number, asset: Hex): Promise<{
3
+ name: string;
4
+ version: string;
5
+ chainId: number;
6
+ verifyingContract: `0x${string}`;
7
+ }>;
8
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +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;AAI9C,wBAAsB,cAAc,CAClC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,GAAG;;;;;GA8BX"}
@@ -0,0 +1,30 @@
1
+ import { TRANSFER_WITH_AUTHORIZATION_ABI } from "./constants.js";
2
+ export async function generateDomain(publicClient, chainId, asset) {
3
+ // Read domain parameters from chain
4
+ let tokenName;
5
+ let tokenVersion;
6
+ try {
7
+ [tokenName, tokenVersion] = await Promise.all([
8
+ publicClient.readContract({
9
+ address: asset,
10
+ abi: TRANSFER_WITH_AUTHORIZATION_ABI,
11
+ functionName: "name",
12
+ }),
13
+ publicClient.readContract({
14
+ address: asset,
15
+ abi: TRANSFER_WITH_AUTHORIZATION_ABI,
16
+ functionName: "version",
17
+ }),
18
+ ]);
19
+ }
20
+ catch (cause) {
21
+ throw new Error("Failed to read contract parameters", { cause });
22
+ }
23
+ const domain = {
24
+ name: tokenName,
25
+ version: tokenVersion,
26
+ chainId,
27
+ verifyingContract: asset,
28
+ };
29
+ return domain;
30
+ }
@@ -1,5 +1,4 @@
1
1
  export declare const X402_EXACT_SCHEME = "exact";
2
- export declare const BASE_SEPOLIA_NETWORK = "base-sepolia";
3
2
  export declare const TRANSFER_WITH_AUTHORIZATION_ABI: readonly [{
4
3
  readonly name: "transferWithAuthorization";
5
4
  readonly type: "function";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/exact/constants.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB,UAAU,CAAC;AACzC,eAAO,MAAM,oBAAoB,iBAAiB,CAAC;AAEnD,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDlC,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;CASf,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;MAU3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,KAAK,CAAC;AAC7D,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;AAErE,eAAO,MAAM,YAAY;;;;;MAKvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/exact/constants.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDlC,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;CASf,CAAC;AAEX,eAAO,MAAM,gBAAgB;;;;;;;;;;MAU3B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,KAAK,CAAC;AAC7D,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,eAAe,CAAC,CAAC;AAErE,eAAO,MAAM,YAAY;;;;;MAKvB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,KAAK,CAAC"}
@@ -7,7 +7,6 @@ const prefixedHexString = type("string").pipe.try((x) => {
7
7
  return toHex(x);
8
8
  });
9
9
  export const X402_EXACT_SCHEME = "exact";
10
- export const BASE_SEPOLIA_NETWORK = "base-sepolia";
11
10
  export const TRANSFER_WITH_AUTHORIZATION_ABI = [
12
11
  {
13
12
  name: "transferWithAuthorization",
@@ -1,4 +1,4 @@
1
1
  import { type FacilitatorHandler } from "@faremeter/types/facilitator";
2
2
  import type { PublicClient, WalletClient } from "viem";
3
- export declare function createFacilitatorHandler(network: string, publicClient: PublicClient, walletClient: WalletClient, assetName: string): FacilitatorHandler;
3
+ export declare function createFacilitatorHandler(network: string, publicClient: PublicClient, walletClient: WalletClient, assetName: string): Promise<FacilitatorHandler>;
4
4
  //# sourceMappingURL=facilitator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"facilitator.d.ts","sourceRoot":"","sources":["../../../src/exact/facilitator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAE,YAAY,EAAO,YAAY,EAAW,MAAM,MAAM,CAAC;AAoCrE,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAmQpB"}
1
+ {"version":3,"file":"facilitator.d.ts","sourceRoot":"","sources":["../../../src/exact/facilitator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,KAAK,EAAE,YAAY,EAAO,YAAY,EAAW,MAAM,MAAM,CAAC;AAqCrE,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAiP7B"}
@@ -2,9 +2,9 @@ import { isValidationError, caseInsensitiveLiteral } from "@faremeter/types";
2
2
  import {} from "@faremeter/types/facilitator";
3
3
  import { type } from "arktype";
4
4
  import { verifyTypedData, encodeFunctionData, isAddress } from "viem";
5
- import { baseSepolia } from "viem/chains";
6
- import { isKnownAsset, lookupKnownAsset, lookupKnownNetwork, } from "@faremeter/info/evm";
7
- import { X402_EXACT_SCHEME, BASE_SEPOLIA_NETWORK, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, } from "./constants.js";
5
+ import { isKnownAsset, isKnownNetwork, lookupKnownAsset, lookupKnownNetwork, } from "@faremeter/info/evm";
6
+ import { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, } from "./constants.js";
7
+ import { generateDomain } from "./common.js";
8
8
  function errorResponse(msg) {
9
9
  return {
10
10
  success: false,
@@ -21,14 +21,15 @@ function parseSignature(signature) {
21
21
  const v = parseInt(sig.slice(128, 130), 16);
22
22
  return { v, r, s };
23
23
  }
24
- export function createFacilitatorHandler(network, publicClient, walletClient, assetName) {
25
- if (network !== BASE_SEPOLIA_NETWORK) {
26
- throw new Error(`Unsupported network: ${network}. Only base-sepolia is supported.`);
24
+ export async function createFacilitatorHandler(network, publicClient, walletClient, assetName) {
25
+ if (!isKnownNetwork(network)) {
26
+ throw new Error(`Unknown network ${network}`);
27
27
  }
28
28
  const networkInfo = lookupKnownNetwork(network);
29
29
  if (!networkInfo) {
30
30
  throw new Error(`Couldn't look up information for ${network}`);
31
31
  }
32
+ const { chainId } = networkInfo;
32
33
  if (!isKnownAsset(assetName)) {
33
34
  throw new Error(`Unknown asset: ${assetName}`);
34
35
  }
@@ -40,6 +41,12 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
40
41
  if (!isAddress(asset)) {
41
42
  throw new Error(`Invalid asset address: ${asset}`);
42
43
  }
44
+ {
45
+ const domain = await generateDomain(publicClient, chainId, asset);
46
+ if (domain.name != assetInfo.contractName) {
47
+ throw new Error(`On chain contract name (${domain.name}) doesn't match configured asset name (${assetInfo.contractName})`);
48
+ }
49
+ }
43
50
  const checkTuple = type({
44
51
  scheme: caseInsensitiveLiteral(X402_EXACT_SCHEME),
45
52
  network: caseInsensitiveLiteral(network),
@@ -56,9 +63,9 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
56
63
  maxTimeoutSeconds: 300,
57
64
  // Provide EIP-712 domain parameters for client signing
58
65
  extra: {
59
- name: assetName,
66
+ name: assetInfo.contractName,
60
67
  version: "2",
61
- chainId: networkInfo.chainId,
68
+ chainId,
62
69
  verifyingContract: asset,
63
70
  },
64
71
  }));
@@ -117,34 +124,7 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
117
124
  if (onChainUsed) {
118
125
  return errorResponse("Authorization already used on-chain");
119
126
  }
120
- // Read domain parameters from chain
121
- let tokenName;
122
- let tokenVersion;
123
- let chainId;
124
- try {
125
- [tokenName, tokenVersion, chainId] = await Promise.all([
126
- publicClient.readContract({
127
- address: asset,
128
- abi: TRANSFER_WITH_AUTHORIZATION_ABI,
129
- functionName: "name",
130
- }),
131
- publicClient.readContract({
132
- address: asset,
133
- abi: TRANSFER_WITH_AUTHORIZATION_ABI,
134
- functionName: "version",
135
- }),
136
- publicClient.getChainId(),
137
- ]);
138
- }
139
- catch (cause) {
140
- throw new Error("Failed to read contract parameters", { cause });
141
- }
142
- const domain = {
143
- name: tokenName,
144
- version: tokenVersion ?? "2",
145
- chainId,
146
- verifyingContract: asset,
147
- };
127
+ const domain = await generateDomain(publicClient, chainId, asset);
148
128
  const types = EIP712_TYPES;
149
129
  const message = {
150
130
  from: authorization.from,
@@ -209,7 +189,7 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
209
189
  to: asset,
210
190
  data,
211
191
  account: acct,
212
- chain: baseSepolia,
192
+ chain: undefined,
213
193
  });
214
194
  const serializedTransaction = await walletClient.signTransaction(request);
215
195
  const txHash = await publicClient.sendRawTransaction({
@@ -226,7 +206,7 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
226
206
  success: true,
227
207
  error: null,
228
208
  txHash,
229
- networkId: networkInfo.chainId.toString(),
209
+ networkId: chainId.toString(),
230
210
  };
231
211
  }
232
212
  catch (cause) {
@@ -1,4 +1,4 @@
1
1
  export { createPaymentHandler } from "./client.js";
2
2
  export { createFacilitatorHandler } from "./facilitator.js";
3
- export { X402_EXACT_SCHEME, BASE_SEPOLIA_NETWORK, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";
3
+ export { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/exact/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,+BAA+B,EAC/B,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/exact/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAC/B,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  export { createPaymentHandler } from "./client.js";
2
2
  export { createFacilitatorHandler } from "./facilitator.js";
3
- export { X402_EXACT_SCHEME, BASE_SEPOLIA_NETWORK, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";
3
+ export { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";