Good morning.
I’m facing an issue with the grouped connections feature, from the documentation we have that:
Group Connections enable multiple login methods to be linked to the same on-chain user identity. This means that users logging in with different authentication providers (e.g., Google and Email Passwordless) can still access the same wallet address—ensuring a unified user experience.
I have two separated projects, BE that uses the Node SDK and FE that uses the React SDK, I set up the same project in both, I set up the google login like in the documentation and created a Custom JWT following this documentation, and then, grouped those two login methods into one Grouped connection.
When I log in using the google login modal I get 2 wallets, the address for the solana wallet is different to the one I get when I log in to web3auth using the Node SDK and my custom JWT, even tho in token I specifcy to use the correct settings to be able to log in through the group connection.
I just set up the examples for Node and React, with the same configuration and I get two different wallet addresses:
React
// IMP START - Quick Start
import { type Web3AuthContextConfig } from '@web3auth/modal/react'
import { WEB3AUTH_NETWORK } from '@web3auth/base';
import { WALLET_CONNECTORS, type Web3AuthOptions } from '@web3auth/modal'
// IMP END - Quick Start
// IMP START - Dashboard Registration
const clientId = <<MY_CLIENT_ID>>; // get from https://dashboard.web3auth.io
// IMP END - Dashboard Registration
// IMP START - Instantiate SDK
const web3AuthOptions: Web3AuthOptions = {
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_DEVNET,
modalConfig: {
connectors: {
[WALLET_CONNECTORS.AUTH]: {
label: "auth",
loginMethods: {
google: {
name: "Google Login",
authConnectionId: "rampa-w3a-google",
groupedAuthConnectionId: "rampa-w3a-group-connection",
},
},
},
},
},
}
const web3AuthContextConfig: Web3AuthContextConfig = {
web3AuthOptions,
}
// IMP END - Instantiate SDK
export default web3AuthContextConfig;
Node
const jwt = require(‘jsonwebtoken’);
const { LAMPORTS_PER_SOL, Connection, PublicKey } = require(“@solanasolanasolanasolana/web3.js”);
const fs = require(“fs”).promises;
const { createSignableMessage } = req@solanasolanaire(‘@solana/signers’);
// IMP START - Quick Start
const { Web3Auth } = require(“/node-sdk”);
// IMP END - Quick Start
// IMP START - Blockchain Calls
// Get Solana Accounts
const getAccounts = async (signer) => {
try {
const publicKey = signer.address;
console.log(“\x1b[33m%s\x1b[0m”, “Public Key:”, publicKey);
} catch (error) {
console.error(“\x1b[33m%s\x1b[0m”, “Error fetching accounts:”, error);
}
};
// Get Solana Balance
const getBalance = async (signer) => {
try {
const publicKey = new PublicKey(signer.address);
const connection = new Connection(“https://api.devnet.solana.com”);
const balance = await connection.getBalance(publicKey) / LAMPORTS_PER_SOL;
console.log(“\x1b[33m%s\x1b[0m”, “Balance:”, balance, “SOL”);
} catch (error) {
console.error(“\x1b[33m%s\x1b[0m”, “Error fetching balance:”, error);
}
};
// Sign Solana Message
const signMessage = async (signer, message) => {
try {
const messageBytes = new TextEncoder().encode(message);
// Create a SignableMessage object from Uint8Array
const signableMessage = createSignableMessage(messageBytes);
const [signature] = await signer.signMessages([signableMessage]);
console.log(“\x1b[33m%s\x1b[0m”, “Signed Message:”, signature);
} catch (error) {
console.error(“\x1b[33m%s\x1b[0m”, “Error signing message:”, error);
}
};
// IMP END - Blockchain Calls
// Perform JWT Login and MFA Setup
const initAndLogin = async () => {
// IMP START - Dashboard Registration
const clientId = <<MY_CLIENT_ID>>;
// IMP END - Dashboard Registration
// IMP START - Verifier Creation
const authConnectionId = “rampa-w3a-jwt”;
// IMP END - Verifier Creation
// IMP START - SDK Initialization
const web3auth = new Web3Auth({
clientId,
web3AuthNetwork: “sapphire_devnet”,
});
await web3auth.init();
// IMP END - SDK Initialization
// IMP START - Auth Provider Login
const privateKey = await fs.readFile(“privateKey.pem”, “utf8”);
// CORRECTED: Use the correct kid and sub values
var idToken = jwt.sign(
{
sub: ‘stvnbvsts@gmail.com’,
name: ‘Steven Bustos’,
email: ‘stvnbvsts@gmail.com’,
aud: ‘urn:rampa-web3auth’,
iss: ‘ https://auth.rampa.local’,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60 * 60,
},
privateKey,
{ algorithm: ‘RS256’, keyid: ‘key-v1’ } // Match Web3AuthNodeService
);
console.log(“\x1b[33m%s\x1b[0m”, “JWT Token:”, idToken);
// IMP END - Auth Provider Login
// IMP START - Login
const result = await web3auth.connect({
authConnectionId: “rampa-w3a-jwt”,
idToken,
groupedAuthConnectionId: “rampa-w3a-group-connection”, // Match your Google token
isUserIdCaseSensitive: true,
userId: “stvnbvsts@gmail.com”, // Use email
userIdField: “sub”, // Use sub field
});
console.log(“\x1b[33m%s\x1b[0m”, “Login successful. \nConnected Chain Namespace:”, result.chainNamespace);
// IMP START - Blockchain Interaction
await getAccounts(result.signer); // Get Solana Accounts
await getBalance(result.signer); // Get Solana Balance
await signMessage(result.signer, “Hello Web3Auth!”); // Sign a Message
// IMP END - Blockchain Interaction
console.log(“\x1b[33m%s\x1b[0m”, “Blockchain interactions done.”);
};
// Call the initialization and login function
initAndLogin().catch(console.error);
This is my google connection configuration:
This is the custom JWT:
And this is the grouped connection set up:
what I’m missing here? I use the same email / name to log in and it creates different wallet address


