helius-wallet-kit SDK, and how to fix them.
Setup
The wallet modal is unstyled or looks broken
The SDK’s stylesheet isn’t loaded. Import it once in your root layout:app/layout.tsx
The hook values never change (stuck on loading)
useHeliusWallet() only works inside HeliusWalletProvider, and the provider must be a client component. Make sure the provider wraps your component tree from a file with "use client" at the top — see Setup.
[HeliusWalletKit] WaaS bootstrap failed (…) in the console
The provider couldn’t resolve your project from the API key. Check that:
NEXT_PUBLIC_HELIUS_API_KEYis set and valid.- The project is on a paid plan with embedded wallets enabled.
- If you domain-restricted the key, your current origin is in the allowed list — see Securing your key.
Sign-in
Users land on an “upgrade” screen instead of the wallet
Embedded wallets require a paid Helius plan. When the resolved plan is free, the provider renders an upgrade prompt (and the backend rejects the request server-side too). Upgrade the project in the dashboard.The wrong sign-in methods appear (e.g. Google shows, external wallet is missing)
Sign-in methods come from your project config in the dashboard under WaaS → Configuration. If a project has none configured, the modal falls back to an org-wide default. Set the methods you want in the dashboard, or passauthMethods to the provider config to override per environment — see Configure sign-in methods.
Passkey sign-in fails or says the passkey isn’t registered
Passkeys are bound to the domain and authenticator they were created on (a WebAuthn constraint, not a Helius one). A passkey or security key registered on another site or device won’t authenticate your app. Create the passkey on the domain you’re testing — note that a passkey made onlocalhost is bound to localhost and won’t carry over to your deployed domain.
Signing and sending
No wallet available when signing
You called a signing method before the embedded wallet finished provisioning. Gate signing on both status === "authenticated" and a non-null address:
… failed (HTTP 404). Set secureRpcUrl …, or mount the Helius route handler
You’re running in direct (Secure RPC) mode, and this call — a send or priority-fee request — needs the server route handler. Mount it at /api/helius/[...path] and set HELIUS_API_KEY:
app/api/helius/[...path]/route.ts
getTransactions needs the Helius route handler … it isn't available in direct/secure-URL mode
Transaction history is only available through the route handler. Add it as shown above.
getPriorityFeeEstimate is not available
Devnet doesn’t support priority-fee estimates — it’s a mainnet feature. Skip the lookup on devnet; sends still work without a priority fee.
A transaction doesn’t land on mainnet
Without the route handler, sends use standard RPC rather than Helius Sender, so they forgo Sender’s optimized landing. Mount the route handler for best mainnet landing. If a send fails outright, refresh the blockhash — a stalerecentBlockhash expires quickly.
Keys and access
RPC or API calls are rejected (401 / 403) after locking your key
Your domain-restricted key doesn’t include the origin you’re calling from. Add every origin you use — production, staging, preview deploys, andlocalhost for development — under RPC Access Control. See Securing your key.
Still stuck?
Discord
Ask the community and the Helius team.
Support
Contact Helius support.