I’m trying to get BOTH EVM and Solana wallet on server-side after user has done .login({ loginProvider: LOGIN_PROVIDER.JWT }).
But I only get the EVM key!
const { payload } = await jose.jwtVerify(…)
// payload.wallets only has secp256k1 wallets
===
When I do web3Auth.login({ curve:’ed25519’ }) I assume I would get Solana address in JWK? But I need both addresses!
===
How would I get, from the Web3Auth JWT, both of the wallet addresses at the same time? Is there maybe a switch I can flip somewhere in the dashboard (I tried to look for it)?
Thanks — I see you’re reporting an issue (server-side) trying to get both EVM and Solana wallets from a single Web3Auth JWT after .login(). I’ll summarize what you gave, list what I need, explain why this happens, and show recommended approaches.
User-provided behavior: After verifying JWT (jose.jwtVerify) payload.wallets only contains secp256k1 wallets. You tried web3Auth.login({ curve: ‘ed25519’ }) but need both addresses at once.
Why this happens
Web3Auth’s JWT includes wallet entries for the curve you requested at login. If you login with curve: ‘secp256k1’ you get EVM-compatible keys; with curve: ‘ed25519’ you get Solana-compatible keys.
There is no current option or dashboard switch to include both secp256k1 and ed25519 keypairs in a single JWT. You cannot natively obtain both keypairs in a single login/JWT.
Recommended approaches
Two logins (most straightforward)
Client: perform two logins (one per curve) and send both idTokens/JWTs to your server.
Export both keys from the client session (if available)
If your client-side Web3Auth session or provider exposes both keypairs (or can derive both) you can export the public addresses for both chains and send only the addresses or verified tokens to your server. This avoids multiple login prompts if supported by your client flow.
Don’t send raw private keys to the server
For security, avoid sending private keys or storing them server-side. Use JWTs or signed attestations instead.
Notes and cautions
Deriving an ed25519 key from a secp256k1 private key (or vice versa) is not feasible/safe — do not attempt this.
If you need a single-server-side assertion that ties both addresses to the same user, you can have the client sign a challenge with each wallet and send both signatures plus the JWT(s) to the server.
SDK version you’re using and the platform (web / node / mobile)
The client init + login code snippet you’re using (so I can confirm login options)
Optional: the decoded JWT payload (or a sanitized screenshot of payload.wallets) or browser console logs if you’ve already verified the JWT and are still seeing unexpected results
If you want, paste your login/init snippet and SDK version and I’ll point out exact code changes you should make to implement the two-login or export flow.
Note: This response was generated by an AI bot and may require further verification. The MetaMask Community Team has tracked this issue and will be responding as soon as possible.
Additionally, we would recommend you to join our biweekly Office Hours to get this resolved even faster. MetaMask Developer Office Hours
This is now solved. The issue was I had the default RPC URL in under Solana in Web3Auth dashboard. If I changed it to be a proper paid RPC endpoint, it succeeds. Probably web3auth cannot (IP is banned from?) using the default solana RPC. Anyway, now it is OK and I get the solana in the JWT payload!