@wtflabs/x402 0.0.1-beta.10 → 0.0.1-beta.11

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.
@@ -353,27 +353,30 @@ interface TokenPaymentCapabilities {
353
353
  };
354
354
  }
355
355
  /**
356
- * detect the payment methods supported by the token
356
+ * Detect the payment methods supported by the token
357
357
  *
358
358
  * @param tokenAddress - token address
359
359
  * @param client - viem PublicClient
360
- * @returns the payment capabilities of the token
360
+ * @returns detection result
361
361
  */
362
362
  declare function detectTokenPaymentMethods(tokenAddress: string, client: PublicClient): Promise<TokenPaymentCapabilities>;
363
363
  /**
364
- * get the recommended payment method for the token
364
+ * Get the recommended payment method (only return types supported by the schema)
365
+ * Sort by priority: eip3009 > permit > permit2
366
+ * Note: permit2-witness is mapped to permit2 because they are the same payment type in the schema
365
367
  *
366
368
  * @param tokenAddress - token address
367
369
  * @param client - viem PublicClient
368
- * @returns the recommended payment method
370
+ * @returns recommended payment method
369
371
  */
370
- declare function getRecommendedPaymentMethod(tokenAddress: string, client: PublicClient): Promise<"eip3009" | "permit" | "permit2" | null>;
372
+ declare function getRecommendedPaymentMethod(tokenAddress: string, client: PublicClient): Promise<"eip3009" | "permit2" | "permit" | null>;
371
373
  /**
372
- * get the name and version information of the token (for EIP-712 signing)
374
+ * Get the name and version information of the token (for EIP-712 signing)
375
+ * Supports proxy contracts (will automatically read from the proxy contract, because the proxy contract will delegatecall to the implementation contract)
373
376
  *
374
377
  * @param tokenAddress - token address
375
378
  * @param client - viem PublicClient
376
- * @returns the name and version information of the token
379
+ * @returns name and version information of the token
377
380
  */
378
381
  declare function getTokenInfo(tokenAddress: string, client: PublicClient): Promise<TokenInfo>;
379
382
 
