thirdweb 5.108.2 → 5.108.4-nightly-a94e9c2396956887d30da0b220675ed315b283ee-20250927000336

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.
Files changed (68) hide show
  1. package/dist/cjs/exports/x402.js.map +1 -1
  2. package/dist/cjs/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js +176 -0
  3. package/dist/cjs/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js.map +1 -0
  4. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js +2 -2
  5. package/dist/cjs/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  6. package/dist/cjs/stories/ConnectEmbed.stories.js +0 -3
  7. package/dist/cjs/stories/ConnectEmbed.stories.js.map +1 -1
  8. package/dist/cjs/version.js +1 -1
  9. package/dist/cjs/version.js.map +1 -1
  10. package/dist/cjs/x402/common.js +39 -1
  11. package/dist/cjs/x402/common.js.map +1 -1
  12. package/dist/cjs/x402/facilitator.js +1 -0
  13. package/dist/cjs/x402/facilitator.js.map +1 -1
  14. package/dist/cjs/x402/fetchWithPayment.js +2 -2
  15. package/dist/cjs/x402/fetchWithPayment.js.map +1 -1
  16. package/dist/cjs/x402/sign.js +100 -34
  17. package/dist/cjs/x402/sign.js.map +1 -1
  18. package/dist/cjs/x402/types.js.map +1 -1
  19. package/dist/esm/exports/x402.js.map +1 -1
  20. package/dist/esm/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js +169 -0
  21. package/dist/esm/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js.map +1 -0
  22. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js +2 -2
  23. package/dist/esm/react/web/ui/ConnectWallet/Modal/ConnectEmbed.js.map +1 -1
  24. package/dist/esm/stories/ConnectEmbed.stories.js +0 -3
  25. package/dist/esm/stories/ConnectEmbed.stories.js.map +1 -1
  26. package/dist/esm/version.js +1 -1
  27. package/dist/esm/version.js.map +1 -1
  28. package/dist/esm/x402/common.js +38 -1
  29. package/dist/esm/x402/common.js.map +1 -1
  30. package/dist/esm/x402/facilitator.js +1 -0
  31. package/dist/esm/x402/facilitator.js.map +1 -1
  32. package/dist/esm/x402/fetchWithPayment.js +2 -2
  33. package/dist/esm/x402/fetchWithPayment.js.map +1 -1
  34. package/dist/esm/x402/sign.js +100 -34
  35. package/dist/esm/x402/sign.js.map +1 -1
  36. package/dist/esm/x402/types.js.map +1 -1
  37. package/dist/scripts/bridge-widget.js +3 -3
  38. package/dist/types/exports/x402.d.ts +1 -1
  39. package/dist/types/exports/x402.d.ts.map +1 -1
  40. package/dist/types/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.d.ts +121 -0
  41. package/dist/types/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.d.ts.map +1 -0
  42. package/dist/types/react/web/ui/Bridge/swap-widget/SwapWidget.d.ts +1 -1
  43. package/dist/types/react/web/ui/ConnectWallet/Modal/ConnectEmbed.d.ts.map +1 -1
  44. package/dist/types/stories/ConnectEmbed.stories.d.ts.map +1 -1
  45. package/dist/types/version.d.ts +1 -1
  46. package/dist/types/version.d.ts.map +1 -1
  47. package/dist/types/x402/common.d.ts +8 -1
  48. package/dist/types/x402/common.d.ts.map +1 -1
  49. package/dist/types/x402/facilitator.d.ts +18 -41
  50. package/dist/types/x402/facilitator.d.ts.map +1 -1
  51. package/dist/types/x402/fetchWithPayment.d.ts +1 -1
  52. package/dist/types/x402/fetchWithPayment.d.ts.map +1 -1
  53. package/dist/types/x402/sign.d.ts +2 -1
  54. package/dist/types/x402/sign.d.ts.map +1 -1
  55. package/dist/types/x402/types.d.ts +16 -3
  56. package/dist/types/x402/types.d.ts.map +1 -1
  57. package/package.json +3 -3
  58. package/src/exports/x402.ts +1 -0
  59. package/src/extensions/erc20/__generated__/USDC/write/transferWithAuthorization.ts +215 -0
  60. package/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx +1 -1
  61. package/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx +2 -3
  62. package/src/stories/ConnectEmbed.stories.tsx +0 -3
  63. package/src/version.ts +1 -1
  64. package/src/x402/common.ts +58 -5
  65. package/src/x402/facilitator.ts +28 -1
  66. package/src/x402/fetchWithPayment.ts +3 -2
  67. package/src/x402/sign.ts +140 -49
  68. package/src/x402/types.ts +18 -7
