helius-wallet-kit 0.1.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 +96 -0
- package/dist/core/index.cjs +461 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +170 -0
- package/dist/core/index.d.ts +170 -0
- package/dist/core/index.js +456 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.cjs +461 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +456 -0
- package/dist/index.js.map +1 -0
- package/dist/next/index.cjs +240 -0
- package/dist/next/index.cjs.map +1 -0
- package/dist/next/index.d.cts +53 -0
- package/dist/next/index.d.ts +53 -0
- package/dist/next/index.js +238 -0
- package/dist/next/index.js.map +1 -0
- package/dist/ui/index.cjs +4 -0
- package/dist/ui/index.cjs.map +1 -0
- package/dist/ui/index.d.cts +2 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/styles.css +58 -0
- package/package.json +83 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import { createContext, useMemo, useState, useEffect, useContext, useCallback } from 'react';
|
|
2
|
+
import { TurnkeyProvider, useTurnkey, ClientState, AuthState } from '@turnkey/react-wallet-kit';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { Connection } from '@solana/web3.js';
|
|
5
|
+
|
|
6
|
+
// src/core/HeliusWalletProvider.tsx
|
|
7
|
+
|
|
8
|
+
// src/core/types.ts
|
|
9
|
+
var WAAS_ALLOWED_PLANS = ["business", "professional"];
|
|
10
|
+
function isWaasEligible(plan) {
|
|
11
|
+
return WAAS_ALLOWED_PLANS.includes(plan);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/core/constants.ts
|
|
15
|
+
var SOLANA_WALLET_ACCOUNT_CONFIG = {
|
|
16
|
+
curve: "CURVE_ED25519",
|
|
17
|
+
pathFormat: "PATH_FORMAT_BIP32",
|
|
18
|
+
path: "m/44'/501'/0'/0'",
|
|
19
|
+
addressFormat: "ADDRESS_FORMAT_SOLANA"
|
|
20
|
+
};
|
|
21
|
+
var DEFAULT_THEME = {
|
|
22
|
+
primaryColor: "#E84125",
|
|
23
|
+
borderRadius: "12px",
|
|
24
|
+
logoLight: "/Helius-Horizontal-Logo-Black.svg",
|
|
25
|
+
logoDark: "/Helius-Horizontal-Logo-White.svg",
|
|
26
|
+
darkMode: true
|
|
27
|
+
};
|
|
28
|
+
var DEFAULT_RPC_PROXY_PATH = "/api/helius/rpc";
|
|
29
|
+
var DEFAULT_HELIUS_API_URL = "https://dev-api.helius.xyz/v0";
|
|
30
|
+
|
|
31
|
+
// src/core/turnkey-config.ts
|
|
32
|
+
function buildTurnkeyConfig(config, bootstrap) {
|
|
33
|
+
const theme = { ...DEFAULT_THEME, ...config.theme };
|
|
34
|
+
const walletAccounts = [SOLANA_WALLET_ACCOUNT_CONFIG];
|
|
35
|
+
const walletConfig = {
|
|
36
|
+
walletName: "Solana Wallet",
|
|
37
|
+
walletAccounts
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
organizationId: bootstrap.organizationId,
|
|
41
|
+
authProxyConfigId: bootstrap.authProxyConfigId,
|
|
42
|
+
auth: {
|
|
43
|
+
// subOrgName = projectId stamps every end-user sub-org with the project,
|
|
44
|
+
// so signatures can be attributed back to it for usage billing (looked up
|
|
45
|
+
// via getSubOrgIds by name). Without it, Turnkey defaults the name to the
|
|
46
|
+
// site hostname and attribution is lost.
|
|
47
|
+
createSuborgParams: {
|
|
48
|
+
passkeyAuth: {
|
|
49
|
+
userName: "Default User",
|
|
50
|
+
subOrgName: config.projectId,
|
|
51
|
+
passkeyName: "Helius Wallet",
|
|
52
|
+
customWallet: walletConfig
|
|
53
|
+
},
|
|
54
|
+
emailOtpAuth: {
|
|
55
|
+
userName: "Email User",
|
|
56
|
+
subOrgName: config.projectId,
|
|
57
|
+
customWallet: walletConfig
|
|
58
|
+
},
|
|
59
|
+
walletAuth: {
|
|
60
|
+
userName: "Wallet User",
|
|
61
|
+
subOrgName: config.projectId,
|
|
62
|
+
customWallet: walletConfig
|
|
63
|
+
},
|
|
64
|
+
oauth: {
|
|
65
|
+
userName: "OAuth User",
|
|
66
|
+
subOrgName: config.projectId,
|
|
67
|
+
customWallet: walletConfig
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
methods: config.authMethods ? {
|
|
71
|
+
passkeyAuthEnabled: config.authMethods.passkey ?? true,
|
|
72
|
+
emailOtpAuthEnabled: config.authMethods.email ?? true,
|
|
73
|
+
smsOtpAuthEnabled: config.authMethods.sms ?? false,
|
|
74
|
+
walletAuthEnabled: config.authMethods.wallet ?? false,
|
|
75
|
+
googleOauthEnabled: config.authMethods.google ?? false,
|
|
76
|
+
appleOauthEnabled: config.authMethods.apple ?? false,
|
|
77
|
+
discordOauthEnabled: config.authMethods.discord ?? false,
|
|
78
|
+
xOauthEnabled: config.authMethods.x ?? false
|
|
79
|
+
} : void 0,
|
|
80
|
+
autoRefreshSession: true
|
|
81
|
+
},
|
|
82
|
+
ui: {
|
|
83
|
+
logoLight: theme.logoLight,
|
|
84
|
+
logoDark: theme.logoDark,
|
|
85
|
+
darkMode: theme.darkMode,
|
|
86
|
+
borderRadius: theme.borderRadius,
|
|
87
|
+
colors: {
|
|
88
|
+
light: {
|
|
89
|
+
primary: theme.primaryColor,
|
|
90
|
+
primaryText: "#FFFFFF",
|
|
91
|
+
button: "#FFFFFF",
|
|
92
|
+
modalBackground: "#FFFFFF",
|
|
93
|
+
modalText: "#090909"
|
|
94
|
+
},
|
|
95
|
+
dark: {
|
|
96
|
+
primary: theme.primaryColor,
|
|
97
|
+
primaryText: "#FFFFFF",
|
|
98
|
+
button: "#222222",
|
|
99
|
+
modalBackground: "#090909",
|
|
100
|
+
modalText: "#DBDBDB",
|
|
101
|
+
iconText: "#999999",
|
|
102
|
+
iconBackground: "#333333"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/core/waas-config.ts
|
|
110
|
+
async function fetchWaasBootstrap(apiBaseUrl, apiKey) {
|
|
111
|
+
try {
|
|
112
|
+
const res = await fetch(`${apiBaseUrl}/waas/config`, {
|
|
113
|
+
headers: { "x-api-key": apiKey }
|
|
114
|
+
});
|
|
115
|
+
const data = await res.json().catch(() => ({}));
|
|
116
|
+
if (res.ok && data.organizationId && data.authProxyConfigId) {
|
|
117
|
+
return {
|
|
118
|
+
bootstrap: {
|
|
119
|
+
organizationId: data.organizationId,
|
|
120
|
+
authProxyConfigId: data.authProxyConfigId
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
error: {
|
|
126
|
+
code: data.code,
|
|
127
|
+
message: data.message ?? `WaaS config request failed (${res.status})`
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
} catch (err) {
|
|
131
|
+
return {
|
|
132
|
+
error: { message: err instanceof Error ? err.message : "Unknown error" }
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
var HeliusWalletContext = createContext({
|
|
137
|
+
rpcProxyPath: DEFAULT_RPC_PROXY_PATH,
|
|
138
|
+
secureRpcUrl: void 0,
|
|
139
|
+
cluster: "devnet",
|
|
140
|
+
setCluster: () => {
|
|
141
|
+
},
|
|
142
|
+
apiKey: null,
|
|
143
|
+
projectId: null,
|
|
144
|
+
planTier: null,
|
|
145
|
+
waasEligible: false
|
|
146
|
+
});
|
|
147
|
+
function HeliusWalletProvider({
|
|
148
|
+
config,
|
|
149
|
+
children
|
|
150
|
+
}) {
|
|
151
|
+
const rpcProxyPath = config.rpcProxyPath ?? DEFAULT_RPC_PROXY_PATH;
|
|
152
|
+
const secureRpcUrl = useMemo(
|
|
153
|
+
() => config.secureRpcUrl,
|
|
154
|
+
[config.secureRpcUrl?.["mainnet-beta"], config.secureRpcUrl?.devnet]
|
|
155
|
+
);
|
|
156
|
+
const apiBaseUrl = config.apiBaseUrl ?? DEFAULT_HELIUS_API_URL;
|
|
157
|
+
const [cluster, setCluster] = useState(config.cluster ?? "devnet");
|
|
158
|
+
const apiKey = config.apiKey ?? null;
|
|
159
|
+
const projectId = config.projectId ?? null;
|
|
160
|
+
const planTier = config.planTier ?? null;
|
|
161
|
+
const [bootstrap, setBootstrap] = useState(null);
|
|
162
|
+
const [bootstrapError, setBootstrapError] = useState(null);
|
|
163
|
+
const waasEligible = planTier ? isWaasEligible(planTier) : false;
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
if (!apiKey) return;
|
|
166
|
+
let cancelled = false;
|
|
167
|
+
(async () => {
|
|
168
|
+
const result = await fetchWaasBootstrap(apiBaseUrl, apiKey);
|
|
169
|
+
if (cancelled) return;
|
|
170
|
+
if (result.bootstrap) {
|
|
171
|
+
setBootstrap(result.bootstrap);
|
|
172
|
+
} else if (result.error) {
|
|
173
|
+
setBootstrapError(result.error);
|
|
174
|
+
}
|
|
175
|
+
})();
|
|
176
|
+
return () => {
|
|
177
|
+
cancelled = true;
|
|
178
|
+
};
|
|
179
|
+
}, [apiKey, apiBaseUrl]);
|
|
180
|
+
const contextValue = useMemo(
|
|
181
|
+
() => ({ rpcProxyPath, secureRpcUrl, cluster, setCluster, apiKey, projectId, planTier, waasEligible }),
|
|
182
|
+
[rpcProxyPath, secureRpcUrl, cluster, apiKey, projectId, planTier, waasEligible]
|
|
183
|
+
);
|
|
184
|
+
if (planTier && !waasEligible) {
|
|
185
|
+
return /* @__PURE__ */ jsx(HeliusWalletContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("div", { style: {
|
|
186
|
+
display: "flex",
|
|
187
|
+
flexDirection: "column",
|
|
188
|
+
alignItems: "center",
|
|
189
|
+
justifyContent: "center",
|
|
190
|
+
minHeight: "100vh",
|
|
191
|
+
gap: "16px",
|
|
192
|
+
padding: "24px",
|
|
193
|
+
fontFamily: "system-ui, sans-serif"
|
|
194
|
+
}, children: [
|
|
195
|
+
/* @__PURE__ */ jsx("img", { src: "/Helius-Icon.svg", alt: "Helius", style: { width: 48, height: 48 } }),
|
|
196
|
+
/* @__PURE__ */ jsx("h1", { style: { fontSize: "24px", fontWeight: 700, margin: 0 }, children: "Helius WaaS" }),
|
|
197
|
+
/* @__PURE__ */ jsxs("p", { style: { color: "#999", margin: 0, textAlign: "center", maxWidth: 400 }, children: [
|
|
198
|
+
"Wallet-as-a-Service requires a ",
|
|
199
|
+
/* @__PURE__ */ jsx("strong", { children: "Business" }),
|
|
200
|
+
" or ",
|
|
201
|
+
/* @__PURE__ */ jsx("strong", { children: "Professional" }),
|
|
202
|
+
" plan. Your current plan: ",
|
|
203
|
+
/* @__PURE__ */ jsx("strong", { children: planTier }),
|
|
204
|
+
"."
|
|
205
|
+
] }),
|
|
206
|
+
/* @__PURE__ */ jsx(
|
|
207
|
+
"a",
|
|
208
|
+
{
|
|
209
|
+
href: "https://dashboard.helius.dev",
|
|
210
|
+
target: "_blank",
|
|
211
|
+
rel: "noopener noreferrer",
|
|
212
|
+
style: {
|
|
213
|
+
background: "#E84125",
|
|
214
|
+
color: "#fff",
|
|
215
|
+
padding: "12px 24px",
|
|
216
|
+
borderRadius: "12px",
|
|
217
|
+
textDecoration: "none",
|
|
218
|
+
fontWeight: 500,
|
|
219
|
+
fontSize: "14px"
|
|
220
|
+
},
|
|
221
|
+
children: "Upgrade Plan"
|
|
222
|
+
}
|
|
223
|
+
)
|
|
224
|
+
] }) });
|
|
225
|
+
}
|
|
226
|
+
const effectiveBootstrap = bootstrap ?? {
|
|
227
|
+
organizationId: "",
|
|
228
|
+
authProxyConfigId: ""
|
|
229
|
+
};
|
|
230
|
+
const turnkeyConfig = buildTurnkeyConfig(config, effectiveBootstrap);
|
|
231
|
+
const providerKey = bootstrap ? `ready:${bootstrap.organizationId}:${bootstrap.authProxyConfigId}` : bootstrapError ? "error" : "pending";
|
|
232
|
+
return /* @__PURE__ */ jsx(HeliusWalletContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
|
|
233
|
+
TurnkeyProvider,
|
|
234
|
+
{
|
|
235
|
+
config: turnkeyConfig,
|
|
236
|
+
callbacks: {
|
|
237
|
+
onError: (error) => {
|
|
238
|
+
const msg = error.message?.toLowerCase() ?? "";
|
|
239
|
+
if (msg.includes("cancel") || msg.includes("abort") || msg.includes("dismissed")) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!bootstrap) return;
|
|
243
|
+
config.onError?.(new Error(error.message));
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
children
|
|
247
|
+
},
|
|
248
|
+
providerKey
|
|
249
|
+
) });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/core/rpc-url.ts
|
|
253
|
+
function resolveRpcUrl(secureRpcUrl, cluster, rpcProxyPath, origin) {
|
|
254
|
+
const secure = secureRpcUrl?.[cluster];
|
|
255
|
+
if (secure) return secure;
|
|
256
|
+
return `${origin}${rpcProxyPath}?cluster=${cluster}`;
|
|
257
|
+
}
|
|
258
|
+
function canSendDirect(secureRpcUrl, cluster) {
|
|
259
|
+
return Boolean(secureRpcUrl?.[cluster]);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/core/useHeliusWallet.ts
|
|
263
|
+
function deriveStatus(clientState, authState) {
|
|
264
|
+
if (clientState === void 0 || clientState === ClientState.Loading)
|
|
265
|
+
return "loading";
|
|
266
|
+
if (authState === AuthState.Authenticated) return "authenticated";
|
|
267
|
+
return "unauthenticated";
|
|
268
|
+
}
|
|
269
|
+
function useHeliusWallet() {
|
|
270
|
+
const {
|
|
271
|
+
handleLogin,
|
|
272
|
+
logout: turnkeyLogout,
|
|
273
|
+
authState,
|
|
274
|
+
clientState,
|
|
275
|
+
user: turnkeyUser,
|
|
276
|
+
session,
|
|
277
|
+
wallets,
|
|
278
|
+
signTransaction: turnkeySignTransaction,
|
|
279
|
+
handleSignMessage,
|
|
280
|
+
handleExportWallet
|
|
281
|
+
} = useTurnkey();
|
|
282
|
+
const { rpcProxyPath, secureRpcUrl, cluster, setCluster, apiKey, projectId, planTier } = useContext(HeliusWalletContext);
|
|
283
|
+
const rpcUrl = useMemo(() => {
|
|
284
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "http://localhost";
|
|
285
|
+
return resolveRpcUrl(secureRpcUrl, cluster, rpcProxyPath, origin);
|
|
286
|
+
}, [secureRpcUrl, rpcProxyPath, cluster]);
|
|
287
|
+
const connection = useMemo(() => new Connection(rpcUrl), [rpcUrl]);
|
|
288
|
+
const status = deriveStatus(clientState, authState);
|
|
289
|
+
const address = wallets?.[0]?.accounts?.[0]?.address ?? null;
|
|
290
|
+
const user = turnkeyUser ? {
|
|
291
|
+
userId: turnkeyUser.userId,
|
|
292
|
+
username: turnkeyUser.userName,
|
|
293
|
+
email: turnkeyUser.userEmail ?? void 0,
|
|
294
|
+
// session.organizationId is the end-user's sub-org id under the
|
|
295
|
+
// configured auth proxy. Falls back to "" only in edge cases where
|
|
296
|
+
// useTurnkey returns a user before the session is fully populated.
|
|
297
|
+
subOrgId: session?.organizationId ?? "",
|
|
298
|
+
walletId: wallets?.[0]?.walletId ?? null
|
|
299
|
+
} : null;
|
|
300
|
+
const login = useCallback(() => handleLogin(), [handleLogin]);
|
|
301
|
+
const logout = useCallback(() => turnkeyLogout(), [turnkeyLogout]);
|
|
302
|
+
const signTransaction = useCallback(
|
|
303
|
+
async (transaction) => {
|
|
304
|
+
const walletAccount = wallets?.[0]?.accounts?.[0];
|
|
305
|
+
if (!walletAccount) throw new Error("No wallet available");
|
|
306
|
+
const hexEncoded = Buffer.from(transaction).toString("hex");
|
|
307
|
+
const signedHex = await turnkeySignTransaction({
|
|
308
|
+
walletAccount,
|
|
309
|
+
unsignedTransaction: hexEncoded,
|
|
310
|
+
transactionType: "TRANSACTION_TYPE_SOLANA"
|
|
311
|
+
});
|
|
312
|
+
return Buffer.from(signedHex, "hex");
|
|
313
|
+
},
|
|
314
|
+
[wallets, turnkeySignTransaction]
|
|
315
|
+
);
|
|
316
|
+
const signAndSendTransaction = useCallback(
|
|
317
|
+
async (transaction) => {
|
|
318
|
+
const signed = await signTransaction(transaction);
|
|
319
|
+
if (canSendDirect(secureRpcUrl, cluster)) {
|
|
320
|
+
return connection.sendRawTransaction(signed, { skipPreflight: true });
|
|
321
|
+
}
|
|
322
|
+
const base64Tx = Buffer.from(signed).toString("base64");
|
|
323
|
+
const headers = {
|
|
324
|
+
"Content-Type": "application/json"
|
|
325
|
+
};
|
|
326
|
+
if (apiKey) headers["x-helius-api-key"] = apiKey;
|
|
327
|
+
const res = await fetch("/api/helius/send", {
|
|
328
|
+
method: "POST",
|
|
329
|
+
headers,
|
|
330
|
+
body: JSON.stringify({ transaction: base64Tx, cluster, address })
|
|
331
|
+
});
|
|
332
|
+
const data = await res.json();
|
|
333
|
+
if (data.error) throw new Error(data.error);
|
|
334
|
+
return data.signature;
|
|
335
|
+
},
|
|
336
|
+
[signTransaction, cluster, apiKey, address, secureRpcUrl, connection]
|
|
337
|
+
);
|
|
338
|
+
const signMessage = useCallback(
|
|
339
|
+
async (message) => {
|
|
340
|
+
const walletAccount = wallets?.[0]?.accounts?.[0];
|
|
341
|
+
if (!walletAccount) throw new Error("No wallet available");
|
|
342
|
+
const result = await handleSignMessage({
|
|
343
|
+
message,
|
|
344
|
+
walletAccount
|
|
345
|
+
});
|
|
346
|
+
const rBytes = Buffer.from(result.r, "hex");
|
|
347
|
+
const sBytes = Buffer.from(result.s, "hex");
|
|
348
|
+
const sigBytes = Buffer.concat([rBytes, sBytes]);
|
|
349
|
+
return sigBytes.toString("hex");
|
|
350
|
+
},
|
|
351
|
+
[wallets, handleSignMessage]
|
|
352
|
+
);
|
|
353
|
+
const exportWallet = useCallback(async () => {
|
|
354
|
+
const wallet = wallets?.[0];
|
|
355
|
+
if (!wallet) throw new Error("No wallet available");
|
|
356
|
+
await handleExportWallet({ walletId: wallet.walletId });
|
|
357
|
+
}, [wallets, handleExportWallet]);
|
|
358
|
+
const getTransactions = useCallback(
|
|
359
|
+
async (options) => {
|
|
360
|
+
if (!address) return [];
|
|
361
|
+
const limit = options?.limit ?? 10;
|
|
362
|
+
const headers = {};
|
|
363
|
+
if (apiKey) headers["x-helius-api-key"] = apiKey;
|
|
364
|
+
const directMode = canSendDirect(secureRpcUrl, cluster);
|
|
365
|
+
const historyUnavailable = "getTransactions needs the Helius route handler (helius-wallet-kit/next); it isn't available in direct/secure-URL mode.";
|
|
366
|
+
let res;
|
|
367
|
+
try {
|
|
368
|
+
res = await fetch(
|
|
369
|
+
`/api/helius/transactions?address=${encodeURIComponent(address)}&cluster=${cluster}&limit=${limit}`,
|
|
370
|
+
{ headers }
|
|
371
|
+
);
|
|
372
|
+
} catch (err) {
|
|
373
|
+
throw directMode ? new Error(historyUnavailable) : err;
|
|
374
|
+
}
|
|
375
|
+
if (res.status === 404 && directMode) throw new Error(historyUnavailable);
|
|
376
|
+
if (!res.ok) {
|
|
377
|
+
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
378
|
+
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
379
|
+
}
|
|
380
|
+
const data = await res.json();
|
|
381
|
+
return Array.isArray(data) ? data : data.transactions ?? [];
|
|
382
|
+
},
|
|
383
|
+
[address, cluster, apiKey]
|
|
384
|
+
);
|
|
385
|
+
const getPriorityFee = useCallback(
|
|
386
|
+
async (accountKeys, priorityLevel = "Medium") => {
|
|
387
|
+
const res = await fetch(rpcUrl, {
|
|
388
|
+
method: "POST",
|
|
389
|
+
headers: { "Content-Type": "application/json" },
|
|
390
|
+
body: JSON.stringify({
|
|
391
|
+
jsonrpc: "2.0",
|
|
392
|
+
id: "helius-wallet-kit-priority-fee",
|
|
393
|
+
method: "getPriorityFeeEstimate",
|
|
394
|
+
params: [{ accountKeys, options: { priorityLevel } }]
|
|
395
|
+
})
|
|
396
|
+
});
|
|
397
|
+
const data = await res.json();
|
|
398
|
+
if (data.error) throw new Error(data.error.message ?? "RPC error");
|
|
399
|
+
return data.result?.priorityFeeEstimate ?? 0;
|
|
400
|
+
},
|
|
401
|
+
[rpcUrl]
|
|
402
|
+
);
|
|
403
|
+
const getPriorityFeeLevels = useCallback(
|
|
404
|
+
async (accountKeys) => {
|
|
405
|
+
const res = await fetch(rpcUrl, {
|
|
406
|
+
method: "POST",
|
|
407
|
+
headers: { "Content-Type": "application/json" },
|
|
408
|
+
body: JSON.stringify({
|
|
409
|
+
jsonrpc: "2.0",
|
|
410
|
+
id: "helius-wallet-kit-priority-fee-levels",
|
|
411
|
+
method: "getPriorityFeeEstimate",
|
|
412
|
+
params: [
|
|
413
|
+
{ accountKeys, options: { includeAllPriorityFeeLevels: true } }
|
|
414
|
+
]
|
|
415
|
+
})
|
|
416
|
+
});
|
|
417
|
+
const data = await res.json();
|
|
418
|
+
if (data.error) throw new Error(data.error.message ?? "RPC error");
|
|
419
|
+
const levels = data.result?.priorityFeeLevels ?? {};
|
|
420
|
+
return {
|
|
421
|
+
min: levels.min ?? 0,
|
|
422
|
+
low: levels.low ?? 0,
|
|
423
|
+
medium: levels.medium ?? 0,
|
|
424
|
+
high: levels.high ?? 0,
|
|
425
|
+
veryHigh: levels.veryHigh ?? 0,
|
|
426
|
+
unsafeMax: levels.unsafeMax ?? 0
|
|
427
|
+
};
|
|
428
|
+
},
|
|
429
|
+
[rpcUrl]
|
|
430
|
+
);
|
|
431
|
+
return {
|
|
432
|
+
address,
|
|
433
|
+
status,
|
|
434
|
+
user,
|
|
435
|
+
login,
|
|
436
|
+
logout,
|
|
437
|
+
signTransaction,
|
|
438
|
+
signAndSendTransaction,
|
|
439
|
+
signMessage,
|
|
440
|
+
exportWallet,
|
|
441
|
+
getTransactions,
|
|
442
|
+
getPriorityFee,
|
|
443
|
+
getPriorityFeeLevels,
|
|
444
|
+
connection,
|
|
445
|
+
rpcUrl,
|
|
446
|
+
cluster,
|
|
447
|
+
setCluster,
|
|
448
|
+
apiKey,
|
|
449
|
+
projectId,
|
|
450
|
+
planTier
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export { HeliusWalletContext, HeliusWalletProvider, isWaasEligible, useHeliusWallet };
|
|
455
|
+
//# sourceMappingURL=index.js.map
|
|
456
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts","../src/core/constants.ts","../src/core/turnkey-config.ts","../src/core/waas-config.ts","../src/core/HeliusWalletProvider.tsx","../src/core/rpc-url.ts","../src/core/useHeliusWallet.ts"],"names":["useMemo"],"mappings":"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","file":"index.js","sourcesContent":["import type { Connection } from \"@solana/web3.js\";\n\nexport interface HeliusWalletConfig {\n apiKey?: string;\n /**\n * Helius project id. Required — stamped as the Turnkey sub-org name on every\n * end-user wallet so signatures can be attributed to your project for usage\n * billing (resolved server-side via getSubOrgIds by name).\n */\n projectId: string;\n planTier?: HeliusPlan;\n rpcProxyPath?: string;\n /**\n * Base URL for the Helius WaaS control-plane API (the `/waas/config`\n * bootstrap). Defaults to Helius production; override for local/staging.\n */\n apiBaseUrl?: string;\n /**\n * Per-cluster Helius Secure RPC URL (key-less, safe in the browser). When set\n * for the active cluster, the wallet's Solana connection, priority-fee lookups,\n * and transaction sends go directly to it — no route handler needed. Sends use\n * standard RPC (not Helius Sender), so they forgo Sender's optimized landing;\n * use proxy mode for best mainnet landing. Falls back to the same-origin\n * `rpcProxyPath` proxy when unset. Pass a stable reference (memoize it) to\n * avoid unnecessary re-renders.\n */\n secureRpcUrl?: Partial<Record<Cluster, string>>;\n cluster?: Cluster;\n authMethods?: {\n passkey?: boolean;\n email?: boolean;\n sms?: boolean;\n wallet?: boolean;\n google?: boolean;\n apple?: boolean;\n discord?: boolean;\n x?: boolean;\n };\n theme?: {\n darkMode?: boolean;\n primaryColor?: string;\n borderRadius?: string;\n logoLight?: string;\n logoDark?: string;\n };\n onError?: (error: Error) => void;\n}\n\nexport type Cluster = \"devnet\" | \"mainnet-beta\";\n\nexport type HeliusPlan = \"basic\" | \"developer\" | \"business\" | \"professional\";\n\nconst WAAS_ALLOWED_PLANS: HeliusPlan[] = [\"business\", \"professional\"];\n\nexport function isWaasEligible(plan: HeliusPlan): boolean {\n return WAAS_ALLOWED_PLANS.includes(plan);\n}\n\nexport type AuthStatus = \"loading\" | \"unauthenticated\" | \"authenticated\";\n\nexport type PriorityLevel =\n | \"Min\"\n | \"Low\"\n | \"Medium\"\n | \"High\"\n | \"VeryHigh\"\n | \"UnsafeMax\";\n\n/**\n * All six priority-fee levels (in micro-lamports per compute unit) returned by\n * Helius's `getPriorityFeeEstimate` when called with\n * `includeAllPriorityFeeLevels: true`. The lowercase keys match the upstream\n * RPC response shape — intentionally distinct from the PascalCase\n * `PriorityLevel` union which is what the RPC accepts as input.\n */\nexport interface PriorityFeeLevels {\n min: number;\n low: number;\n medium: number;\n high: number;\n veryHigh: number;\n unsafeMax: number;\n}\n\n/**\n * One row of Helius Enhanced Transactions API response. Fields beyond the\n * common set are passed through verbatim via the index signature — Helius's\n * parsed-tx schema is evolving, and consumers rendering UI off specific fields\n * should cast at their call site rather than wait for us to widen this type.\n */\nexport interface EnhancedTransaction {\n signature: string;\n slot: number;\n timestamp: number;\n type: string;\n source: string;\n fee: number;\n feePayer: string;\n description?: string;\n nativeTransfers?: Array<{\n fromUserAccount: string;\n toUserAccount: string;\n amount: number;\n }>;\n tokenTransfers?: Array<{\n fromUserAccount: string;\n toUserAccount: string;\n mint: string;\n tokenAmount: number;\n }>;\n [key: string]: unknown;\n}\n\nexport interface HeliusWallet {\n address: string | null;\n status: AuthStatus;\n user: {\n userId: string;\n username: string;\n email?: string;\n /**\n * Turnkey sub-organization id for this end-user. Each authenticated user\n * gets their own sub-org, fully isolated. Useful for server-side audit\n * trails and admin observability. Always defined when status is\n * \"authenticated\".\n */\n subOrgId: string;\n /**\n * Turnkey wallet id (the wallet container holding this user's accounts).\n * May be undefined for a brief window post-signup before the wallet\n * provisioning completes.\n */\n walletId: string | null;\n } | null;\n\n login: () => Promise<void>;\n logout: () => Promise<void>;\n\n signTransaction: (transaction: Uint8Array | Buffer) => Promise<Buffer>;\n signAndSendTransaction: (transaction: Uint8Array | Buffer) => Promise<string>;\n signMessage: (message: string) => Promise<string>;\n\n exportWallet: () => Promise<void>;\n\n /**\n * Fetch parsed transaction history for the connected wallet via Helius\n * Enhanced Transactions API. Returns empty array if no wallet is connected.\n */\n getTransactions: (options?: { limit?: number }) => Promise<EnhancedTransaction[]>;\n\n /**\n * Estimate priority fee in micro-lamports for a transaction touching the\n * given writable accounts. `priorityLevel` defaults to \"Medium\". Uses\n * Helius's `getPriorityFeeEstimate` RPC method.\n */\n getPriorityFee: (\n accountKeys: string[],\n priorityLevel?: PriorityLevel\n ) => Promise<number>;\n\n /**\n * Like `getPriorityFee`, but returns every level Helius reports\n * (min/low/medium/high/veryHigh/unsafeMax). Use when rendering a fee\n * picker; otherwise prefer `getPriorityFee` for the single-value case.\n */\n getPriorityFeeLevels: (accountKeys: string[]) => Promise<PriorityFeeLevels>;\n\n connection: Connection;\n rpcUrl: string;\n\n cluster: Cluster;\n setCluster: (cluster: Cluster) => void;\n\n apiKey: string | null;\n projectId: string | null;\n planTier: HeliusPlan | null;\n}\n","export const SOLANA_WALLET_ACCOUNT_CONFIG = {\n curve: \"CURVE_ED25519\" as const,\n pathFormat: \"PATH_FORMAT_BIP32\" as const,\n path: \"m/44'/501'/0'/0'\",\n addressFormat: \"ADDRESS_FORMAT_SOLANA\" as const,\n};\n\nexport const DEFAULT_THEME = {\n primaryColor: \"#E84125\",\n borderRadius: \"12px\",\n logoLight: \"/Helius-Horizontal-Logo-Black.svg\",\n logoDark: \"/Helius-Horizontal-Logo-White.svg\",\n darkMode: true,\n};\n\n// Aligned with the @helius-labs/wallet-kit/next catch-all route structure —\n// consumers mount a single [...path] handler at /api/helius/, and the RPC\n// proxy lives under that tree alongside /send, /transactions, /plan, and\n// /waas/config. Previously `/api/rpc` (PoC-era top-level route); unified\n// here at M3 (2026-04-23) so one catch-all covers everything.\nexport const DEFAULT_RPC_PROXY_PATH = \"/api/helius/rpc\";\n\n// Helius WaaS control-plane API. The provider fetches its Turnkey bootstrap\n// (org id + auth-proxy config id) directly from here with the project's Helius\n// API key — no route handler required. The endpoint is origin-locked server-side\n// by the key's allowed-domains ACL.\nexport const DEFAULT_HELIUS_API_URL = \"https://dev-api.helius.xyz/v0\";\n","// Pure builder for the Turnkey provider config. Kept separate from\n// HeliusWalletProvider.tsx so it can be unit-tested without pulling in\n// @turnkey/react-wallet-kit at runtime — the Turnkey type below is a\n// type-only import (fully erased), so importing this module loads no\n// browser/ESM Turnkey code.\nimport type { TurnkeyProviderConfig } from \"./internal/turnkey-adapter\";\nimport type { HeliusWalletConfig } from \"./types\";\nimport { SOLANA_WALLET_ACCOUNT_CONFIG, DEFAULT_THEME } from \"./constants\";\n\nexport interface WaasBootstrap {\n organizationId: string;\n authProxyConfigId: string;\n}\n\nexport function buildTurnkeyConfig(\n config: HeliusWalletConfig,\n bootstrap: WaasBootstrap\n): TurnkeyProviderConfig {\n const theme = { ...DEFAULT_THEME, ...config.theme };\n const walletAccounts = [SOLANA_WALLET_ACCOUNT_CONFIG];\n const walletConfig = {\n walletName: \"Solana Wallet\",\n walletAccounts,\n };\n\n return {\n organizationId: bootstrap.organizationId,\n authProxyConfigId: bootstrap.authProxyConfigId,\n\n auth: {\n // subOrgName = projectId stamps every end-user sub-org with the project,\n // so signatures can be attributed back to it for usage billing (looked up\n // via getSubOrgIds by name). Without it, Turnkey defaults the name to the\n // site hostname and attribution is lost.\n createSuborgParams: {\n passkeyAuth: {\n userName: \"Default User\",\n subOrgName: config.projectId,\n passkeyName: \"Helius Wallet\",\n customWallet: walletConfig,\n },\n emailOtpAuth: {\n userName: \"Email User\",\n subOrgName: config.projectId,\n customWallet: walletConfig,\n },\n walletAuth: {\n userName: \"Wallet User\",\n subOrgName: config.projectId,\n customWallet: walletConfig,\n },\n oauth: {\n userName: \"OAuth User\",\n subOrgName: config.projectId,\n customWallet: walletConfig,\n },\n },\n methods: config.authMethods\n ? {\n passkeyAuthEnabled: config.authMethods.passkey ?? true,\n emailOtpAuthEnabled: config.authMethods.email ?? true,\n smsOtpAuthEnabled: config.authMethods.sms ?? false,\n walletAuthEnabled: config.authMethods.wallet ?? false,\n googleOauthEnabled: config.authMethods.google ?? false,\n appleOauthEnabled: config.authMethods.apple ?? false,\n discordOauthEnabled: config.authMethods.discord ?? false,\n xOauthEnabled: config.authMethods.x ?? false,\n }\n : undefined,\n autoRefreshSession: true,\n },\n\n ui: {\n logoLight: theme.logoLight,\n logoDark: theme.logoDark,\n darkMode: theme.darkMode,\n borderRadius: theme.borderRadius,\n colors: {\n light: {\n primary: theme.primaryColor,\n primaryText: \"#FFFFFF\",\n button: \"#FFFFFF\",\n modalBackground: \"#FFFFFF\",\n modalText: \"#090909\",\n },\n dark: {\n primary: theme.primaryColor,\n primaryText: \"#FFFFFF\",\n button: \"#222222\",\n modalBackground: \"#090909\",\n modalText: \"#DBDBDB\",\n iconText: \"#999999\",\n iconBackground: \"#333333\",\n },\n },\n },\n };\n}\n","// Fetches the Turnkey bootstrap (org id + auth-proxy config id) directly from\n// the Helius WaaS control-plane API. No route handler needed: the request is\n// authenticated by the project's Helius API key and origin-locked server-side by\n// the key's allowed-domains ACL. Kept separate from the provider so it can be\n// unit-tested with a mocked fetch.\nimport type { WaasBootstrap } from \"./turnkey-config\";\n\nexport interface WaasBootstrapResult {\n bootstrap?: WaasBootstrap;\n error?: { code?: string; message: string };\n}\n\nexport async function fetchWaasBootstrap(\n apiBaseUrl: string,\n apiKey: string,\n): Promise<WaasBootstrapResult> {\n try {\n const res = await fetch(`${apiBaseUrl}/waas/config`, {\n headers: { \"x-api-key\": apiKey },\n });\n const data = await res.json().catch(() => ({}));\n\n if (res.ok && data.organizationId && data.authProxyConfigId) {\n return {\n bootstrap: {\n organizationId: data.organizationId,\n authProxyConfigId: data.authProxyConfigId,\n },\n };\n }\n\n return {\n error: {\n code: data.code,\n message: data.message ?? `WaaS config request failed (${res.status})`,\n },\n };\n } catch (err) {\n return {\n error: { message: err instanceof Error ? err.message : \"Unknown error\" },\n };\n }\n}\n","\"use client\";\n\nimport React, { createContext, useState, useMemo, useEffect } from \"react\";\nimport { TurnkeyProvider } from \"./internal/turnkey-adapter\";\nimport type { HeliusWalletConfig, Cluster, HeliusPlan } from \"./types\";\nimport { isWaasEligible } from \"./types\";\nimport { DEFAULT_RPC_PROXY_PATH, DEFAULT_HELIUS_API_URL } from \"./constants\";\nimport { buildTurnkeyConfig, type WaasBootstrap } from \"./turnkey-config\";\nimport { fetchWaasBootstrap } from \"./waas-config\";\n\nexport const HeliusWalletContext = createContext<{\n rpcProxyPath: string;\n secureRpcUrl?: Partial<Record<Cluster, string>>;\n cluster: Cluster;\n setCluster: (cluster: Cluster) => void;\n apiKey: string | null;\n projectId: string | null;\n planTier: HeliusPlan | null;\n waasEligible: boolean;\n}>({\n rpcProxyPath: DEFAULT_RPC_PROXY_PATH,\n secureRpcUrl: undefined,\n cluster: \"devnet\",\n setCluster: () => {},\n apiKey: null,\n projectId: null,\n planTier: null,\n waasEligible: false,\n});\n\nexport function HeliusWalletProvider({\n config,\n children,\n}: {\n config: HeliusWalletConfig;\n children: React.ReactNode;\n}) {\n const rpcProxyPath = config.rpcProxyPath ?? DEFAULT_RPC_PROXY_PATH;\n // Stabilize by the actual cluster URLs so an inlined config object doesn't\n // churn the context value (and the memoized connection) every render.\n const secureRpcUrl = useMemo(\n () => config.secureRpcUrl,\n [config.secureRpcUrl?.[\"mainnet-beta\"], config.secureRpcUrl?.devnet],\n );\n const apiBaseUrl = config.apiBaseUrl ?? DEFAULT_HELIUS_API_URL;\n const [cluster, setCluster] = useState<Cluster>(config.cluster ?? \"devnet\");\n const apiKey = config.apiKey ?? null;\n const projectId = config.projectId ?? null;\n const planTier = config.planTier ?? null;\n const [bootstrap, setBootstrap] = useState<WaasBootstrap | null>(null);\n const [bootstrapError, setBootstrapError] = useState<{ code?: string; message: string } | null>(null);\n const waasEligible = planTier ? isWaasEligible(planTier) : false;\n\n // Fetch the Turnkey bootstrap (org id + auth-proxy config id) directly from\n // the Helius WaaS API with the project's API key. No route handler needed —\n // the endpoint is origin-locked server-side by the key's allowed-domains ACL.\n // Plan eligibility is enforced server-side too (a PLAN_INELIGIBLE error here),\n // so there's no separate client-side plan lookup.\n useEffect(() => {\n if (!apiKey) return;\n\n let cancelled = false;\n (async () => {\n const result = await fetchWaasBootstrap(apiBaseUrl, apiKey);\n if (cancelled) return;\n if (result.bootstrap) {\n setBootstrap(result.bootstrap);\n } else if (result.error) {\n setBootstrapError(result.error);\n }\n })();\n\n return () => {\n cancelled = true;\n };\n }, [apiKey, apiBaseUrl]);\n\n const contextValue = useMemo(\n () => ({ rpcProxyPath, secureRpcUrl, cluster, setCluster, apiKey, projectId, planTier, waasEligible }),\n [rpcProxyPath, secureRpcUrl, cluster, apiKey, projectId, planTier, waasEligible]\n );\n\n // Gate: if planTier is provided but not eligible, show upgrade prompt\n if (planTier && !waasEligible) {\n return (\n <HeliusWalletContext.Provider value={contextValue}>\n <div style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n gap: \"16px\",\n padding: \"24px\",\n fontFamily: \"system-ui, sans-serif\",\n }}>\n <img src=\"/Helius-Icon.svg\" alt=\"Helius\" style={{ width: 48, height: 48 }} />\n <h1 style={{ fontSize: \"24px\", fontWeight: 700, margin: 0 }}>\n Helius WaaS\n </h1>\n <p style={{ color: \"#999\", margin: 0, textAlign: \"center\", maxWidth: 400 }}>\n Wallet-as-a-Service requires a <strong>Business</strong> or <strong>Professional</strong> plan.\n Your current plan: <strong>{planTier}</strong>.\n </p>\n <a\n href=\"https://dashboard.helius.dev\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{\n background: \"#E84125\",\n color: \"#fff\",\n padding: \"12px 24px\",\n borderRadius: \"12px\",\n textDecoration: \"none\",\n fontWeight: 500,\n fontSize: \"14px\",\n }}\n >\n Upgrade Plan\n </a>\n </div>\n </HeliusWalletContext.Provider>\n );\n }\n\n // TurnkeyProvider must ALWAYS be in the tree — useHeliusWallet calls\n // useTurnkey() unconditionally, and it throws if no TurnkeyProvider is\n // mounted. During SSR and the initial client render, bootstrap hasn't\n // resolved yet; we mount with placeholder identifiers and re-key the\n // provider so React remounts it with the real config once bootstrap lands.\n //\n // Placeholder identifiers put Turnkey's internal client into an error\n // state that useHeliusWallet surfaces as `status: \"loading\"` — no user\n // interaction is possible until bootstrap succeeds.\n const effectiveBootstrap: WaasBootstrap = bootstrap ?? {\n organizationId: \"\",\n authProxyConfigId: \"\",\n };\n\n const turnkeyConfig = buildTurnkeyConfig(config, effectiveBootstrap);\n\n // Re-key on real bootstrap → forces TurnkeyProvider to remount with the\n // actual Turnkey config. Without this, Turnkey memoizes initial props and\n // never picks up the real identifiers when they arrive post-useEffect.\n const providerKey = bootstrap\n ? `ready:${bootstrap.organizationId}:${bootstrap.authProxyConfigId}`\n : bootstrapError\n ? \"error\"\n : \"pending\";\n\n return (\n <HeliusWalletContext.Provider value={contextValue}>\n <TurnkeyProvider\n key={providerKey}\n config={turnkeyConfig}\n callbacks={{\n onError: (error) => {\n // Silently ignore user cancellations (dismissed passkey prompt, closed modal, etc.)\n const msg = error.message?.toLowerCase() ?? \"\";\n if (msg.includes(\"cancel\") || msg.includes(\"abort\") || msg.includes(\"dismissed\")) {\n return;\n }\n // Also silently ignore errors during the bootstrap-pending window —\n // Turnkey will throw against the placeholder identifiers, but that's\n // expected and transient; real errors surface after remount.\n if (!bootstrap) return;\n config.onError?.(new Error(error.message));\n },\n }}\n >\n {children}\n </TurnkeyProvider>\n </HeliusWalletContext.Provider>\n );\n}\n","import type { Cluster } from \"./types\";\n\n// Resolves the RPC endpoint the wallet's Solana connection uses. Prefers a\n// configured Secure RPC URL for the active cluster (key-less, safe to call\n// directly from the browser); falls back to the same-origin proxy path when\n// none is set for that cluster.\nexport function resolveRpcUrl(\n secureRpcUrl: Partial<Record<Cluster, string>> | undefined,\n cluster: Cluster,\n rpcProxyPath: string,\n origin: string,\n): string {\n const secure = secureRpcUrl?.[cluster];\n if (secure) return secure;\n return `${origin}${rpcProxyPath}?cluster=${cluster}`;\n}\n\n// True when sends can go directly through the secure RPC connection for the\n// active cluster (no Sender proxy needed).\nexport function canSendDirect(\n secureRpcUrl: Partial<Record<Cluster, string>> | undefined,\n cluster: Cluster,\n): boolean {\n return Boolean(secureRpcUrl?.[cluster]);\n}\n","\"use client\";\n\nimport { useContext, useMemo, useCallback } from \"react\";\nimport { useTurnkey, AuthState, ClientState } from \"./internal/turnkey-adapter\";\nimport { Connection } from \"@solana/web3.js\";\nimport { HeliusWalletContext } from \"./HeliusWalletProvider\";\nimport { resolveRpcUrl, canSendDirect } from \"./rpc-url\";\nimport type {\n AuthStatus,\n HeliusWallet,\n EnhancedTransaction,\n PriorityFeeLevels,\n PriorityLevel,\n} from \"./types\";\n\nfunction deriveStatus(\n clientState: typeof ClientState[keyof typeof ClientState] | undefined,\n authState: typeof AuthState[keyof typeof AuthState]\n): AuthStatus {\n if (clientState === undefined || clientState === ClientState.Loading)\n return \"loading\";\n if (authState === AuthState.Authenticated) return \"authenticated\";\n return \"unauthenticated\";\n}\n\nexport function useHeliusWallet(): HeliusWallet {\n const {\n handleLogin,\n logout: turnkeyLogout,\n authState,\n clientState,\n user: turnkeyUser,\n session,\n wallets,\n signTransaction: turnkeySignTransaction,\n handleSignMessage,\n handleExportWallet,\n } = useTurnkey();\n\n const { rpcProxyPath, secureRpcUrl, cluster, setCluster, apiKey, projectId, planTier } =\n useContext(HeliusWalletContext);\n\n const rpcUrl = useMemo(() => {\n const origin =\n typeof window !== \"undefined\"\n ? window.location.origin\n : \"http://localhost\";\n return resolveRpcUrl(secureRpcUrl, cluster, rpcProxyPath, origin);\n }, [secureRpcUrl, rpcProxyPath, cluster]);\n\n const connection = useMemo(() => new Connection(rpcUrl), [rpcUrl]);\n\n const status = deriveStatus(clientState, authState);\n\n const address = wallets?.[0]?.accounts?.[0]?.address ?? null;\n\n const user = turnkeyUser\n ? {\n userId: turnkeyUser.userId,\n username: turnkeyUser.userName,\n email: turnkeyUser.userEmail ?? undefined,\n // session.organizationId is the end-user's sub-org id under the\n // configured auth proxy. Falls back to \"\" only in edge cases where\n // useTurnkey returns a user before the session is fully populated.\n subOrgId: session?.organizationId ?? \"\",\n walletId: wallets?.[0]?.walletId ?? null,\n }\n : null;\n\n const login = useCallback(() => handleLogin(), [handleLogin]);\n\n const logout = useCallback(() => turnkeyLogout(), [turnkeyLogout]);\n\n const signTransaction = useCallback(\n async (transaction: Uint8Array | Buffer): Promise<Buffer> => {\n const walletAccount = wallets?.[0]?.accounts?.[0];\n if (!walletAccount) throw new Error(\"No wallet available\");\n\n const hexEncoded = Buffer.from(transaction).toString(\"hex\");\n const signedHex = await turnkeySignTransaction({\n walletAccount,\n unsignedTransaction: hexEncoded,\n transactionType: \"TRANSACTION_TYPE_SOLANA\",\n });\n return Buffer.from(signedHex, \"hex\");\n },\n [wallets, turnkeySignTransaction]\n );\n\n const signAndSendTransaction = useCallback(\n async (transaction: Uint8Array | Buffer): Promise<string> => {\n const signed = await signTransaction(transaction);\n\n // Direct mode: send straight through the secure RPC connection — no route\n // handler or exposed key needed. This uses standard RPC send, NOT Helius\n // Sender, so it forgoes Sender's optimized landing (Jito dual-routing);\n // use proxy mode for best mainnet landing. `skipPreflight: true` matches\n // the prior Sender contract and avoids a second call on the rate-limited\n // secure URL. The tx goes through the connection it was signed against.\n if (canSendDirect(secureRpcUrl, cluster)) {\n return connection.sendRawTransaction(signed, { skipPreflight: true });\n }\n\n // Proxy mode: route through Helius Sender for optimized landing.\n const base64Tx = Buffer.from(signed).toString(\"base64\");\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (apiKey) headers[\"x-helius-api-key\"] = apiKey;\n\n const res = await fetch(\"/api/helius/send\", {\n method: \"POST\",\n headers,\n body: JSON.stringify({ transaction: base64Tx, cluster, address }),\n });\n\n const data = await res.json();\n if (data.error) throw new Error(data.error);\n return data.signature;\n },\n [signTransaction, cluster, apiKey, address, secureRpcUrl, connection]\n );\n\n const signMessage = useCallback(\n async (message: string): Promise<string> => {\n const walletAccount = wallets?.[0]?.accounts?.[0];\n if (!walletAccount) throw new Error(\"No wallet available\");\n\n const result = await handleSignMessage({\n message,\n walletAccount,\n });\n\n // Turnkey returns r, s as hex strings for Ed25519.\n // Concatenate r + s to form the 64-byte signature.\n const rBytes = Buffer.from(result.r, \"hex\");\n const sBytes = Buffer.from(result.s, \"hex\");\n const sigBytes = Buffer.concat([rBytes, sBytes]);\n\n // Return as hex string (the API route handles base58 encoding).\n return sigBytes.toString(\"hex\");\n },\n [wallets, handleSignMessage]\n );\n\n const exportWallet = useCallback(async (): Promise<void> => {\n const wallet = wallets?.[0];\n if (!wallet) throw new Error(\"No wallet available\");\n await handleExportWallet({ walletId: wallet.walletId });\n }, [wallets, handleExportWallet]);\n\n const getTransactions = useCallback(\n async (options?: { limit?: number }): Promise<EnhancedTransaction[]> => {\n if (!address) return [];\n const limit = options?.limit ?? 10;\n const headers: Record<string, string> = {};\n if (apiKey) headers[\"x-helius-api-key\"] = apiKey;\n\n // Enhanced-tx history has no secure-URL equivalent. In direct mode (this\n // cluster is served by a secure URL, so there's no route handler) surface\n // a clear error. In proxy mode, let real network/HTTP errors through\n // unchanged so they aren't masked by a misleading direct-mode message.\n const directMode = canSendDirect(secureRpcUrl, cluster);\n const historyUnavailable =\n \"getTransactions needs the Helius route handler (helius-wallet-kit/next); it isn't available in direct/secure-URL mode.\";\n let res: Response;\n try {\n res = await fetch(\n `/api/helius/transactions?address=${encodeURIComponent(address)}&cluster=${cluster}&limit=${limit}`,\n { headers }\n );\n } catch (err) {\n throw directMode ? new Error(historyUnavailable) : err;\n }\n if (res.status === 404 && directMode) throw new Error(historyUnavailable);\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));\n throw new Error(err.error ?? `HTTP ${res.status}`);\n }\n const data = await res.json();\n return Array.isArray(data) ? data : (data.transactions ?? []);\n },\n [address, cluster, apiKey]\n );\n\n const getPriorityFee = useCallback(\n async (\n accountKeys: string[],\n priorityLevel: PriorityLevel = \"Medium\"\n ): Promise<number> => {\n const res = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: \"helius-wallet-kit-priority-fee\",\n method: \"getPriorityFeeEstimate\",\n params: [{ accountKeys, options: { priorityLevel } }],\n }),\n });\n const data = await res.json();\n if (data.error) throw new Error(data.error.message ?? \"RPC error\");\n return data.result?.priorityFeeEstimate ?? 0;\n },\n [rpcUrl]\n );\n\n const getPriorityFeeLevels = useCallback(\n async (accountKeys: string[]): Promise<PriorityFeeLevels> => {\n const res = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: \"helius-wallet-kit-priority-fee-levels\",\n method: \"getPriorityFeeEstimate\",\n params: [\n { accountKeys, options: { includeAllPriorityFeeLevels: true } },\n ],\n }),\n });\n const data = await res.json();\n if (data.error) throw new Error(data.error.message ?? \"RPC error\");\n const levels = data.result?.priorityFeeLevels ?? {};\n return {\n min: levels.min ?? 0,\n low: levels.low ?? 0,\n medium: levels.medium ?? 0,\n high: levels.high ?? 0,\n veryHigh: levels.veryHigh ?? 0,\n unsafeMax: levels.unsafeMax ?? 0,\n };\n },\n [rpcUrl]\n );\n\n return {\n address,\n status,\n user,\n login,\n logout,\n signTransaction,\n signAndSendTransaction,\n signMessage,\n exportWallet,\n getTransactions,\n getPriorityFee,\n getPriorityFeeLevels,\n connection,\n rpcUrl,\n cluster,\n setCluster,\n apiKey,\n projectId,\n planTier,\n };\n}\n"]}
|