@faremeter/payment-evm 0.5.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.
@@ -1,4 +1,4 @@
1
- import type { PaymentHandler } from "@faremeter/types";
1
+ import type { PaymentHandler } from "@faremeter/types/client";
2
2
  import type { Hex } from "viem";
3
3
  interface WalletForPayment {
4
4
  network: string;
@@ -0,0 +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;AAOjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAWhC,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,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,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,cAAc,CA+G7E"}
@@ -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";
@@ -0,0 +1 @@
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
- import { type FacilitatorHandler } from "@faremeter/types";
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
@@ -0,0 +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;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"}
@@ -1,9 +1,10 @@
1
- import { isValidationError, caseInsensitiveLiteral, } from "@faremeter/types";
1
+ import { isValidationError, caseInsensitiveLiteral } from "@faremeter/types";
2
+ import {} from "@faremeter/types/facilitator";
2
3
  import { type } from "arktype";
3
4
  import { verifyTypedData, encodeFunctionData, isAddress } from "viem";
4
- import { baseSepolia } from "viem/chains";
5
- import { isKnownAsset, lookupKnownAsset, lookupKnownNetwork, } from "@faremeter/info/evm";
6
- 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";
7
8
  function errorResponse(msg) {
8
9
  return {
9
10
  success: false,
@@ -20,14 +21,15 @@ function parseSignature(signature) {
20
21
  const v = parseInt(sig.slice(128, 130), 16);
21
22
  return { v, r, s };
22
23
  }
23
- export function createFacilitatorHandler(network, publicClient, walletClient, assetName) {
24
- if (network !== BASE_SEPOLIA_NETWORK) {
25
- 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}`);
26
27
  }
27
28
  const networkInfo = lookupKnownNetwork(network);
28
29
  if (!networkInfo) {
29
30
  throw new Error(`Couldn't look up information for ${network}`);
30
31
  }
32
+ const { chainId } = networkInfo;
31
33
  if (!isKnownAsset(assetName)) {
32
34
  throw new Error(`Unknown asset: ${assetName}`);
33
35
  }
@@ -39,6 +41,12 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
39
41
  if (!isAddress(asset)) {
40
42
  throw new Error(`Invalid asset address: ${asset}`);
41
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
+ }
42
50
  const checkTuple = type({
43
51
  scheme: caseInsensitiveLiteral(X402_EXACT_SCHEME),
44
52
  network: caseInsensitiveLiteral(network),
@@ -55,9 +63,9 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
55
63
  maxTimeoutSeconds: 300,
56
64
  // Provide EIP-712 domain parameters for client signing
57
65
  extra: {
58
- name: assetName,
66
+ name: assetInfo.contractName,
59
67
  version: "2",
60
- chainId: networkInfo.chainId,
68
+ chainId,
61
69
  verifyingContract: asset,
62
70
  },
63
71
  }));
@@ -111,39 +119,12 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
111
119
  });
112
120
  }
113
121
  catch (error) {
114
- return errorResponse(`Failed to check authorization status: ${error instanceof Error ? error.message : "Unknown error"}`);
122
+ throw new Error("Failed to check authorization status", { cause: error });
115
123
  }
116
124
  if (onChainUsed) {
117
125
  return errorResponse("Authorization already used on-chain");
118
126
  }
119
- // Read domain parameters from chain
120
- let tokenName;
121
- let tokenVersion;
122
- let chainId;
123
- try {
124
- [tokenName, tokenVersion, chainId] = await Promise.all([
125
- publicClient.readContract({
126
- address: asset,
127
- abi: TRANSFER_WITH_AUTHORIZATION_ABI,
128
- functionName: "name",
129
- }),
130
- publicClient.readContract({
131
- address: asset,
132
- abi: TRANSFER_WITH_AUTHORIZATION_ABI,
133
- functionName: "version",
134
- }),
135
- publicClient.getChainId(),
136
- ]);
137
- }
138
- catch (error) {
139
- return errorResponse(`Failed to read contract parameters: ${error instanceof Error ? error.message : "Unknown error"}`);
140
- }
141
- const domain = {
142
- name: tokenName,
143
- version: tokenVersion ?? "2",
144
- chainId,
145
- verifyingContract: asset,
146
- };
127
+ const domain = await generateDomain(publicClient, chainId, asset);
147
128
  const types = EIP712_TYPES;
148
129
  const message = {
149
130
  from: authorization.from,
@@ -165,8 +146,8 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
165
146
  signature: signature,
166
147
  });
167
148
  }
168
- catch (error) {
169
- return errorResponse(`Signature verification failed: ${error instanceof Error ? error.message : "Unknown error"}`);
149
+ catch (cause) {
150
+ throw new Error("Signature verification failed", { cause });
170
151
  }
171
152
  if (!isValidSignature) {
172
153
  return errorResponse("Invalid signature");
@@ -179,8 +160,8 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
179
160
  functionName: "DOMAIN_SEPARATOR",
180
161
  });
181
162
  }
182
- catch (error) {
183
- return errorResponse(`Contract does not support EIP-712: ${error instanceof Error ? error.message : "Unknown error"}`);
163
+ catch (cause) {
164
+ throw new Error("Contract does not support EIP-712", { cause });
184
165
  }
185
166
  const acct = walletClient.account;
186
167
  if (!acct || acct.type !== "local") {
@@ -208,7 +189,7 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
208
189
  to: asset,
209
190
  data,
210
191
  account: acct,
211
- chain: baseSepolia,
192
+ chain: undefined,
212
193
  });
213
194
  const serializedTransaction = await walletClient.signTransaction(request);
214
195
  const txHash = await publicClient.sendRawTransaction({
@@ -225,11 +206,11 @@ export function createFacilitatorHandler(network, publicClient, walletClient, as
225
206
  success: true,
226
207
  error: null,
227
208
  txHash,
228
- networkId: networkInfo.chainId.toString(),
209
+ networkId: chainId.toString(),
229
210
  };
230
211
  }
231
- catch (error) {
232
- return errorResponse(`Transaction execution failed: ${error instanceof Error ? error.message : "Unknown error"}`);
212
+ catch (cause) {
213
+ throw new Error("Transaction execution failed", { cause });
233
214
  }
234
215
  };
235
216
  return {
@@ -0,0 +1,4 @@
1
+ export { createPaymentHandler } from "./client.js";
2
+ export { createFacilitatorHandler } from "./facilitator.js";
3
+ export { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,+BAA+B,EAC/B,YAAY,EACZ,gBAAgB,EAChB,YAAY,GACb,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { createPaymentHandler } from "./client.js";
2
+ export { createFacilitatorHandler } from "./facilitator.js";
3
+ export { X402_EXACT_SCHEME, TRANSFER_WITH_AUTHORIZATION_ABI, EIP712_TYPES, x402ExactPayload, eip712Domain, } from "./constants.js";
@@ -1,4 +1,2 @@
1
- export { createPaymentHandler } from "./client.js";
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";
1
+ export * as exact from "./exact/index.js";
4
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/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/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC"}
package/dist/src/index.js CHANGED
@@ -1,3 +1 @@
1
- export { createPaymentHandler } from "./client.js";
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";
1
+ export * as exact from "./exact/index.js";