@@ -1,15 +1,25 @@
1
- import { type ERC20TokenAmount, type Money, moneySchema } from "x402/types";
1
+ import type { Abi } from "abitype";
2
+ import { toFunctionSelector } from "viem/utils";
3
+ import { type Money, moneySchema } from "x402/types";
4
+ import { getCachedChain } from "../chains/utils.js";
5
+ import type { ThirdwebClient } from "../client/client.js";
6
+ import { resolveContractAbi } from "../contract/actions/resolve-abi.js";
7
+ import { getContract } from "../contract/contract.js";
8
+ import { isPermitSupported } from "../extensions/erc20/__generated__/IERC20Permit/write/permit.js";
9
+ import { isTransferWithAuthorizationSupported } from "../extensions/erc20/__generated__/USDC/write/transferWithAuthorization.js";
2
10
  import { getAddress } from "../utils/address.js";
3
11
  import { decodePayment } from "./encode.js";
4
- import type { facilitator as facilitatorType } from "./facilitator.js";
12
+ import type { ThirdwebX402Facilitator } from "./facilitator.js";
5
13
  import {
6
14
  networkToChainId,
7
15
  type RequestedPaymentPayload,
8
16
  type RequestedPaymentRequirements,
9
17
  } from "./schemas.js";
10
18
  import {
19
+ type ERC20TokenAmount,
11
20
  type PaymentArgs,
12
21
  type PaymentRequiredResult,
22
+ type SupportedSignatureType,
13
23
  x402Version,
14
24
  } from "./types.js";
15
25
 
@@ -106,7 +116,10 @@ export async function decodePaymentRequest(
106
116
  },
107
117
  output: outputSchema,
108
118
  },
109
- extra: (asset as ERC20TokenAmount["asset"]).eip712,
119
+ extra: {
120
+ facilitatorAddress: facilitator.address,
121
+ ...((asset as ERC20TokenAmount["asset"]).eip712 ?? {}),
122
+ },
110
123
  });
111
124
 
112
125
  // Check for payment header
