-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathproviders.tsx
More file actions
125 lines (110 loc) · 4.2 KB
/
providers.tsx
File metadata and controls
125 lines (110 loc) · 4.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use client';
import type { ReactNode } from 'react';
import { useEffect, useMemo } from 'react';
import { AppProvider, getDefaultConfig, getDefaultMobileConfig } from '@solana/connector/react';
import { createRemoteSignerWallet } from '@solana/connector/remote';
// Get origin synchronously on client, fallback for SSR
const getOrigin = () => {
if (typeof window !== 'undefined') {
return window.location.origin;
}
return 'http://localhost:3000';
};
// Enable remote signer via environment variable (set NEXT_PUBLIC_ENABLE_REMOTE_SIGNER=true)
// For testing, default to true if not explicitly set to 'false'
const ENABLE_REMOTE_SIGNER = process.env.NEXT_PUBLIC_ENABLE_REMOTE_SIGNER !== 'false';
export function Providers({ children }: { children: ReactNode }) {
const connectorConfig = useMemo(() => {
const origin = getOrigin();
// Use RPC proxy to keep API keys server-side
const rpcProxyUrl = `${origin}/api/rpc`;
const clusters = [
{
id: 'solana:mainnet' as const,
label: 'Mainnet',
name: 'mainnet-beta' as const,
url: rpcProxyUrl,
},
{
id: 'solana:devnet' as const,
label: 'Devnet',
name: 'devnet' as const,
url: 'https://api.devnet.solana.com',
},
{
id: 'solana:testnet' as const,
label: 'Testnet',
name: 'testnet' as const,
url: 'https://api.testnet.solana.com',
},
];
// Create remote signer wallet if enabled
// This wallet delegates signing to the /api/connector-signer endpoint
const additionalWallets = ENABLE_REMOTE_SIGNER
? [
createRemoteSignerWallet({
endpoint: `${origin}/api/connector-signer`,
name: 'Privy',
// Optional: provide auth headers for the signing API
// getAuthHeaders: () => ({
// 'Authorization': `Bearer ${getSessionToken()}`
// }),
}),
]
: undefined;
return getDefaultConfig({
appName: 'ConnectorKit Example',
appUrl: origin,
autoConnect: true,
enableMobile: true,
clusters,
additionalWallets,
// WalletConnect: just set to true!
// Project ID is auto-read from NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
// Metadata is auto-generated from appName/appUrl
// Callbacks are auto-wired by AppProvider
walletConnect: true,
});
}, []);
const mobile = useMemo(
() =>
getDefaultMobileConfig({
appName: 'ConnectorKit Example',
appUrl: getOrigin(),
}),
[],
);
// Mount devtools in development mode
useEffect(() => {
if (process.env.NODE_ENV !== 'development') return;
let devtools: { mount: (el: HTMLElement) => void; unmount: () => void } | undefined;
let container: HTMLDivElement | undefined;
// Dynamic import to avoid bundling in production
import('@solana/devtools').then(({ ConnectorDevtools }) => {
// Create container for devtools
container = document.createElement('div');
container.id = 'connector-devtools-container';
document.body.appendChild(container);
// Create and mount devtools (auto-detects window.__connectorClient)
devtools = new ConnectorDevtools({
config: {
position: 'bottom-right',
theme: 'dark',
defaultOpen: false,
rpcUrl: process.env.NEXT_PUBLIC_RPC_URL,
},
});
devtools.mount(container);
});
// Cleanup on unmount
return () => {
devtools?.unmount();
container?.remove();
};
}, []);
return (
<AppProvider connectorConfig={connectorConfig} mobile={mobile}>
{children}
</AppProvider>
);
}