@@ -1996,7 +1996,7 @@ async function settle(wallet, paymentPayload, paymentRequirements) {
1996
1996
  // token
1997
1997
  payload.authorization.from,
1998
1998
  // payer
1999
- payload.authorization.to,
1999
+ paymentRequirements.payTo,
2000
2000
  // seller
2001
2001
  BigInt(payload.authorization.value),
2002
2002
  // amount
@@ -2958,11 +2958,85 @@ async function createPaymentHeader3(client, x402Version, paymentRequirements) {
2958
2958
  var EIP3009_SIGNATURES = ["0xe3ee160e", "0xcf092995"];
2959
2959
  var EIP2612_PERMIT = "0xd505accf";
2960
2960
  var PERMIT2_ADDRESS2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
2961
+ var EIP1967_IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
2962
+ var EIP1822_IMPLEMENTATION_SLOT = "0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3";
2963
+ async function getImplementationAddress(client, proxyAddress) {
2964
+ try {
2965
+ try {
2966
+ const implSlotData = await client.getStorageAt({
2967
+ address: proxyAddress,
2968
+ slot: EIP1967_IMPLEMENTATION_SLOT
2969
+ });
2970
+ if (implSlotData && implSlotData !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
2971
+ const implAddress = `0x${implSlotData.slice(-40)}`;
2972
+ if (implAddress !== "0x0000000000000000000000000000000000000000") {
2973
+ console.log(` \u{1F4E6} Detected EIP-1967 proxy, implementation: ${implAddress}`);
2974
+ return implAddress;
2975
+ }
2976
+ }
2977
+ } catch {
2978
+ }
2979
+ try {
2980
+ const uupsSlotData = await client.getStorageAt({
2981
+ address: proxyAddress,
2982
+ slot: EIP1822_IMPLEMENTATION_SLOT
2983
+ });
2984
+ if (uupsSlotData && uupsSlotData !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
2985
+ const implAddress = `0x${uupsSlotData.slice(-40)}`;
2986
+ if (implAddress !== "0x0000000000000000000000000000000000000000") {
2987
+ console.log(` \u{1F4E6} Detected EIP-1822 UUPS proxy, implementation: ${implAddress}`);
2988
+ return implAddress;
2989
+ }
2990
+ }
2991
+ } catch {
2992
+ }
2993
+ try {
2994
+ const implABI = [
2995
+ {
2996
+ inputs: [],
2997
+ name: "implementation",
2998
+ outputs: [{ name: "", type: "address" }],
2999
+ stateMutability: "view",
3000
+ type: "function"
3001
+ }
3002
+ ];
3003
+ const implAddress = await client.readContract({
3004
+ address: proxyAddress,
3005
+ abi: implABI,
3006
+ functionName: "implementation"
3007
+ });
3008
+ if (implAddress && implAddress !== "0x0000000000000000000000000000000000000000") {
3009
+ console.log(` \u{1F4E6} Detected proxy via implementation(), implementation: ${implAddress}`);
3010
+ return implAddress;
3011
+ }
3012
+ } catch {
3013
+ }
3014
+ return null;
3015
+ } catch (error) {
3016
+ console.error("Error detecting proxy implementation:", error);
3017
+ return null;
3018
+ }
3019
+ }
2961
3020
  async function hasMethod(client, tokenAddress, methodSelector) {
2962
3021
  try {
2963
3022
  const code = await client.getBytecode({ address: tokenAddress });
2964
3023
  if (!code) return false;
2965
- return code.toLowerCase().includes(methodSelector.slice(2).toLowerCase());
3024
+ const hasMethodInProxy = code.toLowerCase().includes(methodSelector.slice(2).toLowerCase());
3025
+ if (hasMethodInProxy) {
3026
+ return true;
3027
+ }
3028
+ const implAddress = await getImplementationAddress(client, tokenAddress);
3029
+ if (implAddress) {
3030
+ const implCode = await client.getBytecode({ address: implAddress });
3031
+ if (implCode) {
3032
+ const hasMethodInImpl = implCode.toLowerCase().includes(methodSelector.slice(2).toLowerCase());
3033
+ if (hasMethodInImpl) {
3034
+ console.log(` \u2705 Method ${methodSelector} found in implementation contract`);
3035
+ }
3036
+ return hasMethodInImpl;
3037
+ }
3038
+ }
3039
+ return false;
2966
3040
  } catch (error) {
2967
3041
  console.error(`Error checking method ${methodSelector}:`, error);
2968
3042
  return false;
@@ -2973,7 +3047,27 @@ async function hasAnyMethod(client, tokenAddress, methodSelectors) {
2973
3047
  const code = await client.getBytecode({ address: tokenAddress });
2974
3048
  if (!code) return false;
2975
3049
  const codeLower = code.toLowerCase();
2976
- return methodSelectors.some((selector) => codeLower.includes(selector.slice(2).toLowerCase()));
3050
+ const hasMethodInProxy = methodSelectors.some(
3051
+ (selector) => codeLower.includes(selector.slice(2).toLowerCase())
3052
+ );
3053
+ if (hasMethodInProxy) {
3054
+ return true;
3055
+ }
3056
+ const implAddress = await getImplementationAddress(client, tokenAddress);
3057
+ if (implAddress) {
3058
+ const implCode = await client.getBytecode({ address: implAddress });
3059
+ if (implCode) {
3060
+ const implCodeLower = implCode.toLowerCase();
3061
+ const hasMethodInImpl = methodSelectors.some(
3062
+ (selector) => implCodeLower.includes(selector.slice(2).toLowerCase())
3063
+ );
3064
+ if (hasMethodInImpl) {
3065
+ console.log(` \u2705 Method(s) found in implementation contract`);
3066
+ }
3067
+ return hasMethodInImpl;
3068
+ }
3069
+ }
3070
+ return false;
2977
3071
  } catch (error) {
2978
3072
  console.error(`Error checking methods ${methodSelectors.join(", ")}:`, error);
2979
3073
  return false;
@@ -3072,6 +3166,12 @@ async function getTokenInfo(tokenAddress, client) {
3072
3166
  }
3073
3167
  ];
3074
3168
  try {
3169
+ const implAddress = await getImplementationAddress(client, address);
3170
+ if (implAddress) {
3171
+ console.log(
3172
+ ` \u{1F4E6} Reading token info from proxy, actual calls will be delegated to implementation`
3173
+ );
3174
+ }
3075
3175
  const name = await client.readContract({
3076
3176
  address,
3077
3177
  abi: erc20ABI,