@@ -184,7 +197,7 @@ export async function decodePaymentRequest(
184
197
  async function processPriceToAtomicAmount(
185
198
  price: Money | ERC20TokenAmount,
186
199
  chainId: number,
187
- facilitator: ReturnType<typeof facilitatorType>,
200
+ facilitator: ThirdwebX402Facilitator,
188
201
  ): Promise<
189
202
  | { maxAmountRequired: string; asset: ERC20TokenAmount["asset"] }
190
203
  | { error: string }
@@ -224,7 +237,7 @@ async function processPriceToAtomicAmount(
224
237
 
225
238
  async function getDefaultAsset(
226
239
  chainId: number,
227
- facilitator: ReturnType<typeof facilitatorType>,
240
+ facilitator: ThirdwebX402Facilitator,
228
241
  ): Promise<ERC20TokenAmount["asset"] | undefined> {
229
242
  const supportedAssets = await facilitator.supported();
230
243
  const matchingAsset = supportedAssets.kinds.find(
@@ -234,3 +247,43 @@ async function getDefaultAsset(
234
247
  ?.defaultAsset as ERC20TokenAmount["asset"];
235
248
  return assetConfig;
236
249
  }
250
+
251
+ export async function getSupportedSignatureType(args: {
252
+ client: ThirdwebClient;
253
+ asset: string;
254
+ chainId: number;
255
+ eip712Extras: ERC20TokenAmount["asset"]["eip712"] | undefined;
256
+ }): Promise<SupportedSignatureType | undefined> {
257
+ const primaryType = args.eip712Extras?.primaryType;
258
+
259
+ if (primaryType === "Permit" || primaryType === "TransferWithAuthorization") {
260
+ return primaryType;
261
+ }
262
+
263
+ // not specified, so we need to detect it
264
+ const abi = await resolveContractAbi<Abi>(
265
+ getContract({
266
+ client: args.client,
267
+ address: args.asset,
268
+ chain: getCachedChain(args.chainId),
269
+ }),
270
+ ).catch((error) => {
271
+ console.error("Error resolving contract ABI", error);
272
+ return [] as Abi;
273
+ });
274
+ const selectors = abi
275
+ .filter((f) => f.type === "function")
276
+ .map((f) => toFunctionSelector(f));
277
+ const hasPermit = isPermitSupported(selectors);
278
+ const hasTransferWithAuthorization =
279
+ isTransferWithAuthorizationSupported(selectors);
280
+
281
+ // prefer transferWithAuthorization over permit
282
+ if (hasTransferWithAuthorization) {
283
+ return "TransferWithAuthorization";
284
+ }
285
+ if (hasPermit) {
286
+ return "Permit";
287
+ }
288
+ return undefined;
289
+ }
@@ -15,6 +15,30 @@ export type ThirdwebX402FacilitatorConfig = {
15
15
  baseUrl?: string;
16
16
  };
17
17
 
18
+ /**
19
+ * facilitator for the x402 payment protocol.
20
+ * @public
21
+ */
22
+ export type ThirdwebX402Facilitator = {
23
+ url: `${string}://${string}`;
24
+ address: string;
25
+ createAuthHeaders: () => Promise<{
26
+ verify: Record<string, string>;
27
+ settle: Record<string, string>;
28
+ supported: Record<string, string>;
29
+ list: Record<string, string>;
30
+ }>;
31
+ verify: (
32
+ payload: RequestedPaymentPayload,
33
+ paymentRequirements: RequestedPaymentRequirements,
34
+ ) => Promise<VerifyResponse>;
35
+ settle: (
36
+ payload: RequestedPaymentPayload,
37
+ paymentRequirements: RequestedPaymentRequirements,
38
+ ) => Promise<FacilitatorSettleResponse>;
39
+ supported: () => Promise<SupportedPaymentKindsResponse>;
40
+ };
41
+
18
42
  const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402";
19
43
 
20
44
  /**
@@ -56,7 +80,9 @@ const DEFAULT_BASE_URL = "https://api.thirdweb.com/v1/payments/x402";
56
80
  *
57
81
  * @bridge x402
58
82
  */
59
- export function facilitator(config: ThirdwebX402FacilitatorConfig) {
83
+ export function facilitator(
84
+ config: ThirdwebX402FacilitatorConfig,
85
+ ): ThirdwebX402Facilitator {
60
86
  const secretKey = config.client.secretKey;
61
87
  if (!secretKey) {
62
88
  throw new Error("Client secret key is required for the x402 facilitator");
@@ -69,6 +95,7 @@ export function facilitator(config: ThirdwebX402FacilitatorConfig) {
69
95
  }
70
96
  const facilitator = {
71
97
  url: (config.baseUrl ?? DEFAULT_BASE_URL) as `${string}://${string}`,
98
+ address: serverWalletAddress,
72
99
  createAuthHeaders: async () => {
73
100
  return {
74
101
  verify: {
@@ -50,7 +50,7 @@ import { createPaymentHeader } from "./sign.js";
50
50
  */
51
51
  export function wrapFetchWithPayment(
52
52
  fetch: typeof globalThis.fetch,
53
- _client: ThirdwebClient,
53
+ client: ThirdwebClient,
54
54
  wallet: Wallet,
55
55
  maxValue: bigint = BigInt(1 * 10 ** 6), // Default to 1 USDC
56
56
  ) {
@@ -103,9 +103,10 @@ export function wrapFetchWithPayment(
103
103
  }
104
104
 
105
105
  const paymentHeader = await createPaymentHeader(
106
+ client,
106
107
  account,
107
- x402Version,
108
108
  selectedPaymentRequirements,
109
+ x402Version,
109
110
  );
110
111
 
111
112
  const initParams = init || {};
package/src/x402/sign.ts CHANGED
@@ -1,7 +1,13 @@
1
+ import { hexToBigInt } from "viem";
1
2
  import type { ExactEvmPayloadAuthorization } from "x402/types";
3
+ import { getCachedChain } from "../chains/utils.js";
4
+ import type { ThirdwebClient } from "../client/client.js";
5
+ import { getContract } from "../contract/contract.js";
6
+ import { nonces } from "../extensions/erc20/__generated__/IERC20Permit/read/nonces.js";
2
7
  import { type Address, getAddress } from "../utils/address.js";
3
8
  import { type Hex, toHex } from "../utils/encoding/hex.js";
4
9
  import type { Account } from "../wallets/interfaces/wallet.js";
10
+ import { getSupportedSignatureType } from "./common.js";
5
11
  import { encodePayment } from "./encode.js";
6
12
  import {
7
13
  networkToChainId,
@@ -9,6 +15,7 @@ import {
9
15
  type RequestedPaymentRequirements,
10
16
  type UnsignedPaymentPayload,
11
17
  } from "./schemas.js";
18
+ import type { ERC20TokenAmount } from "./types.js";
12
19
 
13
20
  /**
14
21
  * Prepares an unsigned payment header with the given sender address and payment requirements.
@@ -22,9 +29,8 @@ function preparePaymentHeader(
22
29
  from: Address,
23
30
  x402Version: number,
24
31
  paymentRequirements: RequestedPaymentRequirements,
32
+ nonce: Hex,
25
33
  ): UnsignedPaymentPayload {
26
- const nonce = createNonce();
27
-
28
34
  const validAfter = BigInt(
29
35
  Math.floor(Date.now() / 1000) - 600, // 10 minutes before
30
36
  ).toString();
@@ -44,7 +50,7 @@ function preparePaymentHeader(
44
50
  value: paymentRequirements.maxAmountRequired,
45
51
  validAfter: validAfter.toString(),
46
52
  validBefore: validBefore.toString(),
47
- nonce,
53
+ nonce: nonce,
48
54
  },
49
55
  },
50
56
  };
@@ -59,45 +65,78 @@ function preparePaymentHeader(
59
65
  * @returns A promise that resolves to the signed payment payload
60
66
  */
61
67
  async function signPaymentHeader(
68
+ client: ThirdwebClient,
62
69
  account: Account,
63
70
  paymentRequirements: RequestedPaymentRequirements,
64
- unsignedPaymentHeader: UnsignedPaymentPayload,
65
- ): Promise<RequestedPaymentPayload> {
66
- const { signature } = await signAuthorization(
67
- account,
68
- unsignedPaymentHeader.payload.authorization,
69
- paymentRequirements,
70
- );
71
-
72
- return {
73
- ...unsignedPaymentHeader,
74
- payload: {
75
- ...unsignedPaymentHeader.payload,
76
- signature,
77
- },
78
- };
79
- }
80
-
81
- /**
82
- * Creates a complete payment payload by preparing and signing a payment header.
83
- *
84
- * @param client - The signer wallet instance used to create and sign the payment
85
- * @param x402Version - The version of the X402 protocol to use
86
- * @param paymentRequirements - The payment requirements containing scheme and network information
87
- * @returns A promise that resolves to the complete signed payment payload
88
- */
89
- async function createPayment(
90
- account: Account,
91
71
  x402Version: number,
92
- paymentRequirements: RequestedPaymentRequirements,
93
72
  ): Promise<RequestedPaymentPayload> {
94
73
  const from = getAddress(account.address);
95
- const unsignedPaymentHeader = preparePaymentHeader(
96
- from,
97
- x402Version,
98
- paymentRequirements,
99
- );
100
- return signPaymentHeader(account, paymentRequirements, unsignedPaymentHeader);
74
+ const chainId = networkToChainId(paymentRequirements.network);
75
+ const supportedSignatureType = await getSupportedSignatureType({
76
+ client,
77
+ asset: paymentRequirements.asset,
78
+ chainId: chainId,
79
+ eip712Extras: paymentRequirements.extra as
80
+ | ERC20TokenAmount["asset"]["eip712"]
81
+ | undefined,
82
+ });
83
+
84
+ switch (supportedSignatureType) {
85
+ case "Permit": {
86
+ const nonce = await nonces({
87
+ contract: getContract({
88
+ address: paymentRequirements.asset,
89
+ chain: getCachedChain(chainId),
90
+ client: client,
91
+ }),
92
+ owner: from,
93
+ });
94
+ const unsignedPaymentHeader = preparePaymentHeader(
95
+ from,
96
+ x402Version,
97
+ paymentRequirements,
98
+ toHex(nonce, { size: 32 }), // permit nonce
99
+ );
100
+ const { signature } = await signERC2612Permit(
101
+ account,
102
+ unsignedPaymentHeader.payload.authorization,
103
+ paymentRequirements,
104
+ );
105
+ return {
106
+ ...unsignedPaymentHeader,
107
+ payload: {
108
+ ...unsignedPaymentHeader.payload,
109
+ signature,
110
+ },
111
+ };
112
+ }
113
+ case "TransferWithAuthorization": {
114
+ // default to transfer with authorization
115
+ const nonce = await createNonce();
116
+ const unsignedPaymentHeader = preparePaymentHeader(
117
+ from,
118
+ x402Version,
119
+ paymentRequirements,
120
+ nonce, // random nonce
121
+ );
122
+ const { signature } = await signERC3009Authorization(
123
+ account,
124
+ unsignedPaymentHeader.payload.authorization,
125
+ paymentRequirements,
126
+ );
127
+ return {
128
+ ...unsignedPaymentHeader,
129
+ payload: {
130
+ ...unsignedPaymentHeader.payload,
131
+ signature,
132
+ },
133
+ };
134
+ }
135
+ default:
136
+ throw new Error(
137
+ `No supported payment authorization methods found on ${paymentRequirements.asset} on chain ${paymentRequirements.network}`,
138
+ );
139
+ }
101
140
  }
102
141
 
103
142
  /**
@@ -109,14 +148,16 @@ async function createPayment(
109
148
  * @returns A promise that resolves to the encoded payment header string
110
149
  */
111
150
  export async function createPaymentHeader(
151
+ client: ThirdwebClient,
112
152
  account: Account,
113
- x402Version: number,
114
153
  paymentRequirements: RequestedPaymentRequirements,
154
+ x402Version: number,
115
155
  ): Promise<string> {
116
- const payment = await createPayment(
156
+ const payment = await signPaymentHeader(
157
+ client,
117
158
  account,
118
- x402Version,
119
159
  paymentRequirements,
160
+ x402Version,
120
161
  );
121
162
  return encodePayment(payment);
122
163
  }
@@ -138,7 +179,7 @@ export async function createPaymentHeader(
138
179
  * @param paymentRequirements.extra - The extra information containing the name and version of the ERC20 contract
139
180
  * @returns The signature for the authorization
140
181
  */
141
- async function signAuthorization(
182
+ async function signERC3009Authorization(
142
183
  account: Account,
143
184
  {
144
185
  from,
@@ -154,8 +195,7 @@ async function signAuthorization(
154
195
  const name = extra?.name;
155
196
  const version = extra?.version;
156
197
 
157
- // TODO (402): detect permit vs transfer on asset contract
158
- const data = {
198
+ const signature = await account.signTypedData({
159
199
  types: {
160
200
  TransferWithAuthorization: [
161
201
  { name: "from", type: "address" },
@@ -176,14 +216,65 @@ async function signAuthorization(
176
216
  message: {
177
217
  from: getAddress(from),
178
218
  to: getAddress(to),
179
- value,
180
- validAfter,
181
- validBefore,
182
- nonce: nonce,
219
+ value: BigInt(value),
220
+ validAfter: BigInt(validAfter),
221
+ validBefore: BigInt(validBefore),
222
+ nonce: nonce as Hex,
183
223
  },
224
+ });
225
+
226
+ return {
227
+ signature,
184
228
  };
229
+ }
230
+
231
+ async function signERC2612Permit(
232
+ account: Account,
233
+ { from, value, validBefore, nonce }: ExactEvmPayloadAuthorization,
234
+ { asset, network, extra }: RequestedPaymentRequirements,
235
+ ): Promise<{ signature: Hex }> {
236
+ const chainId = networkToChainId(network);
237
+ const name = extra?.name;
238
+ const version = extra?.version;
239
+ const facilitatorAddress = extra?.facilitatorAddress;
240
+ if (!facilitatorAddress) {
241
+ throw new Error(
242
+ "facilitatorAddress is required in PaymentRequirements extra to pay with permit-based assets",
243
+ );
244
+ }
245
+ if (!name || !version) {
246
+ throw new Error(
247
+ "name and version are required in PaymentRequirements extra to pay with permit-based assets",
248
+ );
249
+ }
250
+
251
+ //Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline
252
+ const signature = await account.signTypedData({
253
+ types: {
254
+ Permit: [
255
+ { name: "owner", type: "address" },
256
+ { name: "spender", type: "address" },
257
+ { name: "value", type: "uint256" },
258
+ { name: "nonce", type: "uint256" },
259
+ { name: "deadline", type: "uint256" },
260
+ ],
261
+ },
262
+ domain: {
263
+ name,
264
+ version,
265
+ chainId,
266
+ verifyingContract: getAddress(asset),
267
+ },
268
+ primaryType: "Permit" as const,
269
+ message: {
270
+ owner: getAddress(from),
271
+ spender: getAddress(facilitatorAddress), // approve the facilitator
272
+ value: BigInt(value),
273
+ nonce: hexToBigInt(nonce as Hex),
274
+ deadline: BigInt(validBefore),
275
+ },
276
+ });
185
277
 
186
- const signature = await account.signTypedData(data);
187
278
  return {
188
279
  signature,
189
280
  };
@@ -194,7 +285,7 @@ async function signAuthorization(
194
285
  *
195
286
  * @returns A random 32-byte nonce as a hex string
196
287
  */
197
- function createNonce(): Hex {
288
+ async function createNonce(): Promise<Hex> {
198
289
  const cryptoObj =
199
290
  typeof globalThis.crypto !== "undefined" &&
200
291
  typeof globalThis.crypto.getRandomValues === "function"
package/src/x402/types.ts CHANGED
@@ -1,12 +1,8 @@
1
- import type {
2
- ERC20TokenAmount,
3
- Money,
4
- PaymentMiddlewareConfig,
5
- } from "x402/types";
1
+ import type { Money, PaymentMiddlewareConfig } from "x402/types";
6
2
  import type { Chain } from "../chains/types.js";
7
3
  import type { Address } from "../utils/address.js";
8
4
  import type { Prettify } from "../utils/type-utils.js";
9
- import type { facilitator as facilitatorType } from "./facilitator.js";
5
+ import type { ThirdwebX402Facilitator } from "./facilitator.js";
10
6
  import type {
11
7
  FacilitatorNetwork,
12
8
  FacilitatorSettleResponse,
@@ -35,7 +31,7 @@ export type PaymentArgs = {
35
31
  /** The price for accessing the resource - either a USD amount (e.g., "$0.10") or a specific token amount */
36
32
  price: Money | ERC20TokenAmount;
37
33
  /** The payment facilitator instance used to verify and settle payments */
38
- facilitator: ReturnType<typeof facilitatorType>;
34
+ facilitator: ThirdwebX402Facilitator;
39
35
  /** Optional configuration for the payment middleware route */
40
36
  routeConfig?: PaymentMiddlewareConfig;
41
37
  };
@@ -89,3 +85,18 @@ export type VerifyPaymentResult = Prettify<
89
85
  }
90
86
  | PaymentRequiredResult
91
87
  >;
88
+
89
+ export type SupportedSignatureType = "TransferWithAuthorization" | "Permit";
90
+
91
+ export type ERC20TokenAmount = {
92
+ amount: string;
93
+ asset: {
94
+ address: `0x${string}`;
95
+ decimals: number;
96
+ eip712: {
97
+ name: string;
98
+ version: string;
99
+ primaryType: SupportedSignatureType;
100
+ };
101
+ };
102
+ };