@account-kit/privy-integration 4.73.0 → 4.73.1-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 -61
- package/dist/esm/Provider.js +4 -99
- package/dist/esm/Provider.js.map +1 -1
- package/dist/esm/adapters/react-native.d.ts +6 -0
- package/dist/esm/adapters/react-native.js +46 -0
- package/dist/esm/adapters/react-native.js.map +1 -0
- package/dist/esm/adapters/types.d.ts +44 -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 +50 -0
- package/dist/esm/adapters/web.js.map +1 -0
- package/dist/esm/context/AlchemyContext.d.ts +62 -0
- package/dist/esm/context/AlchemyContext.js +105 -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 +5 -13
- package/dist/esm/hooks/internal/useEmbeddedWallet.js.map +1 -1
- package/dist/esm/hooks/useAlchemyClient.js +13 -20
- package/dist/esm/hooks/useAlchemyClient.js.map +1 -1
- package/dist/esm/providers/ReactNativeProvider.d.ts +33 -0
- package/dist/esm/providers/ReactNativeProvider.js +37 -0
- package/dist/esm/providers/ReactNativeProvider.js.map +1 -0
- package/dist/esm/providers/WebProvider.d.ts +33 -0
- package/dist/esm/providers/WebProvider.js +37 -0
- package/dist/esm/providers/WebProvider.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/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 -61
- package/dist/types/Provider.d.ts.map +1 -1
- 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 +45 -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/context/AlchemyContext.d.ts +63 -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 +34 -0
- package/dist/types/providers/ReactNativeProvider.d.ts.map +1 -0
- package/dist/types/providers/WebProvider.d.ts +34 -0
- package/dist/types/providers/WebProvider.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/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +17 -4
- package/src/adapters/react-native.ts +71 -0
- package/src/adapters/types.ts +56 -0
- package/src/adapters/web.ts +73 -0
- package/src/hooks/internal/useEmbeddedWallet.ts +5 -20
- package/src/hooks/useAlchemyClient.ts +17 -32
- package/src/react-native.ts +29 -0
- package/src/version.ts +1 -1
package/dist/esm/Provider.d.ts
CHANGED
|
@@ -1,63 +1,6 @@
|
|
|
1
|
-
import { type PropsWithChildren } from "react";
|
|
2
|
-
import type { SmartWalletClient } from "@account-kit/wallet-client";
|
|
3
|
-
import type { AlchemyProviderConfig } from "./types.js";
|
|
4
1
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* @internal
|
|
2
|
+
* Web-specific exports
|
|
3
|
+
* Re-exports the web provider and hooks for React applications
|
|
8
4
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
cacheKey: string | null;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Provider component that configures Alchemy infrastructure for transaction handling
|
|
15
|
-
* Must be nested INSIDE PrivyProvider to access authentication state
|
|
16
|
-
* Automatically manages client cache lifecycle and resets on logout
|
|
17
|
-
*
|
|
18
|
-
* @param {PropsWithChildren<AlchemyProviderConfig>} props - Component props
|
|
19
|
-
* @param {React.ReactNode} props.children - React children to wrap with Alchemy configuration
|
|
20
|
-
* @param {string} [props.apiKey] - Your Alchemy API key
|
|
21
|
-
* @param {string} [props.jwt] - JWT token for authentication
|
|
22
|
-
* @param {string} [props.rpcUrl] - Custom RPC URL for EVM chains
|
|
23
|
-
* @param {string} [props.solanaRpcUrl] - Custom RPC URL for Solana
|
|
24
|
-
* @param {string | string[]} [props.policyId] - Gas Manager policy ID(s) for EVM chains
|
|
25
|
-
* @param {string | string[]} [props.solanaPolicyId] - Gas Manager policy ID(s) for Solana
|
|
26
|
-
* @param {boolean} [props.disableSponsorship] - Set to true to disable sponsorship by default (default: false)
|
|
27
|
-
* @returns {JSX.Element} Provider component
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```tsx
|
|
31
|
-
* <PrivyProvider appId="...">
|
|
32
|
-
* <AlchemyProvider
|
|
33
|
-
* apiKey="your-alchemy-api-key"
|
|
34
|
-
* policyId="your-gas-policy-id"
|
|
35
|
-
* >
|
|
36
|
-
* <YourApp />
|
|
37
|
-
* </AlchemyProvider>
|
|
38
|
-
* </PrivyProvider>
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
export declare function AlchemyProvider({ children, ...config }: PropsWithChildren<AlchemyProviderConfig>): import("react/jsx-runtime").JSX.Element;
|
|
42
|
-
/**
|
|
43
|
-
* Hook to access Alchemy provider configuration
|
|
44
|
-
* Must be used within an <AlchemyProvider> component
|
|
45
|
-
*
|
|
46
|
-
* @returns {AlchemyProviderConfig} The current Alchemy configuration
|
|
47
|
-
* @throws {Error} If used outside of AlchemyProvider
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```tsx
|
|
51
|
-
* const config = useAlchemyConfig();
|
|
52
|
-
* console.log('Policy ID:', config.policyId);
|
|
53
|
-
* ```
|
|
54
|
-
*/
|
|
55
|
-
export declare function useAlchemyConfig(): AlchemyProviderConfig;
|
|
56
|
-
/**
|
|
57
|
-
* Hook to access the client cache (internal use only)
|
|
58
|
-
*
|
|
59
|
-
* @internal
|
|
60
|
-
* @returns {ClientCache} The client cache object
|
|
61
|
-
*/
|
|
62
|
-
export declare function useClientCache(): ClientCache;
|
|
63
|
-
export {};
|
|
5
|
+
export { AlchemyProvider } from "./providers/WebProvider.js";
|
|
6
|
+
export { useAlchemyConfig } from "./context/AlchemyContext.js";
|
package/dist/esm/Provider.js
CHANGED
|
@@ -1,102 +1,7 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { createContext, useContext, useRef, useEffect, } from "react";
|
|
3
|
-
import { usePrivy } from "@privy-io/react-auth";
|
|
4
|
-
const AlchemyContext = createContext(null);
|
|
5
|
-
const ClientCacheContext = createContext(null);
|
|
6
1
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Automatically manages client cache lifecycle and resets on logout
|
|
10
|
-
*
|
|
11
|
-
* @param {PropsWithChildren<AlchemyProviderConfig>} props - Component props
|
|
12
|
-
* @param {React.ReactNode} props.children - React children to wrap with Alchemy configuration
|
|
13
|
-
* @param {string} [props.apiKey] - Your Alchemy API key
|
|
14
|
-
* @param {string} [props.jwt] - JWT token for authentication
|
|
15
|
-
* @param {string} [props.rpcUrl] - Custom RPC URL for EVM chains
|
|
16
|
-
* @param {string} [props.solanaRpcUrl] - Custom RPC URL for Solana
|
|
17
|
-
* @param {string | string[]} [props.policyId] - Gas Manager policy ID(s) for EVM chains
|
|
18
|
-
* @param {string | string[]} [props.solanaPolicyId] - Gas Manager policy ID(s) for Solana
|
|
19
|
-
* @param {boolean} [props.disableSponsorship] - Set to true to disable sponsorship by default (default: false)
|
|
20
|
-
* @returns {JSX.Element} Provider component
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```tsx
|
|
24
|
-
* <PrivyProvider appId="...">
|
|
25
|
-
* <AlchemyProvider
|
|
26
|
-
* apiKey="your-alchemy-api-key"
|
|
27
|
-
* policyId="your-gas-policy-id"
|
|
28
|
-
* >
|
|
29
|
-
* <YourApp />
|
|
30
|
-
* </AlchemyProvider>
|
|
31
|
-
* </PrivyProvider>
|
|
32
|
-
* ```
|
|
2
|
+
* Web-specific exports
|
|
3
|
+
* Re-exports the web provider and hooks for React applications
|
|
33
4
|
*/
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
// Store cache in a ref - persists across renders but scoped to this component instance
|
|
37
|
-
// This makes it SSR-safe (each request gets its own cache) and React StrictMode-safe
|
|
38
|
-
const cache = useRef({
|
|
39
|
-
client: null,
|
|
40
|
-
cacheKey: null,
|
|
41
|
-
});
|
|
42
|
-
// Track previous state to detect logout and wallet changes
|
|
43
|
-
const prevAuthenticatedRef = useRef(authenticated);
|
|
44
|
-
const prevWalletAddressRef = useRef(user?.wallet?.address);
|
|
45
|
-
// Automatically reset cache when user logs out or switches wallets
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
const wasAuthenticated = prevAuthenticatedRef.current;
|
|
48
|
-
const prevWalletAddress = prevWalletAddressRef.current;
|
|
49
|
-
const currentWalletAddress = user?.wallet?.address;
|
|
50
|
-
// Reset cache on logout
|
|
51
|
-
if (wasAuthenticated && !authenticated) {
|
|
52
|
-
cache.current.client = null;
|
|
53
|
-
cache.current.cacheKey = null;
|
|
54
|
-
}
|
|
55
|
-
// Reset cache on wallet address change (account switching)
|
|
56
|
-
if (authenticated &&
|
|
57
|
-
prevWalletAddress &&
|
|
58
|
-
currentWalletAddress &&
|
|
59
|
-
prevWalletAddress !== currentWalletAddress) {
|
|
60
|
-
cache.current.client = null;
|
|
61
|
-
cache.current.cacheKey = null;
|
|
62
|
-
}
|
|
63
|
-
// Update refs for next render
|
|
64
|
-
prevAuthenticatedRef.current = authenticated;
|
|
65
|
-
prevWalletAddressRef.current = currentWalletAddress;
|
|
66
|
-
}, [authenticated, user?.wallet?.address]);
|
|
67
|
-
return (_jsx(AlchemyContext.Provider, { value: config, children: _jsx(ClientCacheContext.Provider, { value: cache.current, children: children }) }));
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Hook to access Alchemy provider configuration
|
|
71
|
-
* Must be used within an <AlchemyProvider> component
|
|
72
|
-
*
|
|
73
|
-
* @returns {AlchemyProviderConfig} The current Alchemy configuration
|
|
74
|
-
* @throws {Error} If used outside of AlchemyProvider
|
|
75
|
-
*
|
|
76
|
-
* @example
|
|
77
|
-
* ```tsx
|
|
78
|
-
* const config = useAlchemyConfig();
|
|
79
|
-
* console.log('Policy ID:', config.policyId);
|
|
80
|
-
* ```
|
|
81
|
-
*/
|
|
82
|
-
export function useAlchemyConfig() {
|
|
83
|
-
const context = useContext(AlchemyContext);
|
|
84
|
-
if (!context) {
|
|
85
|
-
throw new Error("useAlchemyConfig must be used within <AlchemyProvider />");
|
|
86
|
-
}
|
|
87
|
-
return context;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Hook to access the client cache (internal use only)
|
|
91
|
-
*
|
|
92
|
-
* @internal
|
|
93
|
-
* @returns {ClientCache} The client cache object
|
|
94
|
-
*/
|
|
95
|
-
export function useClientCache() {
|
|
96
|
-
const context = useContext(ClientCacheContext);
|
|
97
|
-
if (!context) {
|
|
98
|
-
throw new Error("useClientCache must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.");
|
|
99
|
-
}
|
|
100
|
-
return context;
|
|
101
|
-
}
|
|
5
|
+
export { AlchemyProvider } from "./providers/WebProvider.js";
|
|
6
|
+
export { useAlchemyConfig } from "./context/AlchemyContext.js";
|
|
102
7
|
//# sourceMappingURL=Provider.js.map
|
package/dist/esm/Provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../src/Provider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Provider.js","sourceRoot":"","sources":["../../src/Provider.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC","sourcesContent":["/**\n * Web-specific exports\n * Re-exports the web provider and hooks for React applications\n */\nexport { AlchemyProvider } from \"./providers/WebProvider.js\";\nexport { useAlchemyConfig } from \"./context/AlchemyContext.js\";\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { usePrivy, useEmbeddedEthereumWallet, } from "@privy-io/expo";
|
|
3
|
+
/**
|
|
4
|
+
* React Native (Expo) adapter for @privy-io/expo
|
|
5
|
+
* Implements platform-specific hooks for React Native applications
|
|
6
|
+
*/
|
|
7
|
+
export const reactNativeAdapter = {
|
|
8
|
+
useEmbeddedWallet() {
|
|
9
|
+
const { wallets } = useEmbeddedEthereumWallet();
|
|
10
|
+
const getEmbeddedWallet = useCallback(() => {
|
|
11
|
+
const wallet = wallets?.[0];
|
|
12
|
+
if (!wallet) {
|
|
13
|
+
throw new Error("Privy embedded wallet not found. Please ensure the user is authenticated and has created a wallet.");
|
|
14
|
+
}
|
|
15
|
+
return adaptExpoWallet(wallet);
|
|
16
|
+
}, [wallets]);
|
|
17
|
+
return getEmbeddedWallet;
|
|
18
|
+
},
|
|
19
|
+
usePrivyAuth() {
|
|
20
|
+
const { user } = usePrivy();
|
|
21
|
+
return { authenticated: !!user, user };
|
|
22
|
+
},
|
|
23
|
+
// EIP-7702 authorization not available on React Native
|
|
24
|
+
useAuthorizationSigner() {
|
|
25
|
+
return null;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Adapts an Expo wallet to the common EmbeddedWallet interface
|
|
30
|
+
*
|
|
31
|
+
* @param {ExpoEmbeddedWallet} wallet - The Expo embedded wallet to adapt
|
|
32
|
+
* @returns {EmbeddedWallet} The adapted wallet following the common interface
|
|
33
|
+
*/
|
|
34
|
+
function adaptExpoWallet(wallet) {
|
|
35
|
+
return {
|
|
36
|
+
address: wallet.address,
|
|
37
|
+
chainId: wallet.chainId || "1",
|
|
38
|
+
getEthereumProvider: async () => {
|
|
39
|
+
if (!wallet.getProvider) {
|
|
40
|
+
throw new Error("getProvider is not available on this wallet. Ensure you're using the embedded Ethereum wallet.");
|
|
41
|
+
}
|
|
42
|
+
return await wallet.getProvider();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=react-native.js.map
|
|
@@ -0,0 +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;AAaxB;;;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,uDAAuD;IACvD,sBAAsB;QACpB,OAAO,IAAI,CAAC;IACd,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 { 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 // EIP-7702 authorization not available on React Native\n useAuthorizationSigner() {\n return null;\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"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Address, Authorization } from "viem";
|
|
2
|
+
import type { AuthorizationRequest } from "@aa-sdk/core";
|
|
3
|
+
/**
|
|
4
|
+
* Platform-agnostic embedded wallet interface
|
|
5
|
+
* Abstracts differences between @privy-io/react-auth and @privy-io/expo
|
|
6
|
+
*/
|
|
7
|
+
export interface EmbeddedWallet {
|
|
8
|
+
/** Wallet address */
|
|
9
|
+
address: Address;
|
|
10
|
+
/** Chain ID (may be CAIP-2 format like "eip155:1" or numeric) */
|
|
11
|
+
chainId: string | number;
|
|
12
|
+
/** Get EVM provider for the wallet */
|
|
13
|
+
getEthereumProvider(): Promise<any>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Platform-agnostic Privy auth state
|
|
17
|
+
*/
|
|
18
|
+
export interface PrivyAuthState {
|
|
19
|
+
/** Whether user is authenticated */
|
|
20
|
+
authenticated: boolean;
|
|
21
|
+
/** User object (platform-specific, used for cache invalidation) */
|
|
22
|
+
user: any;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Adapter interface that each platform must implement
|
|
26
|
+
* Provides platform-specific Privy functionality
|
|
27
|
+
*/
|
|
28
|
+
export interface PrivyAdapter {
|
|
29
|
+
/**
|
|
30
|
+
* Hook to get embedded wallet
|
|
31
|
+
* Must be called as a React hook (follows rules of hooks)
|
|
32
|
+
*/
|
|
33
|
+
useEmbeddedWallet(): () => EmbeddedWallet;
|
|
34
|
+
/**
|
|
35
|
+
* Hook to get Privy authentication state
|
|
36
|
+
* Must be called as a React hook (follows rules of hooks)
|
|
37
|
+
*/
|
|
38
|
+
usePrivyAuth(): PrivyAuthState;
|
|
39
|
+
/**
|
|
40
|
+
* Hook to get EIP-7702 authorization signer (optional, web only)
|
|
41
|
+
* Must be called as a React hook (follows rules of hooks)
|
|
42
|
+
*/
|
|
43
|
+
useAuthorizationSigner?(): ((auth: AuthorizationRequest<number>) => Promise<Authorization<number, true>>) | null;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/adapters/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { Address, Authorization } from \"viem\";\nimport type { AuthorizationRequest } from \"@aa-sdk/core\";\n\n/**\n * Platform-agnostic embedded wallet interface\n * Abstracts differences between @privy-io/react-auth and @privy-io/expo\n */\nexport interface EmbeddedWallet {\n /** Wallet address */\n address: Address;\n\n /** Chain ID (may be CAIP-2 format like \"eip155:1\" or numeric) */\n chainId: string | number;\n\n /** Get EVM provider for the wallet */\n getEthereumProvider(): Promise<any>;\n}\n\n/**\n * Platform-agnostic Privy auth state\n */\nexport interface PrivyAuthState {\n /** Whether user is authenticated */\n authenticated: boolean;\n\n /** User object (platform-specific, used for cache invalidation) */\n user: any;\n}\n\n/**\n * Adapter interface that each platform must implement\n * Provides platform-specific Privy functionality\n */\nexport interface PrivyAdapter {\n /**\n * Hook to get embedded wallet\n * Must be called as a React hook (follows rules of hooks)\n */\n useEmbeddedWallet(): () => EmbeddedWallet;\n\n /**\n * Hook to get Privy authentication state\n * Must be called as a React hook (follows rules of hooks)\n */\n usePrivyAuth(): PrivyAuthState;\n\n /**\n * Hook to get EIP-7702 authorization signer (optional, web only)\n * Must be called as a React hook (follows rules of hooks)\n */\n useAuthorizationSigner?():\n | ((\n auth: AuthorizationRequest<number>,\n ) => Promise<Authorization<number, true>>)\n | null;\n}\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useWallets, usePrivy, useSign7702Authorization, } from "@privy-io/react-auth";
|
|
3
|
+
/**
|
|
4
|
+
* Web adapter for @privy-io/react-auth
|
|
5
|
+
* Implements platform-specific hooks for React web applications
|
|
6
|
+
*/
|
|
7
|
+
export const webAdapter = {
|
|
8
|
+
useEmbeddedWallet() {
|
|
9
|
+
const { wallets } = useWallets();
|
|
10
|
+
const getEmbeddedWallet = useCallback(() => {
|
|
11
|
+
const embedded = wallets.find((w) => w.walletClientType === "privy");
|
|
12
|
+
if (!embedded) {
|
|
13
|
+
throw new Error("Privy embedded wallet not found. Please ensure the user is authenticated.");
|
|
14
|
+
}
|
|
15
|
+
return adaptWebWallet(embedded);
|
|
16
|
+
}, [wallets]);
|
|
17
|
+
return getEmbeddedWallet;
|
|
18
|
+
},
|
|
19
|
+
usePrivyAuth() {
|
|
20
|
+
const { user } = usePrivy();
|
|
21
|
+
return { authenticated: !!user, user };
|
|
22
|
+
},
|
|
23
|
+
useAuthorizationSigner() {
|
|
24
|
+
const { signAuthorization } = useSign7702Authorization();
|
|
25
|
+
return useCallback(async (unsignedAuth) => {
|
|
26
|
+
const signature = await signAuthorization({
|
|
27
|
+
...unsignedAuth,
|
|
28
|
+
contractAddress: unsignedAuth.address ?? unsignedAuth.contractAddress,
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
...unsignedAuth,
|
|
32
|
+
...signature,
|
|
33
|
+
};
|
|
34
|
+
}, [signAuthorization]);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Adapts a Privy web wallet to the common EmbeddedWallet interface
|
|
39
|
+
*
|
|
40
|
+
* @param {PrivyWallet} wallet - The Privy web wallet to adapt
|
|
41
|
+
* @returns {EmbeddedWallet} The adapted wallet following the common interface
|
|
42
|
+
*/
|
|
43
|
+
function adaptWebWallet(wallet) {
|
|
44
|
+
return {
|
|
45
|
+
address: wallet.address,
|
|
46
|
+
chainId: wallet.chainId || "1",
|
|
47
|
+
getEthereumProvider: () => wallet.getEthereumProvider(),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +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;AAK9B;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAiB;IACtC,iBAAiB;QACf,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;QAEjC,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAmB,EAAE;YACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,KAAK,OAAO,CAAC,CAAC;YACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;YACJ,CAAC;YAED,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClC,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,iBAAiB,EAAE,GAAG,wBAAwB,EAAE,CAAC;QAEzD,OAAO,WAAW,CAChB,KAAK,EACH,YAA0C,EACJ,EAAE;YACxC,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC;gBACxC,GAAG,YAAY;gBACf,eAAe,EAAE,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,eAAe;aACtE,CAAC,CAAC;YAEH,OAAO;gBACL,GAAG,YAAY;gBACf,GAAG,SAAS;aACb,CAAC;QACJ,CAAC,EACD,CAAC,iBAAiB,CAAC,CACpB,CAAC;IACJ,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,SAAS,cAAc,CAAC,MAAmB;IACzC,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAwB;QACxC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,GAAG;QAC9B,mBAAmB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,EAAE;KACxD,CAAC;AACJ,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport {\n useWallets,\n usePrivy,\n useSign7702Authorization,\n type ConnectedWallet as PrivyWallet,\n} from \"@privy-io/react-auth\";\nimport 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() {\n const { wallets } = useWallets();\n\n const getEmbeddedWallet = useCallback((): EmbeddedWallet => {\n const embedded = wallets.find((w) => w.walletClientType === \"privy\");\n if (!embedded) {\n throw new Error(\n \"Privy embedded wallet not found. Please ensure the user is authenticated.\",\n );\n }\n\n return adaptWebWallet(embedded);\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 { 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"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type PropsWithChildren } from "react";
|
|
2
|
+
import type { SmartWalletClient } from "@account-kit/wallet-client";
|
|
3
|
+
import type { AlchemyProviderConfig } from "../types.js";
|
|
4
|
+
import type { PrivyAdapter } from "../adapters/types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Client cache stored in React tree (similar to QueryClient in React Query)
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
interface ClientCache {
|
|
11
|
+
client: SmartWalletClient | null;
|
|
12
|
+
cacheKey: string | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Props for AlchemyContextProvider
|
|
16
|
+
*/
|
|
17
|
+
interface AlchemyContextProviderProps extends PropsWithChildren {
|
|
18
|
+
config: AlchemyProviderConfig;
|
|
19
|
+
adapter: PrivyAdapter;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Internal provider component that manages Alchemy context
|
|
23
|
+
* Used by both web and React Native providers
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
* @param {AlchemyContextProviderProps} props - Component props
|
|
27
|
+
* @param {React.ReactNode} props.children - React children to wrap with context
|
|
28
|
+
* @param {AlchemyProviderConfig} props.config - Alchemy configuration
|
|
29
|
+
* @param {PrivyAdapter} props.adapter - Platform adapter
|
|
30
|
+
* @returns {JSX.Element} Context provider component
|
|
31
|
+
*/
|
|
32
|
+
export declare function AlchemyContextProvider({ children, config, adapter, }: AlchemyContextProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
/**
|
|
34
|
+
* Hook to access Alchemy provider configuration
|
|
35
|
+
* Must be used within an <AlchemyProvider> component
|
|
36
|
+
*
|
|
37
|
+
* @returns {AlchemyProviderConfig} The current Alchemy configuration
|
|
38
|
+
* @throws {Error} If used outside of AlchemyProvider
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* const config = useAlchemyConfig();
|
|
43
|
+
* console.log('Policy ID:', config.policyId);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function useAlchemyConfig(): AlchemyProviderConfig;
|
|
47
|
+
/**
|
|
48
|
+
* Hook to access the platform adapter
|
|
49
|
+
* Must be used within an <AlchemyProvider> component
|
|
50
|
+
*
|
|
51
|
+
* @internal
|
|
52
|
+
* @returns {PrivyAdapter} The platform adapter
|
|
53
|
+
*/
|
|
54
|
+
export declare function useAdapter(): PrivyAdapter;
|
|
55
|
+
/**
|
|
56
|
+
* Hook to access the client cache (internal use only)
|
|
57
|
+
*
|
|
58
|
+
* @internal
|
|
59
|
+
* @returns {ClientCache} The client cache object
|
|
60
|
+
*/
|
|
61
|
+
export declare function useClientCache(): ClientCache;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useRef, useEffect, } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* Context for Alchemy configuration
|
|
5
|
+
*/
|
|
6
|
+
const AlchemyConfigContext = createContext(null);
|
|
7
|
+
/**
|
|
8
|
+
* Context for the platform adapter
|
|
9
|
+
*/
|
|
10
|
+
const AdapterContext = createContext(null);
|
|
11
|
+
const ClientCacheContext = createContext(null);
|
|
12
|
+
/**
|
|
13
|
+
* Internal provider component that manages Alchemy context
|
|
14
|
+
* Used by both web and React Native providers
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
* @param {AlchemyContextProviderProps} props - Component props
|
|
18
|
+
* @param {React.ReactNode} props.children - React children to wrap with context
|
|
19
|
+
* @param {AlchemyProviderConfig} props.config - Alchemy configuration
|
|
20
|
+
* @param {PrivyAdapter} props.adapter - Platform adapter
|
|
21
|
+
* @returns {JSX.Element} Context provider component
|
|
22
|
+
*/
|
|
23
|
+
export function AlchemyContextProvider({ children, config, adapter, }) {
|
|
24
|
+
const { authenticated, user } = adapter.usePrivyAuth();
|
|
25
|
+
// Store cache in a ref - persists across renders but scoped to this component instance
|
|
26
|
+
// This makes it SSR-safe (each request gets its own cache) and React StrictMode-safe
|
|
27
|
+
const cache = useRef({
|
|
28
|
+
client: null,
|
|
29
|
+
cacheKey: null,
|
|
30
|
+
});
|
|
31
|
+
// Track previous state to detect logout and wallet changes
|
|
32
|
+
const prevAuthenticatedRef = useRef(authenticated);
|
|
33
|
+
const prevWalletAddressRef = useRef(user?.wallet?.address);
|
|
34
|
+
// Automatically reset cache when user logs out or switches wallets
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const wasAuthenticated = prevAuthenticatedRef.current;
|
|
37
|
+
const prevWalletAddress = prevWalletAddressRef.current;
|
|
38
|
+
const currentWalletAddress = user?.wallet?.address;
|
|
39
|
+
// Reset cache on logout
|
|
40
|
+
if (wasAuthenticated && !authenticated) {
|
|
41
|
+
cache.current.client = null;
|
|
42
|
+
cache.current.cacheKey = null;
|
|
43
|
+
}
|
|
44
|
+
// Reset cache on wallet address change (account switching)
|
|
45
|
+
if (authenticated &&
|
|
46
|
+
prevWalletAddress &&
|
|
47
|
+
currentWalletAddress &&
|
|
48
|
+
prevWalletAddress !== currentWalletAddress) {
|
|
49
|
+
cache.current.client = null;
|
|
50
|
+
cache.current.cacheKey = null;
|
|
51
|
+
}
|
|
52
|
+
// Update refs for next render
|
|
53
|
+
prevAuthenticatedRef.current = authenticated;
|
|
54
|
+
prevWalletAddressRef.current = currentWalletAddress;
|
|
55
|
+
}, [authenticated, user?.wallet?.address]);
|
|
56
|
+
return (_jsx(AlchemyConfigContext.Provider, { value: config, children: _jsx(AdapterContext.Provider, { value: adapter, children: _jsx(ClientCacheContext.Provider, { value: cache.current, children: children }) }) }));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Hook to access Alchemy provider configuration
|
|
60
|
+
* Must be used within an <AlchemyProvider> component
|
|
61
|
+
*
|
|
62
|
+
* @returns {AlchemyProviderConfig} The current Alchemy configuration
|
|
63
|
+
* @throws {Error} If used outside of AlchemyProvider
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* const config = useAlchemyConfig();
|
|
68
|
+
* console.log('Policy ID:', config.policyId);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function useAlchemyConfig() {
|
|
72
|
+
const context = useContext(AlchemyConfigContext);
|
|
73
|
+
if (!context) {
|
|
74
|
+
throw new Error("useAlchemyConfig must be used within <AlchemyProvider />");
|
|
75
|
+
}
|
|
76
|
+
return context;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Hook to access the platform adapter
|
|
80
|
+
* Must be used within an <AlchemyProvider> component
|
|
81
|
+
*
|
|
82
|
+
* @internal
|
|
83
|
+
* @returns {PrivyAdapter} The platform adapter
|
|
84
|
+
*/
|
|
85
|
+
export function useAdapter() {
|
|
86
|
+
const context = useContext(AdapterContext);
|
|
87
|
+
if (!context) {
|
|
88
|
+
throw new Error("useAdapter must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.");
|
|
89
|
+
}
|
|
90
|
+
return context;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Hook to access the client cache (internal use only)
|
|
94
|
+
*
|
|
95
|
+
* @internal
|
|
96
|
+
* @returns {ClientCache} The client cache object
|
|
97
|
+
*/
|
|
98
|
+
export function useClientCache() {
|
|
99
|
+
const context = useContext(ClientCacheContext);
|
|
100
|
+
if (!context) {
|
|
101
|
+
throw new Error("useClientCache must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.");
|
|
102
|
+
}
|
|
103
|
+
return context;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=AlchemyContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AlchemyContext.js","sourceRoot":"","sources":["../../../src/context/AlchemyContext.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n type PropsWithChildren,\n createContext,\n useContext,\n useRef,\n useEffect,\n} from \"react\";\nimport type { SmartWalletClient } from \"@account-kit/wallet-client\";\nimport type { AlchemyProviderConfig } from \"../types.js\";\nimport type { PrivyAdapter } from \"../adapters/types.js\";\n\n/**\n * Context for Alchemy configuration\n */\nconst AlchemyConfigContext = createContext<AlchemyProviderConfig | null>(null);\n\n/**\n * Context for the platform adapter\n */\nconst AdapterContext = createContext<PrivyAdapter | null>(null);\n\n/**\n * Client cache stored in React tree (similar to QueryClient in React Query)\n *\n * @internal\n */\ninterface ClientCache {\n client: SmartWalletClient | null;\n cacheKey: string | null;\n}\n\nconst ClientCacheContext = createContext<ClientCache | null>(null);\n\n/**\n * Props for AlchemyContextProvider\n */\ninterface AlchemyContextProviderProps extends PropsWithChildren {\n config: AlchemyProviderConfig;\n adapter: PrivyAdapter;\n}\n\n/**\n * Internal provider component that manages Alchemy context\n * Used by both web and React Native providers\n *\n * @internal\n * @param {AlchemyContextProviderProps} props - Component props\n * @param {React.ReactNode} props.children - React children to wrap with context\n * @param {AlchemyProviderConfig} props.config - Alchemy configuration\n * @param {PrivyAdapter} props.adapter - Platform adapter\n * @returns {JSX.Element} Context provider component\n */\nexport function AlchemyContextProvider({\n children,\n config,\n adapter,\n}: AlchemyContextProviderProps) {\n const { authenticated, user } = adapter.usePrivyAuth();\n\n // Store cache in a ref - persists across renders but scoped to this component instance\n // This makes it SSR-safe (each request gets its own cache) and React StrictMode-safe\n const cache = useRef<ClientCache>({\n client: null,\n cacheKey: null,\n });\n\n // Track previous state to detect logout and wallet changes\n const prevAuthenticatedRef = useRef(authenticated);\n const prevWalletAddressRef = useRef(user?.wallet?.address);\n\n // Automatically reset cache when user logs out or switches wallets\n useEffect(() => {\n const wasAuthenticated = prevAuthenticatedRef.current;\n const prevWalletAddress = prevWalletAddressRef.current;\n const currentWalletAddress = user?.wallet?.address;\n\n // Reset cache on logout\n if (wasAuthenticated && !authenticated) {\n cache.current.client = null;\n cache.current.cacheKey = null;\n }\n\n // Reset cache on wallet address change (account switching)\n if (\n authenticated &&\n prevWalletAddress &&\n currentWalletAddress &&\n prevWalletAddress !== currentWalletAddress\n ) {\n cache.current.client = null;\n cache.current.cacheKey = null;\n }\n\n // Update refs for next render\n prevAuthenticatedRef.current = authenticated;\n prevWalletAddressRef.current = currentWalletAddress;\n }, [authenticated, user?.wallet?.address]);\n\n return (\n <AlchemyConfigContext.Provider value={config}>\n <AdapterContext.Provider value={adapter}>\n <ClientCacheContext.Provider value={cache.current}>\n {children}\n </ClientCacheContext.Provider>\n </AdapterContext.Provider>\n </AlchemyConfigContext.Provider>\n );\n}\n\n/**\n * Hook to access Alchemy provider configuration\n * Must be used within an <AlchemyProvider> component\n *\n * @returns {AlchemyProviderConfig} The current Alchemy configuration\n * @throws {Error} If used outside of AlchemyProvider\n *\n * @example\n * ```tsx\n * const config = useAlchemyConfig();\n * console.log('Policy ID:', config.policyId);\n * ```\n */\nexport function useAlchemyConfig(): AlchemyProviderConfig {\n const context = useContext(AlchemyConfigContext);\n if (!context) {\n throw new Error(\"useAlchemyConfig must be used within <AlchemyProvider />\");\n }\n return context;\n}\n\n/**\n * Hook to access the platform adapter\n * Must be used within an <AlchemyProvider> component\n *\n * @internal\n * @returns {PrivyAdapter} The platform adapter\n */\nexport function useAdapter(): PrivyAdapter {\n const context = useContext(AdapterContext);\n if (!context) {\n throw new Error(\n \"useAdapter must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.\",\n );\n }\n return context;\n}\n\n/**\n * Hook to access the client cache (internal use only)\n *\n * @internal\n * @returns {ClientCache} The client cache object\n */\nexport function useClientCache(): ClientCache {\n const context = useContext(ClientCacheContext);\n if (!context) {\n throw new Error(\n \"useClientCache must be used within <AlchemyProvider />. Make sure AlchemyProvider is nested inside PrivyProvider.\",\n );\n }\n return context;\n}\n"]}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { type ConnectedWallet as PrivyWallet } from "@privy-io/react-auth";
|
|
2
1
|
/**
|
|
3
2
|
* Internal hook to get the Privy embedded wallet
|
|
4
|
-
*
|
|
3
|
+
* Uses the platform adapter to abstract differences between web and React Native
|
|
5
4
|
*
|
|
6
5
|
* @internal
|
|
7
|
-
* @returns {() =>
|
|
6
|
+
* @returns {() => EmbeddedWallet} Function that returns the embedded wallet
|
|
8
7
|
* @throws {Error} If embedded wallet is not found
|
|
9
8
|
*/
|
|
10
|
-
export declare function useEmbeddedWallet(): () =>
|
|
9
|
+
export declare function useEmbeddedWallet(): () => import("../../adapters/types.js").EmbeddedWallet;
|
|
@@ -1,22 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useWallets, } from "@privy-io/react-auth";
|
|
1
|
+
import { useAdapter } from "../../context/AlchemyContext.js";
|
|
3
2
|
/**
|
|
4
3
|
* Internal hook to get the Privy embedded wallet
|
|
5
|
-
*
|
|
4
|
+
* Uses the platform adapter to abstract differences between web and React Native
|
|
6
5
|
*
|
|
7
6
|
* @internal
|
|
8
|
-
* @returns {() =>
|
|
7
|
+
* @returns {() => EmbeddedWallet} Function that returns the embedded wallet
|
|
9
8
|
* @throws {Error} If embedded wallet is not found
|
|
10
9
|
*/
|
|
11
10
|
export function useEmbeddedWallet() {
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const embedded = wallets.find((w) => w.walletClientType === "privy");
|
|
15
|
-
if (!embedded) {
|
|
16
|
-
throw new Error("Privy embedded wallet not found. Please ensure the user is authenticated.");
|
|
17
|
-
}
|
|
18
|
-
return embedded;
|
|
19
|
-
}, [wallets]);
|
|
20
|
-
return getEmbeddedWallet;
|
|
11
|
+
const adapter = useAdapter();
|
|
12
|
+
return adapter.useEmbeddedWallet();
|
|
21
13
|
}
|
|
22
14
|
//# sourceMappingURL=useEmbeddedWallet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEmbeddedWallet.js","sourceRoot":"","sources":["../../../../src/hooks/internal/useEmbeddedWallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"useEmbeddedWallet.js","sourceRoot":"","sources":["../../../../src/hooks/internal/useEmbeddedWallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,iBAAiB,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import { useAdapter } from \"../../context/AlchemyContext.js\";\n\n/**\n * Internal hook to get the Privy embedded wallet\n * Uses the platform adapter to abstract differences between web and React Native\n *\n * @internal\n * @returns {() => EmbeddedWallet} Function that returns the embedded wallet\n * @throws {Error} If embedded wallet is not found\n */\nexport function useEmbeddedWallet() {\n const adapter = useAdapter();\n return adapter.useEmbeddedWallet();\n}\n"]}
|