@account-kit/privy-integration 4.73.1-alpha.4 → 4.73.1-alpha.6

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.
@@ -22,11 +22,15 @@ export const reactNativeAdapter = {
22
22
  },
23
23
  useAuthorizationSigner() {
24
24
  const { wallets } = useEmbeddedEthereumWallet();
25
- return useCallback(async (unsignedAuth) => {
25
+ // Don't memoize the callback - create it fresh each time to ensure we have the latest wallets
26
+ const signAuthorization = async (unsignedAuth) => {
27
+ console.log("[RN Adapter] signAuthorization called with:", unsignedAuth);
28
+ console.log("[RN Adapter] Current wallets:", wallets);
26
29
  const wallet = wallets?.[0];
27
30
  if (!wallet) {
28
31
  throw new Error("Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.");
29
32
  }
33
+ console.log("[RN Adapter] Using wallet:", wallet.address);
30
34
  const provider = await wallet.getProvider?.();
31
35
  if (!provider) {
32
36
  throw new Error("Provider not available on this wallet. Ensure you're using the embedded Ethereum wallet.");
@@ -36,6 +40,7 @@ export const reactNativeAdapter = {
36
40
  if (!implementationAddress) {
37
41
  throw new Error("Implementation address is required for EIP-7702 authorization");
38
42
  }
43
+ console.log("[RN Adapter] Signing 7702 auth for address:", implementationAddress);
39
44
  // EIP-7702 Authorization structure
40
45
  const authorization = {
41
46
  domain: {
@@ -61,6 +66,7 @@ export const reactNativeAdapter = {
61
66
  method: "eth_signTypedData_v4",
62
67
  params: [wallet.address, JSON.stringify(authorization)],
63
68
  }));
69
+ console.log("[RN Adapter] Received signature:", signature);
64
70
  // Parse the signature into r, s, v components
65
71
  // Signature format: 0x[r(64)][s(64)][v(2)]
66
72
  const r = `0x${signature.slice(2, 66)}`;
@@ -69,7 +75,7 @@ export const reactNativeAdapter = {
69
75
  // Convert v to yParity (0 or 1)
70
76
  // v can be 27/28 (legacy) or 0/1 (EIP-155)
71
77
  const yParity = v >= 27 ? v - 27 : v;
72
- return {
78
+ const result = {
73
79
  chainId: unsignedAuth.chainId,
74
80
  address: implementationAddress,
75
81
  nonce: unsignedAuth.nonce,
@@ -77,7 +83,10 @@ export const reactNativeAdapter = {
77
83
  s,
78
84
  yParity,
79
85
  };
80
- }, [wallets]);
86
+ console.log("[RN Adapter] Returning authorization:", result);
87
+ return result;
88
+ };
89
+ return signAuthorization;
81
90
  },
82
91
  };
83
92
  /**
@@ -87,14 +96,34 @@ export const reactNativeAdapter = {
87
96
  * @returns {EmbeddedWallet} The adapted wallet following the common interface
88
97
  */
89
98
  function adaptExpoWallet(wallet) {
99
+ // Use closure to maintain up-to-date chain ID across chain switches
100
+ let cachedChainId = wallet.chainId || "1";
90
101
  return {
91
102
  address: wallet.address,
92
- chainId: wallet.chainId || "1",
103
+ get chainId() {
104
+ return cachedChainId;
105
+ },
93
106
  getEthereumProvider: async () => {
94
107
  if (!wallet.getProvider) {
95
108
  throw new Error("getProvider is not available on this wallet. Ensure you're using the embedded Ethereum wallet.");
96
109
  }
97
- return await wallet.getProvider();
110
+ const provider = await wallet.getProvider();
111
+ // Always fetch current chain ID when provider is accessed
112
+ // This ensures we have the latest chain after wallet_switchEthereumChain calls
113
+ try {
114
+ const currentChainId = (await provider.request({
115
+ method: "eth_chainId",
116
+ params: [],
117
+ }));
118
+ // Convert hex to decimal string format (e.g., "0x1" -> "1")
119
+ cachedChainId = parseInt(currentChainId, 16).toString();
120
+ console.log("[RN Adapter] Updated chain ID to:", cachedChainId);
121
+ }
122
+ catch (err) {
123
+ console.warn("[Privy Integration] Failed to fetch current chain ID:", err);
124
+ // Fall back to cached value if fetch fails
125
+ }
126
+ return provider;
98
127
  },
99
128
  };
100
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"react-native.js","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EACL,QAAQ,EACR,yBAAyB,GAE1B,MAAM,gBAAgB,CAAC;AAexB;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC9C,iBAAiB;QACf,MAAM,EAAE,OAAO,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEhD,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAmB,EAAE;YACzD,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;YACJ,CAAC;YAED,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAEd,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,YAAY;QACV,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IACzC,CAAC;IAED,sBAAsB;QACpB,MAAM,EAAE,OAAO,EAAE,GAAG,yBAAyB,EAAE,CAAC;QAEhD,OAAO,WAAW,CAChB,KAAK,EACH,YAA0C,EACJ,EAAE;YACxC,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;YACJ,CAAC;YAED,0FAA0F;YAC1F,MAAM,qBAAqB,GACzB,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,eAAe,CAAC;YAEvD,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;YACJ,CAAC;YAED,mCAAmC;YACnC,MAAM,aAAa,GAAG;gBACpB,MAAM,EAAE;oBACN,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,GAAG;oBACZ,OAAO,EAAE,YAAY,CAAC,OAAO;iBAC9B;gBACD,KAAK,EAAE;oBACL,aAAa,EAAE;wBACb,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;wBACpC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;wBACpC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;qBACnC;iBACF;gBACD,WAAW,EAAE,eAAwB;gBACrC,OAAO,EAAE;oBACP,OAAO,EAAE,YAAY,CAAC,OAAO;oBAC7B,OAAO,EAAE,qBAAqB;oBAC9B,KAAK,EAAE,YAAY,CAAC,KAAK;iBAC1B;aACF,CAAC;YAEF,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC;gBACxC,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;aACxD,CAAC,CAAkB,CAAC;YAErB,8CAA8C;YAC9C,2CAA2C;YAC3C,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAmB,CAAC;YACzD,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,EAAmB,CAAC;YAC3D,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YAElD,gCAAgC;YAChC,2CAA2C;YAC3C,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAErC,OAAO;gBACL,OAAO,EAAE,YAAY,CAAC,OAAO;gBAC7B,OAAO,EAAE,qBAAqB;gBAC9B,KAAK,EAAE,YAAY,CAAC,KAAK;gBACzB,CAAC;gBACD,CAAC;gBACD,OAAO;aACR,CAAC;QACJ,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,SAAS,eAAe,CAAC,MAA0B;IACjD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAwB;QACxC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,GAAG;QAC9B,mBAAmB,EAAE,KAAK,IAAI,EAAE;YAC9B,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport {\n usePrivy,\n useEmbeddedEthereumWallet,\n type PrivyEmbeddedWalletProvider,\n} from \"@privy-io/expo\";\nimport type { Authorization } from \"viem\";\nimport type { AuthorizationRequest } from \"@aa-sdk/core\";\nimport type { PrivyAdapter, EmbeddedWallet, PrivyAuthState } from \"./types.js\";\n\n/**\n * Wallet type from @privy-io/expo\n * Based on the example app structure\n */\ninterface ExpoEmbeddedWallet {\n address: string;\n chainId?: string;\n getProvider?: () => Promise<PrivyEmbeddedWalletProvider>;\n}\n\n/**\n * React Native (Expo) adapter for @privy-io/expo\n * Implements platform-specific hooks for React Native applications\n */\nexport const reactNativeAdapter: PrivyAdapter = {\n useEmbeddedWallet() {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n const wallet = wallets?.[0];\n if (!wallet) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.\",\n );\n }\n\n return adaptExpoWallet(wallet);\n }, [wallets]);\n\n return getEmbeddedWallet;\n },\n\n usePrivyAuth(): PrivyAuthState {\n const { user } = usePrivy();\n return { authenticated: !!user, user };\n },\n\n useAuthorizationSigner() {\n const { wallets } = useEmbeddedEthereumWallet();\n\n return useCallback(\n async (\n unsignedAuth: AuthorizationRequest<number>,\n ): Promise<Authorization<number, true>> => {\n const wallet = wallets?.[0];\n if (!wallet) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.\",\n );\n }\n\n const provider = await wallet.getProvider?.();\n if (!provider) {\n throw new Error(\n \"Provider not available on this wallet. Ensure you're using the embedded Ethereum wallet.\",\n );\n }\n\n // Extract the implementation address (handle both 'address' and 'contractAddress' fields)\n const implementationAddress =\n unsignedAuth.address ?? unsignedAuth.contractAddress;\n\n if (!implementationAddress) {\n throw new Error(\n \"Implementation address is required for EIP-7702 authorization\",\n );\n }\n\n // EIP-7702 Authorization structure\n const authorization = {\n domain: {\n name: \"EIP-7702\",\n version: \"1\",\n chainId: unsignedAuth.chainId,\n },\n types: {\n Authorization: [\n { name: \"chainId\", type: \"uint256\" },\n { name: \"address\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n ],\n },\n primaryType: \"Authorization\" as const,\n message: {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n },\n };\n\n const signature = (await provider.request({\n method: \"eth_signTypedData_v4\",\n params: [wallet.address, JSON.stringify(authorization)],\n })) as `0x${string}`;\n\n // Parse the signature into r, s, v components\n // Signature format: 0x[r(64)][s(64)][v(2)]\n const r = `0x${signature.slice(2, 66)}` as `0x${string}`;\n const s = `0x${signature.slice(66, 130)}` as `0x${string}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n // Convert v to yParity (0 or 1)\n // v can be 27/28 (legacy) or 0/1 (EIP-155)\n const yParity = v >= 27 ? v - 27 : v;\n\n return {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n r,\n s,\n yParity,\n };\n },\n [wallets],\n );\n },\n};\n\n/**\n * Adapts an Expo wallet to the common EmbeddedWallet interface\n *\n * @param {ExpoEmbeddedWallet} wallet - The Expo embedded wallet to adapt\n * @returns {EmbeddedWallet} The adapted wallet following the common interface\n */\nfunction adaptExpoWallet(wallet: ExpoEmbeddedWallet): EmbeddedWallet {\n return {\n address: wallet.address as `0x${string}`,\n chainId: wallet.chainId || \"1\",\n getEthereumProvider: async () => {\n if (!wallet.getProvider) {\n throw new Error(\n \"getProvider is not available on this wallet. Ensure you're using the embedded Ethereum wallet.\",\n );\n }\n return await wallet.getProvider();\n },\n };\n}\n"]}
1
+ {"version":3,"file":"react-native.js","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback } from \"react\";\nimport {\n usePrivy,\n useEmbeddedEthereumWallet,\n type PrivyEmbeddedWalletProvider,\n} from \"@privy-io/expo\";\nimport type { Authorization } from \"viem\";\nimport type { AuthorizationRequest } from \"@aa-sdk/core\";\nimport type { PrivyAdapter, EmbeddedWallet, PrivyAuthState } from \"./types.js\";\n\n/**\n * Wallet type from @privy-io/expo\n * Based on the example app structure\n */\ninterface ExpoEmbeddedWallet {\n address: string;\n chainId?: string;\n getProvider?: () => Promise<PrivyEmbeddedWalletProvider>;\n}\n\n/**\n * React Native (Expo) adapter for @privy-io/expo\n * Implements platform-specific hooks for React Native applications\n */\nexport const reactNativeAdapter: PrivyAdapter = {\n useEmbeddedWallet() {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n const wallet = wallets?.[0];\n if (!wallet) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.\",\n );\n }\n\n return adaptExpoWallet(wallet);\n }, [wallets]);\n\n return getEmbeddedWallet;\n },\n\n usePrivyAuth(): PrivyAuthState {\n const { user } = usePrivy();\n return { authenticated: !!user, user };\n },\n\n useAuthorizationSigner() {\n const { wallets } = useEmbeddedEthereumWallet();\n\n // Don't memoize the callback - create it fresh each time to ensure we have the latest wallets\n const signAuthorization = async (\n unsignedAuth: AuthorizationRequest<number>,\n ): Promise<Authorization<number, true>> => {\n console.log(\"[RN Adapter] signAuthorization called with:\", unsignedAuth);\n console.log(\"[RN Adapter] Current wallets:\", wallets);\n\n const wallet = wallets?.[0];\n if (!wallet) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.\",\n );\n }\n\n console.log(\"[RN Adapter] Using wallet:\", wallet.address);\n\n const provider = await wallet.getProvider?.();\n if (!provider) {\n throw new Error(\n \"Provider not available on this wallet. Ensure you're using the embedded Ethereum wallet.\",\n );\n }\n\n // Extract the implementation address (handle both 'address' and 'contractAddress' fields)\n const implementationAddress =\n unsignedAuth.address ?? unsignedAuth.contractAddress;\n\n if (!implementationAddress) {\n throw new Error(\n \"Implementation address is required for EIP-7702 authorization\",\n );\n }\n\n console.log(\n \"[RN Adapter] Signing 7702 auth for address:\",\n implementationAddress,\n );\n\n // EIP-7702 Authorization structure\n const authorization = {\n domain: {\n name: \"EIP-7702\",\n version: \"1\",\n chainId: unsignedAuth.chainId,\n },\n types: {\n Authorization: [\n { name: \"chainId\", type: \"uint256\" },\n { name: \"address\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n ],\n },\n primaryType: \"Authorization\" as const,\n message: {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n },\n };\n\n const signature = (await provider.request({\n method: \"eth_signTypedData_v4\",\n params: [wallet.address, JSON.stringify(authorization)],\n })) as `0x${string}`;\n\n console.log(\"[RN Adapter] Received signature:\", signature);\n\n // Parse the signature into r, s, v components\n // Signature format: 0x[r(64)][s(64)][v(2)]\n const r = `0x${signature.slice(2, 66)}` as `0x${string}`;\n const s = `0x${signature.slice(66, 130)}` as `0x${string}`;\n const v = parseInt(signature.slice(130, 132), 16);\n\n // Convert v to yParity (0 or 1)\n // v can be 27/28 (legacy) or 0/1 (EIP-155)\n const yParity = v >= 27 ? v - 27 : v;\n\n const result = {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n r,\n s,\n yParity,\n };\n\n console.log(\"[RN Adapter] Returning authorization:\", result);\n return result;\n };\n\n return signAuthorization;\n },\n};\n\n/**\n * Adapts an Expo wallet to the common EmbeddedWallet interface\n *\n * @param {ExpoEmbeddedWallet} wallet - The Expo embedded wallet to adapt\n * @returns {EmbeddedWallet} The adapted wallet following the common interface\n */\nfunction adaptExpoWallet(wallet: ExpoEmbeddedWallet): EmbeddedWallet {\n // Use closure to maintain up-to-date chain ID across chain switches\n let cachedChainId = wallet.chainId || \"1\";\n\n return {\n address: wallet.address as `0x${string}`,\n get chainId() {\n return cachedChainId;\n },\n getEthereumProvider: async () => {\n if (!wallet.getProvider) {\n throw new Error(\n \"getProvider is not available on this wallet. Ensure you're using the embedded Ethereum wallet.\",\n );\n }\n const provider = await wallet.getProvider();\n\n // Always fetch current chain ID when provider is accessed\n // This ensures we have the latest chain after wallet_switchEthereumChain calls\n try {\n const currentChainId = (await provider.request({\n method: \"eth_chainId\",\n params: [],\n })) as string;\n\n // Convert hex to decimal string format (e.g., \"0x1\" -> \"1\")\n cachedChainId = parseInt(currentChainId, 16).toString();\n console.log(\"[RN Adapter] Updated chain ID to:\", cachedChainId);\n } catch (err) {\n console.warn(\n \"[Privy Integration] Failed to fetch current chain ID:\",\n err,\n );\n // Fall back to cached value if fetch fails\n }\n\n return provider;\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- export declare const VERSION = "4.73.1-alpha.4";
1
+ export declare const VERSION = "4.73.1-alpha.6";
@@ -1,4 +1,4 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "4.73.1-alpha.4";
3
+ export const VERSION = "4.73.1-alpha.6";
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.73.1-alpha.4\";\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,gBAAgB,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.73.1-alpha.6\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,YAAY,CAAC;AAY/E;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAuGhC,CAAC"}
1
+ {"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,YAAY,CAAC;AAY/E;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAsHhC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "4.73.1-alpha.4";
1
+ export declare const VERSION = "4.73.1-alpha.6";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@account-kit/privy-integration",
3
- "version": "4.73.1-alpha.4",
3
+ "version": "4.73.1-alpha.6",
4
4
  "description": "Use Alchemy gas sponsorship, swaps and more with Privy",
5
5
  "author": "Alchemy",
6
6
  "license": "MIT",
@@ -95,5 +95,5 @@
95
95
  "url": "https://github.com/alchemyplatform/aa-sdk/issues"
96
96
  },
97
97
  "homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
98
- "gitHead": "0b4e411c20856ba68c93c4c71877db2fafd87780"
98
+ "gitHead": "711614b095d09e184d5fdda7379774c898d04c35"
99
99
  }
@@ -48,82 +48,97 @@ export const reactNativeAdapter: PrivyAdapter = {
48
48
  useAuthorizationSigner() {
49
49
  const { wallets } = useEmbeddedEthereumWallet();
50
50
 
51
- return useCallback(
52
- async (
53
- unsignedAuth: AuthorizationRequest<number>,
54
- ): Promise<Authorization<number, true>> => {
55
- const wallet = wallets?.[0];
56
- if (!wallet) {
57
- throw new Error(
58
- "Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.",
59
- );
60
- }
61
-
62
- const provider = await wallet.getProvider?.();
63
- if (!provider) {
64
- throw new Error(
65
- "Provider not available on this wallet. Ensure you're using the embedded Ethereum wallet.",
66
- );
67
- }
68
-
69
- // Extract the implementation address (handle both 'address' and 'contractAddress' fields)
70
- const implementationAddress =
71
- unsignedAuth.address ?? unsignedAuth.contractAddress;
72
-
73
- if (!implementationAddress) {
74
- throw new Error(
75
- "Implementation address is required for EIP-7702 authorization",
76
- );
77
- }
78
-
79
- // EIP-7702 Authorization structure
80
- const authorization = {
81
- domain: {
82
- name: "EIP-7702",
83
- version: "1",
84
- chainId: unsignedAuth.chainId,
85
- },
86
- types: {
87
- Authorization: [
88
- { name: "chainId", type: "uint256" },
89
- { name: "address", type: "address" },
90
- { name: "nonce", type: "uint256" },
91
- ],
92
- },
93
- primaryType: "Authorization" as const,
94
- message: {
95
- chainId: unsignedAuth.chainId,
96
- address: implementationAddress,
97
- nonce: unsignedAuth.nonce,
98
- },
99
- };
100
-
101
- const signature = (await provider.request({
102
- method: "eth_signTypedData_v4",
103
- params: [wallet.address, JSON.stringify(authorization)],
104
- })) as `0x${string}`;
105
-
106
- // Parse the signature into r, s, v components
107
- // Signature format: 0x[r(64)][s(64)][v(2)]
108
- const r = `0x${signature.slice(2, 66)}` as `0x${string}`;
109
- const s = `0x${signature.slice(66, 130)}` as `0x${string}`;
110
- const v = parseInt(signature.slice(130, 132), 16);
111
-
112
- // Convert v to yParity (0 or 1)
113
- // v can be 27/28 (legacy) or 0/1 (EIP-155)
114
- const yParity = v >= 27 ? v - 27 : v;
115
-
116
- return {
51
+ // Don't memoize the callback - create it fresh each time to ensure we have the latest wallets
52
+ const signAuthorization = async (
53
+ unsignedAuth: AuthorizationRequest<number>,
54
+ ): Promise<Authorization<number, true>> => {
55
+ console.log("[RN Adapter] signAuthorization called with:", unsignedAuth);
56
+ console.log("[RN Adapter] Current wallets:", wallets);
57
+
58
+ const wallet = wallets?.[0];
59
+ if (!wallet) {
60
+ throw new Error(
61
+ "Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.",
62
+ );
63
+ }
64
+
65
+ console.log("[RN Adapter] Using wallet:", wallet.address);
66
+
67
+ const provider = await wallet.getProvider?.();
68
+ if (!provider) {
69
+ throw new Error(
70
+ "Provider not available on this wallet. Ensure you're using the embedded Ethereum wallet.",
71
+ );
72
+ }
73
+
74
+ // Extract the implementation address (handle both 'address' and 'contractAddress' fields)
75
+ const implementationAddress =
76
+ unsignedAuth.address ?? unsignedAuth.contractAddress;
77
+
78
+ if (!implementationAddress) {
79
+ throw new Error(
80
+ "Implementation address is required for EIP-7702 authorization",
81
+ );
82
+ }
83
+
84
+ console.log(
85
+ "[RN Adapter] Signing 7702 auth for address:",
86
+ implementationAddress,
87
+ );
88
+
89
+ // EIP-7702 Authorization structure
90
+ const authorization = {
91
+ domain: {
92
+ name: "EIP-7702",
93
+ version: "1",
94
+ chainId: unsignedAuth.chainId,
95
+ },
96
+ types: {
97
+ Authorization: [
98
+ { name: "chainId", type: "uint256" },
99
+ { name: "address", type: "address" },
100
+ { name: "nonce", type: "uint256" },
101
+ ],
102
+ },
103
+ primaryType: "Authorization" as const,
104
+ message: {
117
105
  chainId: unsignedAuth.chainId,
118
106
  address: implementationAddress,
119
107
  nonce: unsignedAuth.nonce,
120
- r,
121
- s,
122
- yParity,
123
- };
124
- },
125
- [wallets],
126
- );
108
+ },
109
+ };
110
+
111
+ const signature = (await provider.request({
112
+ method: "eth_signTypedData_v4",
113
+ params: [wallet.address, JSON.stringify(authorization)],
114
+ })) as `0x${string}`;
115
+
116
+ console.log("[RN Adapter] Received signature:", signature);
117
+
118
+ // Parse the signature into r, s, v components
119
+ // Signature format: 0x[r(64)][s(64)][v(2)]
120
+ const r = `0x${signature.slice(2, 66)}` as `0x${string}`;
121
+ const s = `0x${signature.slice(66, 130)}` as `0x${string}`;
122
+ const v = parseInt(signature.slice(130, 132), 16);
123
+
124
+ // Convert v to yParity (0 or 1)
125
+ // v can be 27/28 (legacy) or 0/1 (EIP-155)
126
+ const yParity = v >= 27 ? v - 27 : v;
127
+
128
+ const result = {
129
+ chainId: unsignedAuth.chainId,
130
+ address: implementationAddress,
131
+ nonce: unsignedAuth.nonce,
132
+ r,
133
+ s,
134
+ yParity,
135
+ };
136
+
137
+ console.log("[RN Adapter] Returning authorization:", result);
138
+ return result;
139
+ };
140
+
141
+ return signAuthorization;
127
142
  },
128
143
  };
129
144
 
@@ -134,16 +149,42 @@ export const reactNativeAdapter: PrivyAdapter = {
134
149
  * @returns {EmbeddedWallet} The adapted wallet following the common interface
135
150
  */
136
151
  function adaptExpoWallet(wallet: ExpoEmbeddedWallet): EmbeddedWallet {
152
+ // Use closure to maintain up-to-date chain ID across chain switches
153
+ let cachedChainId = wallet.chainId || "1";
154
+
137
155
  return {
138
156
  address: wallet.address as `0x${string}`,
139
- chainId: wallet.chainId || "1",
157
+ get chainId() {
158
+ return cachedChainId;
159
+ },
140
160
  getEthereumProvider: async () => {
141
161
  if (!wallet.getProvider) {
142
162
  throw new Error(
143
163
  "getProvider is not available on this wallet. Ensure you're using the embedded Ethereum wallet.",
144
164
  );
145
165
  }
146
- return await wallet.getProvider();
166
+ const provider = await wallet.getProvider();
167
+
168
+ // Always fetch current chain ID when provider is accessed
169
+ // This ensures we have the latest chain after wallet_switchEthereumChain calls
170
+ try {
171
+ const currentChainId = (await provider.request({
172
+ method: "eth_chainId",
173
+ params: [],
174
+ })) as string;
175
+
176
+ // Convert hex to decimal string format (e.g., "0x1" -> "1")
177
+ cachedChainId = parseInt(currentChainId, 16).toString();
178
+ console.log("[RN Adapter] Updated chain ID to:", cachedChainId);
179
+ } catch (err) {
180
+ console.warn(
181
+ "[Privy Integration] Failed to fetch current chain ID:",
182
+ err,
183
+ );
184
+ // Fall back to cached value if fetch fails
185
+ }
186
+
187
+ return provider;
147
188
  },
148
189
  };
149
190
  }
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "4.73.1-alpha.4";
3
+ export const VERSION = "4.73.1-alpha.6";