@account-kit/privy-integration 4.75.4 → 4.75.5-alpha.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/dist/esm/Provider.d.ts +4 -71
- package/dist/esm/Provider.js +4 -109
- package/dist/esm/Provider.js.map +1 -1
- package/dist/esm/Provider.native.d.ts +6 -0
- package/dist/esm/Provider.native.js +13 -0
- package/dist/esm/Provider.native.js.map +1 -0
- package/dist/esm/adapters/react-native.d.ts +6 -0
- package/dist/esm/adapters/react-native.js +132 -0
- package/dist/esm/adapters/react-native.js.map +1 -0
- package/dist/esm/adapters/types.d.ts +56 -0
- package/dist/esm/adapters/types.js +2 -0
- package/dist/esm/adapters/types.js.map +1 -0
- package/dist/esm/adapters/web.d.ts +6 -0
- package/dist/esm/adapters/web.js +70 -0
- package/dist/esm/adapters/web.js.map +1 -0
- package/dist/esm/adapters/web.native.d.ts +5 -0
- package/dist/esm/adapters/web.native.js +6 -0
- package/dist/esm/adapters/web.native.js.map +1 -0
- package/dist/esm/context/AlchemyContext.d.ts +71 -0
- package/dist/esm/context/AlchemyContext.js +115 -0
- package/dist/esm/context/AlchemyContext.js.map +1 -0
- package/dist/esm/hooks/internal/useEmbeddedWallet.d.ts +3 -4
- package/dist/esm/hooks/internal/useEmbeddedWallet.js +6 -13
- package/dist/esm/hooks/internal/useEmbeddedWallet.js.map +1 -1
- package/dist/esm/hooks/useAlchemyClient.js +17 -24
- package/dist/esm/hooks/useAlchemyClient.js.map +1 -1
- package/dist/esm/hooks/useAlchemySendTransaction.js +1 -1
- package/dist/esm/hooks/useAlchemySendTransaction.js.map +1 -1
- package/dist/esm/hooks/useAlchemySolanaTransaction.js +1 -1
- package/dist/esm/hooks/useAlchemySolanaTransaction.js.map +1 -1
- package/dist/esm/providers/ReactNativeProvider.d.ts +37 -0
- package/dist/esm/providers/ReactNativeProvider.js +41 -0
- package/dist/esm/providers/ReactNativeProvider.js.map +1 -0
- package/dist/esm/providers/WebProvider.d.ts +37 -0
- package/dist/esm/providers/WebProvider.js +41 -0
- package/dist/esm/providers/WebProvider.js.map +1 -0
- package/dist/esm/providers/WebProvider.native.d.ts +5 -0
- package/dist/esm/providers/WebProvider.native.js +9 -0
- package/dist/esm/providers/WebProvider.native.js.map +1 -0
- package/dist/esm/react-native.d.ts +11 -0
- package/dist/esm/react-native.js +13 -0
- package/dist/esm/react-native.js.map +1 -0
- package/dist/esm/types.d.ts +6 -0
- package/dist/esm/types.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/Provider.d.ts +4 -71
- package/dist/types/Provider.d.ts.map +1 -1
- package/dist/types/Provider.native.d.ts +7 -0
- package/dist/types/Provider.native.d.ts.map +1 -0
- package/dist/types/adapters/react-native.d.ts +7 -0
- package/dist/types/adapters/react-native.d.ts.map +1 -0
- package/dist/types/adapters/types.d.ts +57 -0
- package/dist/types/adapters/types.d.ts.map +1 -0
- package/dist/types/adapters/web.d.ts +7 -0
- package/dist/types/adapters/web.d.ts.map +1 -0
- package/dist/types/adapters/web.native.d.ts +6 -0
- package/dist/types/adapters/web.native.d.ts.map +1 -0
- package/dist/types/context/AlchemyContext.d.ts +72 -0
- package/dist/types/context/AlchemyContext.d.ts.map +1 -0
- package/dist/types/hooks/internal/useEmbeddedWallet.d.ts +3 -4
- package/dist/types/hooks/internal/useEmbeddedWallet.d.ts.map +1 -1
- package/dist/types/hooks/useAlchemyClient.d.ts.map +1 -1
- package/dist/types/providers/ReactNativeProvider.d.ts +38 -0
- package/dist/types/providers/ReactNativeProvider.d.ts.map +1 -0
- package/dist/types/providers/WebProvider.d.ts +38 -0
- package/dist/types/providers/WebProvider.d.ts.map +1 -0
- package/dist/types/providers/WebProvider.native.d.ts +6 -0
- package/dist/types/providers/WebProvider.native.d.ts.map +1 -0
- package/dist/types/react-native.d.ts +12 -0
- package/dist/types/react-native.d.ts.map +1 -0
- package/dist/types/types.d.ts +6 -0
- package/dist/types/types.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 +27 -4
- package/src/Provider.native.tsx +18 -0
- package/src/Provider.tsx +6 -0
- package/src/adapters/react-native.ts +202 -0
- package/src/adapters/types.ts +71 -0
- package/src/adapters/web.native.ts +6 -0
- package/src/adapters/web.ts +107 -0
- package/src/context/AlchemyContext.tsx +185 -0
- package/src/hooks/internal/useEmbeddedWallet.ts +6 -20
- package/src/hooks/useAlchemyClient.ts +24 -38
- package/src/hooks/useAlchemySendTransaction.ts +1 -1
- package/src/hooks/useAlchemySolanaTransaction.ts +1 -1
- package/src/providers/ReactNativeProvider.tsx +49 -0
- package/src/providers/WebProvider.native.tsx +11 -0
- package/src/providers/WebProvider.tsx +49 -0
- package/src/react-native.ts +29 -0
- package/src/types.ts +7 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type PropsWithChildren,
|
|
3
|
+
createContext,
|
|
4
|
+
useContext,
|
|
5
|
+
useRef,
|
|
6
|
+
useEffect,
|
|
7
|
+
} from "react";
|
|
8
|
+
import type { SmartWalletClient } from "@account-kit/wallet-client";
|
|
9
|
+
import type { SmartContractAccount } from "@aa-sdk/core";
|
|
10
|
+
import type { AlchemyProviderConfig } from "../types.js";
|
|
11
|
+
import type { PrivyAdapter } from "../adapters/types.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Normalized config with defaults applied
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export type NormalizedAlchemyConfig = AlchemyProviderConfig &
|
|
19
|
+
Required<Pick<AlchemyProviderConfig, "accountAuthMode">>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Context for Alchemy configuration
|
|
23
|
+
*/
|
|
24
|
+
const AlchemyConfigContext = createContext<NormalizedAlchemyConfig | null>(
|
|
25
|
+
null,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Context for the platform adapter
|
|
30
|
+
*/
|
|
31
|
+
const AdapterContext = createContext<PrivyAdapter | null>(null);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Client cache stored in React tree (similar to QueryClient in React Query)
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
interface ClientCache {
|
|
39
|
+
client: SmartWalletClient | null;
|
|
40
|
+
account: SmartContractAccount | null;
|
|
41
|
+
cacheKey: string | null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ClientCacheContext = createContext<ClientCache | null>(null);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Props for AlchemyContextProvider
|
|
48
|
+
*/
|
|
49
|
+
interface AlchemyContextProviderProps extends PropsWithChildren {
|
|
50
|
+
config: AlchemyProviderConfig;
|
|
51
|
+
adapter: PrivyAdapter;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Internal provider component that manages Alchemy context
|
|
56
|
+
* Used by both web and React Native providers
|
|
57
|
+
*
|
|
58
|
+
* @internal
|
|
59
|
+
* @param {AlchemyContextProviderProps} props - Component props
|
|
60
|
+
* @param {React.ReactNode} props.children - React children to wrap with context
|
|
61
|
+
* @param {AlchemyProviderConfig} props.config - Alchemy configuration
|
|
62
|
+
* @param {PrivyAdapter} props.adapter - Platform adapter
|
|
63
|
+
* @returns {JSX.Element} Context provider component
|
|
64
|
+
*/
|
|
65
|
+
export function AlchemyContextProvider({
|
|
66
|
+
children,
|
|
67
|
+
config,
|
|
68
|
+
adapter,
|
|
69
|
+
}: AlchemyContextProviderProps) {
|
|
70
|
+
const { authenticated } = adapter.usePrivyAuth();
|
|
71
|
+
const walletAddress = adapter.useWalletAddress(config.walletAddress);
|
|
72
|
+
|
|
73
|
+
// Normalize config with default values
|
|
74
|
+
const normalizedConfig: NormalizedAlchemyConfig = {
|
|
75
|
+
...config,
|
|
76
|
+
accountAuthMode: config.accountAuthMode ?? "eip7702",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Store cache in a ref - persists across renders but scoped to this component instance
|
|
80
|
+
// This makes it SSR-safe (each request gets its own cache) and React StrictMode-safe
|
|
81
|
+
const cache = useRef<ClientCache>({
|
|
82
|
+
client: null,
|
|
83
|
+
account: null,
|
|
84
|
+
cacheKey: null,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Track previous state to detect logout and wallet changes
|
|
88
|
+
const prevAuthenticatedRef = useRef(authenticated);
|
|
89
|
+
const prevWalletAddressRef = useRef(walletAddress);
|
|
90
|
+
|
|
91
|
+
// Automatically reset cache when user logs out or switches wallets
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const wasAuthenticated = prevAuthenticatedRef.current;
|
|
94
|
+
const prevWalletAddress = prevWalletAddressRef.current;
|
|
95
|
+
const currentWalletAddress = walletAddress;
|
|
96
|
+
|
|
97
|
+
// Reset cache on logout
|
|
98
|
+
if (wasAuthenticated && !authenticated) {
|
|
99
|
+
cache.current.client = null;
|
|
100
|
+
cache.current.account = null;
|
|
101
|
+
cache.current.cacheKey = null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Reset cache on wallet address change (account switching)
|
|
105
|
+
if (
|
|
106
|
+
authenticated &&
|
|
107
|
+
prevWalletAddress &&
|
|
108
|
+
currentWalletAddress &&
|
|
109
|
+
prevWalletAddress !== currentWalletAddress
|
|
110
|
+
) {
|
|
111
|
+
cache.current.client = null;
|
|
112
|
+
cache.current.account = null;
|
|
113
|
+
cache.current.cacheKey = null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Update refs for next render
|
|
117
|
+
prevAuthenticatedRef.current = authenticated;
|
|
118
|
+
prevWalletAddressRef.current = currentWalletAddress;
|
|
119
|
+
}, [authenticated, walletAddress]);
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<AlchemyConfigContext.Provider value={normalizedConfig}>
|
|
123
|
+
<AdapterContext.Provider value={adapter}>
|
|
124
|
+
<ClientCacheContext.Provider value={cache.current}>
|
|
125
|
+
{children}
|
|
126
|
+
</ClientCacheContext.Provider>
|
|
127
|
+
</AdapterContext.Provider>
|
|
128
|
+
</AlchemyConfigContext.Provider>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Hook to access Alchemy provider configuration
|
|
134
|
+
* Must be used within an <AlchemyProvider> component
|
|
135
|
+
*
|
|
136
|
+
* @returns {NormalizedAlchemyConfig} The current Alchemy configuration with defaults applied
|
|
137
|
+
* @throws {Error} If used outside of AlchemyProvider
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```tsx
|
|
141
|
+
* const config = useAlchemyConfig();
|
|
142
|
+
* console.log('Policy ID:', config.policyId);
|
|
143
|
+
* console.log('Auth Mode:', config.accountAuthMode); // Always defined
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export function useAlchemyConfig(): NormalizedAlchemyConfig {
|
|
147
|
+
const context = useContext(AlchemyConfigContext);
|
|
148
|
+
if (!context) {
|
|
149
|
+
throw new Error("useAlchemyConfig must be used within <AlchemyProvider />");
|
|
150
|
+
}
|
|
151
|
+
return context;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Hook to access the platform adapter
|
|
156
|
+
* Must be used within an <AlchemyProvider> component
|
|
157
|
+
*
|
|
158
|
+
* @internal
|
|
159
|
+
* @returns {PrivyAdapter} The platform adapter
|
|
160
|
+
*/
|
|
161
|
+
export function useAdapter(): PrivyAdapter {
|
|
162
|
+
const context = useContext(AdapterContext);
|
|
163
|
+
if (!context) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"useAdapter must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.",
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
return context;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Hook to access the client cache (internal use only)
|
|
173
|
+
*
|
|
174
|
+
* @internal
|
|
175
|
+
* @returns {ClientCache} The client cache object
|
|
176
|
+
*/
|
|
177
|
+
export function useClientCache(): ClientCache {
|
|
178
|
+
const context = useContext(ClientCacheContext);
|
|
179
|
+
if (!context) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
"useClientCache must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.",
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return context;
|
|
185
|
+
}
|
|
@@ -1,29 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
useWallets,
|
|
4
|
-
type ConnectedWallet as PrivyWallet,
|
|
5
|
-
} from "@privy-io/react-auth";
|
|
1
|
+
import { useAdapter, useAlchemyConfig } from "../../context/AlchemyContext.js";
|
|
6
2
|
|
|
7
3
|
/**
|
|
8
4
|
* Internal hook to get the Privy embedded wallet
|
|
9
|
-
*
|
|
5
|
+
* Uses the platform adapter to abstract differences between web and React Native
|
|
10
6
|
*
|
|
11
7
|
* @internal
|
|
12
|
-
* @returns {() =>
|
|
8
|
+
* @returns {() => EmbeddedWallet} Function that returns the embedded wallet
|
|
13
9
|
* @throws {Error} If embedded wallet is not found
|
|
14
10
|
*/
|
|
15
11
|
export function useEmbeddedWallet() {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const embedded = wallets.find((w) => w.walletClientType === "privy");
|
|
20
|
-
if (!embedded) {
|
|
21
|
-
throw new Error(
|
|
22
|
-
"Privy embedded wallet not found. Please ensure the user is authenticated.",
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
return embedded;
|
|
26
|
-
}, [wallets]);
|
|
27
|
-
|
|
28
|
-
return getEmbeddedWallet;
|
|
12
|
+
const adapter = useAdapter();
|
|
13
|
+
const config = useAlchemyConfig();
|
|
14
|
+
return adapter.useEmbeddedWallet(config.walletAddress);
|
|
29
15
|
}
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import {
|
|
3
3
|
WalletClientSigner,
|
|
4
|
-
type AuthorizationRequest,
|
|
5
4
|
ConnectionConfigSchema,
|
|
6
5
|
type SmartContractAccount,
|
|
7
6
|
} from "@aa-sdk/core";
|
|
8
|
-
import {
|
|
9
|
-
createWalletClient,
|
|
10
|
-
custom,
|
|
11
|
-
type Address,
|
|
12
|
-
type Authorization,
|
|
13
|
-
} from "viem";
|
|
14
|
-
import { useSign7702Authorization } from "@privy-io/react-auth";
|
|
7
|
+
import { createWalletClient, custom, type Address } from "viem";
|
|
15
8
|
import {
|
|
16
9
|
createSmartWalletClient,
|
|
17
10
|
type SmartWalletClient,
|
|
18
11
|
} from "@account-kit/wallet-client";
|
|
19
12
|
import { alchemy } from "@account-kit/infra";
|
|
20
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
useAlchemyConfig,
|
|
15
|
+
useClientCache,
|
|
16
|
+
useAdapter,
|
|
17
|
+
} from "../context/AlchemyContext.js";
|
|
21
18
|
import { getChain } from "../util/getChain.js";
|
|
22
19
|
import { useEmbeddedWallet } from "./internal/useEmbeddedWallet.js";
|
|
23
20
|
|
|
@@ -40,42 +37,43 @@ export type AlchemyClientResult = {
|
|
|
40
37
|
* ```
|
|
41
38
|
*/
|
|
42
39
|
export function useAlchemyClient() {
|
|
43
|
-
const
|
|
40
|
+
const adapter = useAdapter();
|
|
44
41
|
const config = useAlchemyConfig();
|
|
42
|
+
const signAuthorizationFn =
|
|
43
|
+
adapter.useAuthorizationSigner?.(config.walletAddress) || null;
|
|
45
44
|
const cache = useClientCache();
|
|
46
45
|
const getEmbeddedWallet = useEmbeddedWallet();
|
|
47
46
|
|
|
48
|
-
const
|
|
49
|
-
const
|
|
47
|
+
const getClient = useCallback(async (): Promise<AlchemyClientResult> => {
|
|
48
|
+
const embeddedWallet = getEmbeddedWallet();
|
|
49
|
+
|
|
50
|
+
// IMPORTANT: Get provider FIRST to ensure chain ID is updated
|
|
51
|
+
// The provider fetch triggers chain ID update in the adapter
|
|
52
|
+
const provider = await embeddedWallet.getEthereumProvider();
|
|
53
|
+
|
|
54
|
+
// NOW get the chain from the SAME wallet instance with updated chain ID
|
|
50
55
|
// Handle CAIP-2 format like "eip155:1"
|
|
51
|
-
const chainIdStr =
|
|
56
|
+
const chainIdStr = embeddedWallet.chainId?.toString();
|
|
52
57
|
|
|
53
58
|
if (!chainIdStr) {
|
|
54
59
|
throw new Error(
|
|
55
60
|
"Embedded wallet chainId is not set. Please ensure the wallet is connected to a network.",
|
|
56
61
|
);
|
|
57
62
|
}
|
|
58
|
-
|
|
59
63
|
const numericChainId = chainIdStr.includes(":")
|
|
60
64
|
? chainIdStr.split(":")[1]
|
|
61
65
|
: chainIdStr;
|
|
62
|
-
|
|
63
66
|
const parsedChainId = Number(numericChainId);
|
|
64
|
-
|
|
65
67
|
if (isNaN(parsedChainId)) {
|
|
66
68
|
throw new Error(
|
|
67
69
|
`Failed to parse chainId from embedded wallet. Received: ${chainIdStr}`,
|
|
68
70
|
);
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
}, [getEmbeddedWallet]);
|
|
73
|
-
|
|
74
|
-
const getClient = useCallback(async (): Promise<AlchemyClientResult> => {
|
|
75
|
-
const embeddedWallet = getEmbeddedWallet();
|
|
76
|
-
const chain = getEmbeddedWalletChain();
|
|
73
|
+
const chain = getChain(parsedChainId);
|
|
77
74
|
|
|
78
75
|
// Generate a cache key based on configuration and wallet address
|
|
76
|
+
// IMPORTANT: Include whether authorization signer is available in cache key
|
|
79
77
|
const currentCacheKey = JSON.stringify({
|
|
80
78
|
address: embeddedWallet.address,
|
|
81
79
|
chainId: chain.id,
|
|
@@ -84,6 +82,7 @@ export function useAlchemyClient() {
|
|
|
84
82
|
rpcUrl: config.rpcUrl,
|
|
85
83
|
policyId: config.policyId,
|
|
86
84
|
accountAuthMode: config.accountAuthMode,
|
|
85
|
+
hasAuthSigner: !!signAuthorizationFn,
|
|
87
86
|
});
|
|
88
87
|
|
|
89
88
|
// Return cached client and account if configuration hasn't changed
|
|
@@ -91,9 +90,6 @@ export function useAlchemyClient() {
|
|
|
91
90
|
return { client: cache.client, account: cache.account };
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
// Configuration changed or no cache exists, create new client
|
|
95
|
-
const provider = await embeddedWallet.getEthereumProvider();
|
|
96
|
-
|
|
97
93
|
// Create base signer from Privy wallet
|
|
98
94
|
const baseSigner = new WalletClientSigner(
|
|
99
95
|
createWalletClient({
|
|
@@ -106,19 +102,10 @@ export function useAlchemyClient() {
|
|
|
106
102
|
|
|
107
103
|
// Optionally extend signer with EIP-7702 authorization support
|
|
108
104
|
const signer =
|
|
109
|
-
config.accountAuthMode === "eip7702"
|
|
105
|
+
config.accountAuthMode === "eip7702" && !!signAuthorizationFn
|
|
110
106
|
? {
|
|
111
107
|
...baseSigner,
|
|
112
|
-
signAuthorization:
|
|
113
|
-
unsignedAuth: AuthorizationRequest<number>,
|
|
114
|
-
): Promise<Authorization<number, true>> => {
|
|
115
|
-
const signature = await signAuthorization({
|
|
116
|
-
...unsignedAuth,
|
|
117
|
-
contractAddress:
|
|
118
|
-
unsignedAuth.address ?? unsignedAuth.contractAddress,
|
|
119
|
-
});
|
|
120
|
-
return { ...unsignedAuth, ...signature };
|
|
121
|
-
},
|
|
108
|
+
signAuthorization: signAuthorizationFn,
|
|
122
109
|
}
|
|
123
110
|
: baseSigner;
|
|
124
111
|
|
|
@@ -166,8 +153,7 @@ export function useAlchemyClient() {
|
|
|
166
153
|
return { client: cache.client, account: cache.account };
|
|
167
154
|
}, [
|
|
168
155
|
getEmbeddedWallet,
|
|
169
|
-
|
|
170
|
-
signAuthorization,
|
|
156
|
+
signAuthorizationFn,
|
|
171
157
|
config.apiKey,
|
|
172
158
|
config.jwt,
|
|
173
159
|
config.rpcUrl,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useState } from "react";
|
|
2
2
|
import { type Hex, isHex } from "viem";
|
|
3
3
|
import { useAlchemyClient } from "./useAlchemyClient.js";
|
|
4
|
-
import { useAlchemyConfig } from "../
|
|
4
|
+
import { useAlchemyConfig } from "../context/AlchemyContext.js";
|
|
5
5
|
import type {
|
|
6
6
|
UnsignedTransactionRequest,
|
|
7
7
|
SendTransactionOptions,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
TransactionInstruction,
|
|
8
8
|
VersionedTransaction,
|
|
9
9
|
} from "@solana/web3.js";
|
|
10
|
-
import { useAlchemyConfig } from "../
|
|
10
|
+
import { useAlchemyConfig } from "../context/AlchemyContext.js";
|
|
11
11
|
import { createSolanaSponsoredTransaction } from "../util/createSolanaSponsoredTransaction.js";
|
|
12
12
|
import { useSignTransaction, useWallets } from "@privy-io/react-auth/solana";
|
|
13
13
|
import { createSolanaTransaction } from "../util/createSolanaTransaction.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PropsWithChildren } from "react";
|
|
2
|
+
import { AlchemyContextProvider } from "../context/AlchemyContext.js";
|
|
3
|
+
import { reactNativeAdapter } from "../adapters/react-native.js";
|
|
4
|
+
import type { AlchemyProviderConfig } from "../types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Provider component for React Native (Expo) applications
|
|
8
|
+
* Must be nested INSIDE PrivyProvider from @privy-io/expo
|
|
9
|
+
*
|
|
10
|
+
* @param {PropsWithChildren<AlchemyProviderConfig>} props - Component props
|
|
11
|
+
* @param {React.ReactNode} props.children - React children to wrap with Alchemy configuration
|
|
12
|
+
* @param {string} [props.apiKey] - Your Alchemy API key
|
|
13
|
+
* @param {string} [props.jwt] - JWT token for authentication
|
|
14
|
+
* @param {string} [props.rpcUrl] - Custom RPC URL for EVM chains
|
|
15
|
+
* @param {string} [props.solanaRpcUrl] - Custom RPC URL for Solana
|
|
16
|
+
* @param {string | string[]} [props.policyId] - Gas Manager policy ID(s) for EVM chains
|
|
17
|
+
* @param {string | string[]} [props.solanaPolicyId] - Gas Manager policy ID(s) for Solana
|
|
18
|
+
* @param {boolean} [props.disableSponsorship] - Set to true to disable sponsorship by default (default: false)
|
|
19
|
+
* @param {'eip7702' | 'owner'} [props.accountAuthMode] - Authorization mode for EVM smart accounts (default: 'eip7702')
|
|
20
|
+
* @param {string} [props.walletAddress] - Optional: Specify which wallet address to use (defaults to first wallet in array)
|
|
21
|
+
* @returns {JSX.Element} Provider component
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* import { PrivyProvider } from '@privy-io/expo';
|
|
26
|
+
* import { AlchemyProvider } from '@account-kit/privy-integration/react-native';
|
|
27
|
+
*
|
|
28
|
+
* <PrivyProvider appId="..." clientId="...">
|
|
29
|
+
* <AlchemyProvider
|
|
30
|
+
* apiKey="your-alchemy-api-key"
|
|
31
|
+
* policyId="your-gas-policy-id"
|
|
32
|
+
* accountAuthMode="eip7702"
|
|
33
|
+
* walletAddress="0x123..." // Optional: specify which wallet to use
|
|
34
|
+
* >
|
|
35
|
+
* <YourApp />
|
|
36
|
+
* </AlchemyProvider>
|
|
37
|
+
* </PrivyProvider>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function AlchemyProvider({
|
|
41
|
+
children,
|
|
42
|
+
...config
|
|
43
|
+
}: PropsWithChildren<AlchemyProviderConfig>) {
|
|
44
|
+
return (
|
|
45
|
+
<AlchemyContextProvider config={config} adapter={reactNativeAdapter}>
|
|
46
|
+
{children}
|
|
47
|
+
</AlchemyContextProvider>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native stub for WebProvider
|
|
3
|
+
* This file prevents Metro from importing web-specific code
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function AlchemyProvider() {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"This module requires @privy-io/react-auth which is not available in React Native. " +
|
|
9
|
+
'Import from "@account-kit/privy-integration/react-native" instead.',
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PropsWithChildren } from "react";
|
|
2
|
+
import { AlchemyContextProvider } from "../context/AlchemyContext.js";
|
|
3
|
+
import { webAdapter } from "../adapters/web.js";
|
|
4
|
+
import type { AlchemyProviderConfig } from "../types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Provider component for React web applications
|
|
8
|
+
* Must be nested INSIDE PrivyProvider from @privy-io/react-auth
|
|
9
|
+
*
|
|
10
|
+
* @param {PropsWithChildren<AlchemyProviderConfig>} props - Component props
|
|
11
|
+
* @param {React.ReactNode} props.children - React children to wrap with Alchemy configuration
|
|
12
|
+
* @param {string} [props.apiKey] - Your Alchemy API key
|
|
13
|
+
* @param {string} [props.jwt] - JWT token for authentication
|
|
14
|
+
* @param {string} [props.rpcUrl] - Custom RPC URL for EVM chains
|
|
15
|
+
* @param {string} [props.solanaRpcUrl] - Custom RPC URL for Solana
|
|
16
|
+
* @param {string | string[]} [props.policyId] - Gas Manager policy ID(s) for EVM chains
|
|
17
|
+
* @param {string | string[]} [props.solanaPolicyId] - Gas Manager policy ID(s) for Solana
|
|
18
|
+
* @param {boolean} [props.disableSponsorship] - Set to true to disable sponsorship by default (default: false)
|
|
19
|
+
* @param {'eip7702' | 'owner'} [props.accountAuthMode] - Authorization mode for EVM smart accounts (default: 'eip7702')
|
|
20
|
+
* @param {string} [props.walletAddress] - Optional: Specify which wallet address to use (defaults to first embedded wallet)
|
|
21
|
+
* @returns {JSX.Element} Provider component
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* import { PrivyProvider } from '@privy-io/react-auth';
|
|
26
|
+
* import { AlchemyProvider } from '@account-kit/privy-integration';
|
|
27
|
+
*
|
|
28
|
+
* <PrivyProvider appId="...">
|
|
29
|
+
* <AlchemyProvider
|
|
30
|
+
* apiKey="your-alchemy-api-key"
|
|
31
|
+
* policyId="your-gas-policy-id"
|
|
32
|
+
* accountAuthMode="eip7702"
|
|
33
|
+
* walletAddress="0x123..." // Optional: specify which wallet to use
|
|
34
|
+
* >
|
|
35
|
+
* <YourApp />
|
|
36
|
+
* </AlchemyProvider>
|
|
37
|
+
* </PrivyProvider>
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export function AlchemyProvider({
|
|
41
|
+
children,
|
|
42
|
+
...config
|
|
43
|
+
}: PropsWithChildren<AlchemyProviderConfig>) {
|
|
44
|
+
return (
|
|
45
|
+
<AlchemyContextProvider config={config} adapter={webAdapter}>
|
|
46
|
+
{children}
|
|
47
|
+
</AlchemyContextProvider>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native (Expo) entry point
|
|
3
|
+
* Import from '@account-kit/privy-integration/react-native' in Expo apps
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Provider
|
|
7
|
+
export { AlchemyProvider } from "./providers/ReactNativeProvider.js";
|
|
8
|
+
export { useAlchemyConfig } from "./context/AlchemyContext.js";
|
|
9
|
+
|
|
10
|
+
// Hooks
|
|
11
|
+
export { useAlchemyClient } from "./hooks/useAlchemyClient.js";
|
|
12
|
+
export { useAlchemySendTransaction } from "./hooks/useAlchemySendTransaction.js";
|
|
13
|
+
export { useAlchemyPrepareSwap } from "./hooks/useAlchemyPrepareSwap.js";
|
|
14
|
+
export { useAlchemySubmitSwap } from "./hooks/useAlchemySubmitSwap.js";
|
|
15
|
+
|
|
16
|
+
// Types
|
|
17
|
+
export type {
|
|
18
|
+
AlchemyProviderConfig,
|
|
19
|
+
UnsignedTransactionRequest,
|
|
20
|
+
SendTransactionOptions,
|
|
21
|
+
SendTransactionResult,
|
|
22
|
+
UseSendTransactionResult,
|
|
23
|
+
PrepareSwapRequest,
|
|
24
|
+
PrepareSwapResult,
|
|
25
|
+
UsePrepareSwapResult,
|
|
26
|
+
SubmitSwapResult,
|
|
27
|
+
UseSubmitSwapResult,
|
|
28
|
+
SwapQuote,
|
|
29
|
+
} from "./types.js";
|
package/src/types.ts
CHANGED
|
@@ -29,6 +29,13 @@ export type AlchemyProviderConfig = z.infer<typeof ConnectionConfigSchema> & {
|
|
|
29
29
|
* Default: false (sponsorship enabled when policyId is provided)
|
|
30
30
|
*/
|
|
31
31
|
disableSponsorship?: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Optional: Specify which wallet address to use
|
|
35
|
+
* - If provided, will use the wallet matching this address
|
|
36
|
+
* - If not provided, defaults to the first embedded wallet (web) or first wallet in array (React Native)
|
|
37
|
+
*/
|
|
38
|
+
walletAddress?: string;
|
|
32
39
|
};
|
|
33
40
|
|
|
34
41
|
/**
|
package/src/version.ts
CHANGED