@account-kit/privy-integration 4.75.5-alpha.0 → 4.76.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.
- package/README.md +165 -6
- package/dist/esm/adapters/react-native.js +4 -4
- package/dist/esm/adapters/react-native.js.map +1 -1
- package/dist/esm/adapters/web.js +3 -2
- package/dist/esm/adapters/web.js.map +1 -1
- package/dist/esm/hooks/useAlchemyClient.js +2 -2
- package/dist/esm/hooks/useAlchemyClient.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/adapters/react-native.d.ts.map +1 -1
- package/dist/types/adapters/web.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/adapters/react-native.ts +16 -8
- package/src/adapters/web.ts +11 -5
- package/src/hooks/useAlchemyClient.ts +2 -2
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @account-kit/privy-integration
|
|
2
2
|
|
|
3
|
-
Add gas sponsorship and smart wallet features to your Privy app in under 5 minutes.
|
|
3
|
+
Add gas sponsorship and smart wallet features to your Privy app in under 5 minutes. Works with **React Web** and **React Native (Expo)**.
|
|
4
4
|
|
|
5
5
|
## What This Package Does
|
|
6
6
|
|
|
@@ -10,7 +10,8 @@ If you're already using [Privy](https://privy.io) for authentication, this packa
|
|
|
10
10
|
- **⛽ Gas Sponsorship** - Pay gas fees for your users via Alchemy Gas Manager (EVM & Solana)
|
|
11
11
|
- **💱 Token Swaps** - Execute swaps through Alchemy's swap infrastructure
|
|
12
12
|
- **🚀 Batched Transactions** - Send multiple operations in a single transaction using `sendTransaction([...])`
|
|
13
|
-
- **☀️ Solana Support** - Send sponsored Solana transactions with Privy's embedded Solana wallets
|
|
13
|
+
- **☀️ Solana Support** - Send sponsored Solana transactions with Privy's embedded Solana wallets (Web only)
|
|
14
|
+
- **📱 React Native Support** - Full EVM support for React Native apps using `@privy-io/expo`
|
|
14
15
|
|
|
15
16
|
All while keeping Privy as your authentication provider. No need to change your auth flow or migrate user accounts.
|
|
16
17
|
|
|
@@ -24,6 +25,8 @@ All while keeping Privy as your authentication provider. No need to change your
|
|
|
24
25
|
|
|
25
26
|
## Installation
|
|
26
27
|
|
|
28
|
+
### React Web
|
|
29
|
+
|
|
27
30
|
```bash
|
|
28
31
|
npm install @account-kit/privy-integration
|
|
29
32
|
# or
|
|
@@ -32,7 +35,17 @@ yarn add @account-kit/privy-integration
|
|
|
32
35
|
pnpm add @account-kit/privy-integration
|
|
33
36
|
```
|
|
34
37
|
|
|
35
|
-
###
|
|
38
|
+
### React Native (Expo)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install @account-kit/privy-integration @privy-io/expo
|
|
42
|
+
# or
|
|
43
|
+
yarn add @account-kit/privy-integration @privy-io/expo
|
|
44
|
+
# or
|
|
45
|
+
pnpm add @account-kit/privy-integration @privy-io/expo
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Optional: Solana Support (Web Only)
|
|
36
49
|
|
|
37
50
|
To use Solana features (like `useAlchemySolanaTransaction`), you'll need to install the Solana Web3.js library:
|
|
38
51
|
|
|
@@ -50,10 +63,15 @@ Then import from the `/solana` export:
|
|
|
50
63
|
import { useAlchemySolanaTransaction } from "@account-kit/privy-integration/solana";
|
|
51
64
|
```
|
|
52
65
|
|
|
53
|
-
> **Note:** The Solana functionality is completely optional. If you only need EVM features, you don't need to install `@solana/web3.js`.
|
|
66
|
+
> **Note:** The Solana functionality is completely optional and currently only available for React web. If you only need EVM features, you don't need to install `@solana/web3.js`.
|
|
54
67
|
|
|
55
68
|
## Quick Start
|
|
56
69
|
|
|
70
|
+
Choose your platform:
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary><strong>React Web</strong></summary>
|
|
74
|
+
|
|
57
75
|
### 1. Wrap Your App with Both Providers
|
|
58
76
|
|
|
59
77
|
**Important:** `AlchemyProvider` must be nested **inside** `PrivyProvider` to access authentication state.
|
|
@@ -98,7 +116,7 @@ function SendButton() {
|
|
|
98
116
|
const result = await sendTransaction({
|
|
99
117
|
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
100
118
|
data: "0x...",
|
|
101
|
-
value: "
|
|
119
|
+
value: "0xde0b6b3a7640000", // 1 ETH in hex (also accepts decimal string or bigint)
|
|
102
120
|
});
|
|
103
121
|
|
|
104
122
|
console.log("Transaction hash:", result.txnHash);
|
|
@@ -111,7 +129,7 @@ function SendButton() {
|
|
|
111
129
|
try {
|
|
112
130
|
// Batch transactions
|
|
113
131
|
const result = await sendTransaction([
|
|
114
|
-
{ to: "0x...", data: "0x...", value: "
|
|
132
|
+
{ to: "0x...", data: "0x...", value: "0xde0b6b3a7640000" }, // 1 ETH
|
|
115
133
|
{ to: "0x...", data: "0x..." },
|
|
116
134
|
{ to: "0x...", data: "0x..." },
|
|
117
135
|
]);
|
|
@@ -249,6 +267,146 @@ function SolanaSendButton() {
|
|
|
249
267
|
}
|
|
250
268
|
```
|
|
251
269
|
|
|
270
|
+
</details>
|
|
271
|
+
|
|
272
|
+
<details>
|
|
273
|
+
<summary><strong>React Native (Expo)</strong></summary>
|
|
274
|
+
|
|
275
|
+
### 1. Wrap Your App with Both Providers
|
|
276
|
+
|
|
277
|
+
**Important:** Use `@privy-io/expo` and import from `/react-native` for React Native apps.
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { PrivyProvider } from "@privy-io/expo";
|
|
281
|
+
import { AlchemyProvider } from "@account-kit/privy-integration/react-native";
|
|
282
|
+
|
|
283
|
+
function App() {
|
|
284
|
+
return (
|
|
285
|
+
<PrivyProvider appId="your-privy-app-id" clientId="your-privy-client-id">
|
|
286
|
+
<AlchemyProvider
|
|
287
|
+
apiKey="your-alchemy-api-key"
|
|
288
|
+
policyId="your-gas-policy-id" // optional, for gas sponsorship
|
|
289
|
+
>
|
|
290
|
+
<YourApp />
|
|
291
|
+
</AlchemyProvider>
|
|
292
|
+
</PrivyProvider>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### 2. Send Gasless Transactions
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
import { useAlchemySendTransaction } from "@account-kit/privy-integration/react-native";
|
|
301
|
+
import { Button } from "react-native";
|
|
302
|
+
|
|
303
|
+
function SendButton() {
|
|
304
|
+
const { sendTransaction, isLoading, error, data } =
|
|
305
|
+
useAlchemySendTransaction();
|
|
306
|
+
|
|
307
|
+
const handleSend = async () => {
|
|
308
|
+
try {
|
|
309
|
+
// Single transaction
|
|
310
|
+
const result = await sendTransaction({
|
|
311
|
+
to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
|
|
312
|
+
data: "0x...",
|
|
313
|
+
value: "0xde0b6b3a7640000", // 1 ETH in hex (also accepts decimal string or bigint)
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
console.log("Transaction hash:", result.txnHash);
|
|
317
|
+
} catch (err) {
|
|
318
|
+
console.error("Transaction failed:", err);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
const handleBatch = async () => {
|
|
323
|
+
try {
|
|
324
|
+
// Batch transactions
|
|
325
|
+
const result = await sendTransaction([
|
|
326
|
+
{ to: "0x...", data: "0x...", value: "0xde0b6b3a7640000" }, // 1 ETH
|
|
327
|
+
{ to: "0x...", data: "0x..." },
|
|
328
|
+
{ to: "0x...", data: "0x..." },
|
|
329
|
+
]);
|
|
330
|
+
|
|
331
|
+
console.log("Batch transaction hash:", result.txnHash);
|
|
332
|
+
} catch (err) {
|
|
333
|
+
console.error("Batch transaction failed:", err);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
return (
|
|
338
|
+
<>
|
|
339
|
+
<Button
|
|
340
|
+
onPress={handleSend}
|
|
341
|
+
disabled={isLoading}
|
|
342
|
+
title={isLoading ? "Sending..." : "Send Transaction"}
|
|
343
|
+
/>
|
|
344
|
+
<Button
|
|
345
|
+
onPress={handleBatch}
|
|
346
|
+
disabled={isLoading}
|
|
347
|
+
title={isLoading ? "Sending..." : "Send Batch"}
|
|
348
|
+
/>
|
|
349
|
+
</>
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### 3. Execute Token Swaps
|
|
355
|
+
|
|
356
|
+
```tsx
|
|
357
|
+
import {
|
|
358
|
+
useAlchemyPrepareSwap,
|
|
359
|
+
useAlchemySubmitSwap,
|
|
360
|
+
} from "@account-kit/privy-integration/react-native";
|
|
361
|
+
import { Button } from "react-native";
|
|
362
|
+
|
|
363
|
+
function SwapButton() {
|
|
364
|
+
const { prepareSwap } = useAlchemyPrepareSwap();
|
|
365
|
+
const { submitSwap, isLoading } = useAlchemySubmitSwap();
|
|
366
|
+
|
|
367
|
+
const handleSwap = async () => {
|
|
368
|
+
try {
|
|
369
|
+
// Prepare swap
|
|
370
|
+
const preparedSwap = await prepareSwap({
|
|
371
|
+
fromToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", // ETH
|
|
372
|
+
toToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
|
|
373
|
+
fromAmount: "0xde0b6b3a7640000", // Swap exactly 1 ETH
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// Execute swap
|
|
377
|
+
const result = await submitSwap(preparedSwap);
|
|
378
|
+
console.log("Swap confirmed:", result.txnHash);
|
|
379
|
+
} catch (err) {
|
|
380
|
+
console.error("Swap failed:", err);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
return (
|
|
385
|
+
<Button
|
|
386
|
+
onPress={handleSwap}
|
|
387
|
+
disabled={isLoading}
|
|
388
|
+
title={isLoading ? "Swapping..." : "Swap Tokens"}
|
|
389
|
+
/>
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Multiple Wallet Support
|
|
395
|
+
|
|
396
|
+
If your users have multiple Privy wallets, specify which one to use:
|
|
397
|
+
|
|
398
|
+
```tsx
|
|
399
|
+
<AlchemyProvider
|
|
400
|
+
apiKey="your-alchemy-api-key"
|
|
401
|
+
policyId="your-gas-policy-id"
|
|
402
|
+
walletAddress="0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
|
|
403
|
+
>
|
|
404
|
+
<YourApp />
|
|
405
|
+
</AlchemyProvider>
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
</details>
|
|
409
|
+
|
|
252
410
|
## Configuration
|
|
253
411
|
|
|
254
412
|
### AlchemyProvider Props
|
|
@@ -263,6 +421,7 @@ function SolanaSendButton() {
|
|
|
263
421
|
| `solanaPolicyId` | `string \| string[]` | No | Gas Manager policy ID(s) for Solana sponsorship |
|
|
264
422
|
| `disableSponsorship` | `boolean` | No | Set to `true` to disable gas sponsorship by default (default: `false`) |
|
|
265
423
|
| `accountAuthMode` | `'eip7702' \| 'owner'` | No | Authorization mode for EVM smart accounts (default: `'eip7702'`) |
|
|
424
|
+
| `walletAddress` | `string` | No | Specific wallet address to use if user has multiple wallets (defaults to first wallet) |
|
|
266
425
|
|
|
267
426
|
\* **Required configuration (pick one):**
|
|
268
427
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { usePrivy, useEmbeddedEthereumWallet, } from "@privy-io/expo";
|
|
3
|
+
import { isAddressEqual, parseSignature } from "viem";
|
|
3
4
|
import { hashAuthorization } from "viem/utils";
|
|
4
|
-
import { parseSignature } from "viem";
|
|
5
5
|
/**
|
|
6
6
|
* React Native (Expo) adapter for @privy-io/expo
|
|
7
7
|
* Implements platform-specific hooks for React Native applications
|
|
@@ -15,7 +15,7 @@ export const reactNativeAdapter = {
|
|
|
15
15
|
}
|
|
16
16
|
// If a preferred address is specified, find that wallet
|
|
17
17
|
const wallet = preferredAddress
|
|
18
|
-
? wallets.find((w) => w.address
|
|
18
|
+
? wallets.find((w) => isAddressEqual(w.address, preferredAddress))
|
|
19
19
|
: wallets[0];
|
|
20
20
|
if (!wallet) {
|
|
21
21
|
throw new Error(preferredAddress
|
|
@@ -37,7 +37,7 @@ export const reactNativeAdapter = {
|
|
|
37
37
|
}
|
|
38
38
|
// If a preferred address is specified, find that wallet
|
|
39
39
|
if (preferredAddress) {
|
|
40
|
-
const wallet = wallets.find((w) => w.address
|
|
40
|
+
const wallet = wallets.find((w) => isAddressEqual(w.address, preferredAddress));
|
|
41
41
|
return wallet?.address;
|
|
42
42
|
}
|
|
43
43
|
// Otherwise return the first wallet
|
|
@@ -51,7 +51,7 @@ export const reactNativeAdapter = {
|
|
|
51
51
|
}
|
|
52
52
|
// If a preferred address is specified, find that wallet
|
|
53
53
|
const wallet = preferredAddress
|
|
54
|
-
? wallets.find((w) => w.address
|
|
54
|
+
? wallets.find((w) => isAddressEqual(w.address, preferredAddress))
|
|
55
55
|
: wallets[0];
|
|
56
56
|
if (!wallet) {
|
|
57
57
|
throw new Error(preferredAddress
|
|
@@ -1 +1 @@
|
|
|
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 { hashAuthorization } from \"viem/utils\";\nimport { parseSignature } 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(preferredAddress?: string) {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n if (!wallets || wallets.length === 0) {\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 // If a preferred address is specified, find that wallet\n const wallet = preferredAddress\n ? wallets.find(\n (w) => w.address.toLowerCase() === preferredAddress.toLowerCase(),\n )\n : wallets[0];\n\n if (!wallet) {\n throw new Error(\n preferredAddress\n ? `Privy embedded wallet with address ${preferredAddress} not found.`\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, preferredAddress]);\n\n return getEmbeddedWallet;\n },\n\n usePrivyAuth(): PrivyAuthState {\n const { user } = usePrivy();\n return { authenticated: !!user, user };\n },\n\n useWalletAddress(preferredAddress?: string): string | undefined {\n const { wallets } = useEmbeddedEthereumWallet();\n\n if (!wallets || wallets.length === 0) {\n return undefined;\n }\n\n // If a preferred address is specified, find that wallet\n if (preferredAddress) {\n const wallet = wallets.find(\n (w) => w.address.toLowerCase() === preferredAddress.toLowerCase(),\n );\n return wallet?.address;\n }\n\n // Otherwise return the first wallet\n return wallets[0]?.address;\n },\n\n useAuthorizationSigner(preferredAddress?: string) {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const signAuthorization = useCallback(\n async (\n unsignedAuth: AuthorizationRequest<number>,\n ): Promise<Authorization<number, true>> => {\n if (!wallets || wallets.length === 0) {\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 // If a preferred address is specified, find that wallet\n const wallet = preferredAddress\n ? wallets.find(\n (w) => w.address.toLowerCase() === preferredAddress.toLowerCase(),\n )\n : wallets[0];\n\n if (!wallet) {\n throw new Error(\n preferredAddress\n ? `Privy embedded wallet with address ${preferredAddress} not found.`\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 // Create the authorization structure (matches Privy's implementation)\n const authorization = {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n };\n\n // Hash the authorization using viem (same as Privy does)\n const authorizationHash = hashAuthorization(authorization);\n\n // Sign the hash directly with secp256k1_sign (same as Privy)\n const signature = (await provider.request({\n method: \"secp256k1_sign\",\n params: [authorizationHash],\n })) as `0x${string}`;\n\n // Parse the signature using viem (same as Privy)\n const parsedSignature = parseSignature(signature);\n\n return {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n ...parsedSignature,\n };\n },\n [wallets, preferredAddress],\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 } catch {\n // Fall back to cached value if fetch fails\n // Chain ID fetch errors are non-critical and can happen during initialization\n }\n\n return provider;\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 { isAddressEqual, parseSignature, type Authorization } from \"viem\";\nimport { hashAuthorization } from \"viem/utils\";\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(preferredAddress?: string) {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n if (!wallets || wallets.length === 0) {\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 // If a preferred address is specified, find that wallet\n const wallet = preferredAddress\n ? wallets.find((w) =>\n isAddressEqual(\n w.address as `0x${string}`,\n preferredAddress as `0x${string}`,\n ),\n )\n : wallets[0];\n\n if (!wallet) {\n throw new Error(\n preferredAddress\n ? `Privy embedded wallet with address ${preferredAddress} not found.`\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, preferredAddress]);\n\n return getEmbeddedWallet;\n },\n\n usePrivyAuth(): PrivyAuthState {\n const { user } = usePrivy();\n return { authenticated: !!user, user };\n },\n\n useWalletAddress(preferredAddress?: string): string | undefined {\n const { wallets } = useEmbeddedEthereumWallet();\n\n if (!wallets || wallets.length === 0) {\n return undefined;\n }\n\n // If a preferred address is specified, find that wallet\n if (preferredAddress) {\n const wallet = wallets.find((w) =>\n isAddressEqual(\n w.address as `0x${string}`,\n preferredAddress as `0x${string}`,\n ),\n );\n return wallet?.address;\n }\n\n // Otherwise return the first wallet\n return wallets[0]?.address;\n },\n\n useAuthorizationSigner(preferredAddress?: string) {\n const { wallets } = useEmbeddedEthereumWallet();\n\n const signAuthorization = useCallback(\n async (\n unsignedAuth: AuthorizationRequest<number>,\n ): Promise<Authorization<number, true>> => {\n if (!wallets || wallets.length === 0) {\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 // If a preferred address is specified, find that wallet\n const wallet = preferredAddress\n ? wallets.find((w) =>\n isAddressEqual(\n w.address as `0x${string}`,\n preferredAddress as `0x${string}`,\n ),\n )\n : wallets[0];\n\n if (!wallet) {\n throw new Error(\n preferredAddress\n ? `Privy embedded wallet with address ${preferredAddress} not found.`\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 // Create the authorization structure (matches Privy's implementation)\n const authorization = {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n };\n\n // Hash the authorization using viem (same as Privy does)\n const authorizationHash = hashAuthorization(authorization);\n\n // Sign the hash directly with secp256k1_sign (same as Privy)\n const signature = (await provider.request({\n method: \"secp256k1_sign\",\n params: [authorizationHash],\n })) as `0x${string}`;\n\n // Parse the signature using viem (same as Privy)\n const parsedSignature = parseSignature(signature);\n\n return {\n chainId: unsignedAuth.chainId,\n address: implementationAddress,\n nonce: unsignedAuth.nonce,\n ...parsedSignature,\n };\n },\n [wallets, preferredAddress],\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 } catch {\n // Fall back to cached value if fetch fails\n // Chain ID fetch errors are non-critical and can happen during initialization\n }\n\n return provider;\n },\n };\n}\n"]}
|
package/dist/esm/adapters/web.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import { useWallets, usePrivy, useSign7702Authorization, } from "@privy-io/react-auth";
|
|
3
|
+
import { isAddressEqual } from "viem";
|
|
3
4
|
/**
|
|
4
5
|
* Web adapter for @privy-io/react-auth
|
|
5
6
|
* Implements platform-specific hooks for React web applications
|
|
@@ -14,7 +15,7 @@ export const webAdapter = {
|
|
|
14
15
|
}
|
|
15
16
|
// If a preferred address is specified, find that wallet
|
|
16
17
|
const embedded = preferredAddress
|
|
17
|
-
? privyWallets.find((w) => w.address
|
|
18
|
+
? privyWallets.find((w) => isAddressEqual(w.address, preferredAddress))
|
|
18
19
|
: privyWallets[0];
|
|
19
20
|
if (!embedded) {
|
|
20
21
|
throw new Error(preferredAddress
|
|
@@ -34,7 +35,7 @@ export const webAdapter = {
|
|
|
34
35
|
const privyWallets = wallets.filter((w) => w.walletClientType === "privy");
|
|
35
36
|
// If a preferred address is specified, find that wallet
|
|
36
37
|
if (preferredAddress) {
|
|
37
|
-
const wallet = privyWallets.find((w) => w.address
|
|
38
|
+
const wallet = privyWallets.find((w) => isAddressEqual(w.address, preferredAddress));
|
|
38
39
|
return wallet?.address;
|
|
39
40
|
}
|
|
40
41
|
// Otherwise return the first embedded wallet
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../../src/adapters/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EACL,UAAU,EACV,QAAQ,EACR,wBAAwB,GAEzB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../../src/adapters/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback } from \"react\";\nimport {\n useWallets,\n usePrivy,\n useSign7702Authorization,\n type ConnectedWallet as PrivyWallet,\n} from \"@privy-io/react-auth\";\nimport { isAddressEqual, type Authorization } from \"viem\";\nimport type { AuthorizationRequest } from \"@aa-sdk/core\";\nimport type { PrivyAdapter, EmbeddedWallet, PrivyAuthState } from \"./types.js\";\n\n/**\n * Web adapter for @privy-io/react-auth\n * Implements platform-specific hooks for React web applications\n */\nexport const webAdapter: PrivyAdapter = {\n useEmbeddedWallet(preferredAddress?: string) {\n const { wallets } = useWallets();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n const privyWallets = wallets.filter(\n (w) => w.walletClientType === \"privy\",\n );\n\n if (privyWallets.length === 0) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated.\",\n );\n }\n\n // If a preferred address is specified, find that wallet\n const embedded = preferredAddress\n ? privyWallets.find((w) =>\n isAddressEqual(\n w.address as `0x${string}`,\n preferredAddress as `0x${string}`,\n ),\n )\n : privyWallets[0];\n\n if (!embedded) {\n throw new Error(\n preferredAddress\n ? `Privy embedded wallet with address ${preferredAddress} not found.`\n : \"Privy embedded wallet not found. Please ensure the user is authenticated.\",\n );\n }\n\n return adaptWebWallet(embedded);\n }, [wallets, preferredAddress]);\n\n return getEmbeddedWallet;\n },\n\n usePrivyAuth(): PrivyAuthState {\n const { user } = usePrivy();\n return { authenticated: !!user, user };\n },\n\n useWalletAddress(preferredAddress?: string): string | undefined {\n const { wallets } = useWallets();\n const privyWallets = wallets.filter((w) => w.walletClientType === \"privy\");\n\n // If a preferred address is specified, find that wallet\n if (preferredAddress) {\n const wallet = privyWallets.find((w) =>\n isAddressEqual(\n w.address as `0x${string}`,\n preferredAddress as `0x${string}`,\n ),\n );\n return wallet?.address;\n }\n\n // Otherwise return the first embedded wallet\n return privyWallets[0]?.address;\n },\n\n useAuthorizationSigner(_preferredAddress?: string) {\n const { signAuthorization } = useSign7702Authorization();\n\n return useCallback(\n async (\n unsignedAuth: AuthorizationRequest<number>,\n ): Promise<Authorization<number, true>> => {\n const signature = await signAuthorization({\n ...unsignedAuth,\n contractAddress: unsignedAuth.address ?? unsignedAuth.contractAddress,\n });\n\n return {\n ...unsignedAuth,\n ...signature,\n };\n },\n [signAuthorization],\n );\n },\n};\n\n/**\n * Adapts a Privy web wallet to the common EmbeddedWallet interface\n *\n * @param {PrivyWallet} wallet - The Privy web wallet to adapt\n * @returns {EmbeddedWallet} The adapted wallet following the common interface\n */\nfunction adaptWebWallet(wallet: PrivyWallet): EmbeddedWallet {\n return {\n address: wallet.address as `0x${string}`,\n chainId: wallet.chainId || \"1\",\n getEthereumProvider: () => wallet.getEthereumProvider(),\n };\n}\n"]}
|
|
@@ -45,7 +45,7 @@ export function useAlchemyClient() {
|
|
|
45
45
|
}
|
|
46
46
|
const chain = getChain(parsedChainId);
|
|
47
47
|
// Generate a cache key based on configuration and wallet address
|
|
48
|
-
// IMPORTANT: Include whether authorization
|
|
48
|
+
// IMPORTANT: Include whether authorization signing is supported in cache key
|
|
49
49
|
const currentCacheKey = JSON.stringify({
|
|
50
50
|
address: embeddedWallet.address,
|
|
51
51
|
chainId: chain.id,
|
|
@@ -54,7 +54,7 @@ export function useAlchemyClient() {
|
|
|
54
54
|
rpcUrl: config.rpcUrl,
|
|
55
55
|
policyId: config.policyId,
|
|
56
56
|
accountAuthMode: config.accountAuthMode,
|
|
57
|
-
|
|
57
|
+
supportsSignAuthorization: !!signAuthorizationFn,
|
|
58
58
|
});
|
|
59
59
|
// Return cached client and account if configuration hasn't changed
|
|
60
60
|
if (cache.client && cache.account && cache.cacheKey === currentCacheKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAlchemyClient.js","sourceRoot":"","sources":["../../../src/hooks/useAlchemyClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,GAEvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAgB,MAAM,MAAM,CAAC;AAChE,OAAO,EACL,uBAAuB,GAExB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAOpE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,mBAAmB,GACvB,OAAO,CAAC,sBAAsB,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;IACjE,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,MAAM,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;IAE9C,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,IAAkC,EAAE;QACrE,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;QAE3C,8DAA8D;QAC9D,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,mBAAmB,EAAE,CAAC;QAE5D,wEAAwE;QACxE,uCAAuC;QACvC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QAEtD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC7C,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC,CAAC,UAAU,CAAC;QACf,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,2DAA2D,UAAU,EAAE,CACxE,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;QAEtC,iEAAiE;QACjE,
|
|
1
|
+
{"version":3,"file":"useAlchemyClient.js","sourceRoot":"","sources":["../../../src/hooks/useAlchemyClient.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback } from \"react\";\nimport {\n WalletClientSigner,\n ConnectionConfigSchema,\n type SmartContractAccount,\n} from \"@aa-sdk/core\";\nimport { createWalletClient, custom, type Address } from \"viem\";\nimport {\n createSmartWalletClient,\n type SmartWalletClient,\n} from \"@account-kit/wallet-client\";\nimport { alchemy } from \"@account-kit/infra\";\nimport {\n useAlchemyConfig,\n useClientCache,\n useAdapter,\n} from \"../context/AlchemyContext.js\";\nimport { getChain } from \"../util/getChain.js\";\nimport { useEmbeddedWallet } from \"./internal/useEmbeddedWallet.js\";\n\nexport type AlchemyClientResult = {\n client: SmartWalletClient;\n account: SmartContractAccount;\n};\n\n/**\n * Hook to get and memoize a SmartWalletClient instance with its associated account\n * The client and account are cached in the AlchemyProvider context (React tree scoped)\n * Automatically clears cache on logout via the provider\n *\n * @returns {{ getClient: () => Promise<AlchemyClientResult> }} Object containing the smart wallet client and account getter\n *\n * @example\n * ```tsx\n * const { getClient } = useAlchemyClient();\n * const { client, account } = await getClient();\n * ```\n */\nexport function useAlchemyClient() {\n const adapter = useAdapter();\n const config = useAlchemyConfig();\n const signAuthorizationFn =\n adapter.useAuthorizationSigner?.(config.walletAddress) || null;\n const cache = useClientCache();\n const getEmbeddedWallet = useEmbeddedWallet();\n\n const getClient = useCallback(async (): Promise<AlchemyClientResult> => {\n const embeddedWallet = getEmbeddedWallet();\n\n // IMPORTANT: Get provider FIRST to ensure chain ID is updated\n // The provider fetch triggers chain ID update in the adapter\n const provider = await embeddedWallet.getEthereumProvider();\n\n // NOW get the chain from the SAME wallet instance with updated chain ID\n // Handle CAIP-2 format like \"eip155:1\"\n const chainIdStr = embeddedWallet.chainId?.toString();\n\n if (!chainIdStr) {\n throw new Error(\n \"Embedded wallet chainId is not set. Please ensure the wallet is connected to a network.\",\n );\n }\n const numericChainId = chainIdStr.includes(\":\")\n ? chainIdStr.split(\":\")[1]\n : chainIdStr;\n const parsedChainId = Number(numericChainId);\n if (isNaN(parsedChainId)) {\n throw new Error(\n `Failed to parse chainId from embedded wallet. Received: ${chainIdStr}`,\n );\n }\n\n const chain = getChain(parsedChainId);\n\n // Generate a cache key based on configuration and wallet address\n // IMPORTANT: Include whether authorization signing is supported in cache key\n const currentCacheKey = JSON.stringify({\n address: embeddedWallet.address,\n chainId: chain.id,\n apiKey: config.apiKey,\n jwt: config.jwt,\n rpcUrl: config.rpcUrl,\n policyId: config.policyId,\n accountAuthMode: config.accountAuthMode,\n supportsSignAuthorization: !!signAuthorizationFn,\n });\n\n // Return cached client and account if configuration hasn't changed\n if (cache.client && cache.account && cache.cacheKey === currentCacheKey) {\n return { client: cache.client, account: cache.account };\n }\n\n // Create base signer from Privy wallet\n const baseSigner = new WalletClientSigner(\n createWalletClient({\n account: embeddedWallet.address as Address,\n chain,\n transport: custom(provider),\n }),\n \"privy\",\n );\n\n // Optionally extend signer with EIP-7702 authorization support\n const signer =\n config.accountAuthMode === \"eip7702\" && !!signAuthorizationFn\n ? {\n ...baseSigner,\n signAuthorization: signAuthorizationFn,\n }\n : baseSigner;\n\n // Determine transport configuration using schema validation\n // This properly handles combinations like rpcUrl + jwt together\n const transportConfig = ConnectionConfigSchema.parse({\n rpcUrl: config.rpcUrl,\n apiKey: config.apiKey,\n jwt: config.jwt,\n });\n\n const transport = alchemy(transportConfig);\n\n transport.updateHeaders({\n \"X-Alchemy-Client-Breadcrumb\": \"privyIntegrationSdk\",\n });\n\n // Create and cache the smart wallet client in provider context\n cache.client = createSmartWalletClient({\n chain,\n transport,\n signer,\n policyIds: config.policyId\n ? Array.isArray(config.policyId)\n ? config.policyId\n : [config.policyId]\n : undefined,\n });\n\n // Request the account to properly initialize the smart wallet\n // Pass a creation hint based on auth mode to ensure different accounts for different modes\n // This prevents 7702 accounts from being reused in owner mode and vice versa\n cache.account =\n config.accountAuthMode === \"eip7702\"\n ? await cache.client.requestAccount({\n creationHint: { accountType: \"7702\" },\n })\n : await cache.client.requestAccount({\n creationHint: { accountType: \"sma-b\" },\n });\n\n // Store the cache key\n cache.cacheKey = currentCacheKey;\n\n return { client: cache.client, account: cache.account };\n }, [\n getEmbeddedWallet,\n signAuthorizationFn,\n config.apiKey,\n config.jwt,\n config.rpcUrl,\n config.policyId,\n cache,\n config.accountAuthMode,\n ]);\n\n return { getClient };\n}\n"]}
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.
|
|
1
|
+
export declare const VERSION = "4.76.0";
|
package/dist/esm/version.js
CHANGED
package/dist/esm/version.js.map
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.76.0\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../../src/adapters/react-native.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,YAAY,CAAC;AAY/E;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,YA6IhC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../src/adapters/web.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,YAAY,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../../src/adapters/web.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,YAAY,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,YAmFxB,CAAC"}
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "4.
|
|
1
|
+
export declare const VERSION = "4.76.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@account-kit/privy-integration",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.76.0",
|
|
4
4
|
"description": "Use Alchemy gas sponsorship, swaps and more with Privy",
|
|
5
5
|
"author": "Alchemy",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"typescript-template": "*"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@account-kit/infra": "^4.
|
|
68
|
-
"@account-kit/wallet-client": "^4.
|
|
67
|
+
"@account-kit/infra": "^4.76.0",
|
|
68
|
+
"@account-kit/wallet-client": "^4.76.0"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@privy-io/expo": "^0.58.1",
|
|
@@ -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": "
|
|
98
|
+
"gitHead": "664b587d4ab2c3be0ff244a8a25b172a6d496a78"
|
|
99
99
|
}
|
|
@@ -4,9 +4,8 @@ import {
|
|
|
4
4
|
useEmbeddedEthereumWallet,
|
|
5
5
|
type PrivyEmbeddedWalletProvider,
|
|
6
6
|
} from "@privy-io/expo";
|
|
7
|
-
import type
|
|
7
|
+
import { isAddressEqual, parseSignature, type Authorization } from "viem";
|
|
8
8
|
import { hashAuthorization } from "viem/utils";
|
|
9
|
-
import { parseSignature } from "viem";
|
|
10
9
|
import type { AuthorizationRequest } from "@aa-sdk/core";
|
|
11
10
|
import type { PrivyAdapter, EmbeddedWallet, PrivyAuthState } from "./types.js";
|
|
12
11
|
|
|
@@ -37,8 +36,11 @@ export const reactNativeAdapter: PrivyAdapter = {
|
|
|
37
36
|
|
|
38
37
|
// If a preferred address is specified, find that wallet
|
|
39
38
|
const wallet = preferredAddress
|
|
40
|
-
? wallets.find(
|
|
41
|
-
(
|
|
39
|
+
? wallets.find((w) =>
|
|
40
|
+
isAddressEqual(
|
|
41
|
+
w.address as `0x${string}`,
|
|
42
|
+
preferredAddress as `0x${string}`,
|
|
43
|
+
),
|
|
42
44
|
)
|
|
43
45
|
: wallets[0];
|
|
44
46
|
|
|
@@ -70,8 +72,11 @@ export const reactNativeAdapter: PrivyAdapter = {
|
|
|
70
72
|
|
|
71
73
|
// If a preferred address is specified, find that wallet
|
|
72
74
|
if (preferredAddress) {
|
|
73
|
-
const wallet = wallets.find(
|
|
74
|
-
(
|
|
75
|
+
const wallet = wallets.find((w) =>
|
|
76
|
+
isAddressEqual(
|
|
77
|
+
w.address as `0x${string}`,
|
|
78
|
+
preferredAddress as `0x${string}`,
|
|
79
|
+
),
|
|
75
80
|
);
|
|
76
81
|
return wallet?.address;
|
|
77
82
|
}
|
|
@@ -95,8 +100,11 @@ export const reactNativeAdapter: PrivyAdapter = {
|
|
|
95
100
|
|
|
96
101
|
// If a preferred address is specified, find that wallet
|
|
97
102
|
const wallet = preferredAddress
|
|
98
|
-
? wallets.find(
|
|
99
|
-
(
|
|
103
|
+
? wallets.find((w) =>
|
|
104
|
+
isAddressEqual(
|
|
105
|
+
w.address as `0x${string}`,
|
|
106
|
+
preferredAddress as `0x${string}`,
|
|
107
|
+
),
|
|
100
108
|
)
|
|
101
109
|
: wallets[0];
|
|
102
110
|
|
package/src/adapters/web.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
useSign7702Authorization,
|
|
6
6
|
type ConnectedWallet as PrivyWallet,
|
|
7
7
|
} from "@privy-io/react-auth";
|
|
8
|
-
import type
|
|
8
|
+
import { isAddressEqual, type Authorization } from "viem";
|
|
9
9
|
import type { AuthorizationRequest } from "@aa-sdk/core";
|
|
10
10
|
import type { PrivyAdapter, EmbeddedWallet, PrivyAuthState } from "./types.js";
|
|
11
11
|
|
|
@@ -30,8 +30,11 @@ export const webAdapter: PrivyAdapter = {
|
|
|
30
30
|
|
|
31
31
|
// If a preferred address is specified, find that wallet
|
|
32
32
|
const embedded = preferredAddress
|
|
33
|
-
? privyWallets.find(
|
|
34
|
-
(
|
|
33
|
+
? privyWallets.find((w) =>
|
|
34
|
+
isAddressEqual(
|
|
35
|
+
w.address as `0x${string}`,
|
|
36
|
+
preferredAddress as `0x${string}`,
|
|
37
|
+
),
|
|
35
38
|
)
|
|
36
39
|
: privyWallets[0];
|
|
37
40
|
|
|
@@ -60,8 +63,11 @@ export const webAdapter: PrivyAdapter = {
|
|
|
60
63
|
|
|
61
64
|
// If a preferred address is specified, find that wallet
|
|
62
65
|
if (preferredAddress) {
|
|
63
|
-
const wallet = privyWallets.find(
|
|
64
|
-
(
|
|
66
|
+
const wallet = privyWallets.find((w) =>
|
|
67
|
+
isAddressEqual(
|
|
68
|
+
w.address as `0x${string}`,
|
|
69
|
+
preferredAddress as `0x${string}`,
|
|
70
|
+
),
|
|
65
71
|
);
|
|
66
72
|
return wallet?.address;
|
|
67
73
|
}
|
|
@@ -73,7 +73,7 @@ export function useAlchemyClient() {
|
|
|
73
73
|
const chain = getChain(parsedChainId);
|
|
74
74
|
|
|
75
75
|
// Generate a cache key based on configuration and wallet address
|
|
76
|
-
// IMPORTANT: Include whether authorization
|
|
76
|
+
// IMPORTANT: Include whether authorization signing is supported in cache key
|
|
77
77
|
const currentCacheKey = JSON.stringify({
|
|
78
78
|
address: embeddedWallet.address,
|
|
79
79
|
chainId: chain.id,
|
|
@@ -82,7 +82,7 @@ export function useAlchemyClient() {
|
|
|
82
82
|
rpcUrl: config.rpcUrl,
|
|
83
83
|
policyId: config.policyId,
|
|
84
84
|
accountAuthMode: config.accountAuthMode,
|
|
85
|
-
|
|
85
|
+
supportsSignAuthorization: !!signAuthorizationFn,
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
// Return cached client and account if configuration hasn't changed
|
package/src/version.ts
CHANGED