How to retrieve the wallet of a user authenticated via AWS Cognito?

Hello, I’ve setup web3auth + aws cognito by using the “Web3Auth & ReactJS Example using AWS Cognito” example code on my NextJS app. Everything works fine and I’m able to login/authenticate a user.

On the frontend code, I’m able to retrieve the user wallet.

Now, I want to retrieve the user wallet on my backend code, which probably means I need to use the “@web3auth/node-sdk”. I’m not able to retrieve the user wallet on my backend, I get error 403 Unauthorized. Can you please help?

  • SDK Version:
    @web3auth/base”: “^8.4.0”,
    @web3auth/ethereum-provider”: “^8.4.0”,
    @web3auth/no-modal”: “^8.4.0”,
    @web3auth/openlogin-adapter”: “^8.4.0”,
    @web3auth/node-sdk”: “^3.3.0”,

  • Platform: NextJS/NodeJS

Code:

import { Web3Auth } from "@web3auth/node-sdk";
import { CHAIN_NAMESPACES } from "@web3auth/base";
import jwt, { JwtHeader, SigningKeyCallback } from "jsonwebtoken";
import jwksClient, { SigningKey } from "jwks-rsa";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";

const web3authClientId = "<web3auth_client_id>";
const awsCognitoClientId = "<aws_cognito_client_id>";
const w3aVerifier = "<w3a_verifier>";
const cognitoDomain = "<cognito_domain_url>";

const web3auth = new Web3Auth({
	clientId: web3authClientId,
	web3AuthNetwork: "mainnet",
	usePnPKey: false, // Setting this to true returns the same key as PnP Web SDK.
	// By default, this SDK returns CoreKitKey.
});

const chainConfig = {
	chainNamespace: CHAIN_NAMESPACES.EIP155,
	displayName: "ETH Mainnet",
	blockExplorer: "https://etherscan.io",
	ticker: "ETH",
	tickerName: "Ethereum",
	chainId: "0x1",
	rpcTarget: "https://rpc.ankr.com/eth", // needed for non-other chains
};

const provider = new EthereumPrivateKeyProvider({ config: { chainConfig } });

web3auth.init({ provider });

const client = jwksClient({
	jwksUri:
		"https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_gkn7r52OP/.well-known/jwks.json",
});

function getKey(header: JwtHeader, callback: SigningKeyCallback): void {
	client.getSigningKey(
		header.kid as string,
		(err: Error | null, key: SigningKey | undefined) => {
			const signingKey = key?.getPublicKey();
			callback(null, signingKey);
		}
	);
}

const verifyJWT = (token: string): Promise<any> => {
	return new Promise((resolve, reject) => {
		jwt.verify(token, getKey, { algorithms: ["RS256"] }, (err, decoded) => {
			if (err) {
				return reject("Invalid token");
			}
			resolve(decoded);
		});
	});
};

const getToken = async (idToken: string): Promise<void> => {
	try {
		// Fetch wallet address using Web3Auth
		const walletProvider = await web3auth.connect({
			verifier: w3aVerifier,
			verifierId: "1314b8b2-20a1-7034-68fc-dab6ee931e03",
			idToken,
		});

		// Proceed with the logic to create a checkout session using the wallet address
		console.log("Wallet Address:");
		// ...
	} catch (error) {
		console.error("Error getting token:", error);
	}
};

// Example usage
const exampleUsage = async () => {
	const idToken =
		"eyJraWQiOiJTckp3cWtWT1R1Y29qQzlZWG9rRmY4NG5mN3BGbnp0V1NieGpIWHF2SGlvPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxMzE0YjhiMi0yMGExLTcwMzQtNjhmYy1kYWI2ZWU5MzFlMDMiLCJjb2duaXRvOmdyb3VwcyI6WyJldS1jZW50cmFsLTFfZ2tuN3I1Mk9QX0dvb2dsZSJdLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAuZXUtY2VudHJhbC0xLmFtYXpvbmF3cy5jb21cL2V1LWNlbnRyYWwtMV9na243cjUyT1AiLCJ2ZXJzaW9uIjoyLCJjbGllbnRfaWQiOiI0dnRwajYyc3Z0YW1uZms2Z3FjOW50cTE2bCIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJhdXRoX3RpbWUiOjE3MTYzNzAyMzcsImV4cCI6MTcxNjM3MzgzNywiaWF0IjoxNzE2MzcwMjM3LCJqdGkiOiIzOWYwOWE4ZS03Yjc4LTQ1MWMtOWU3NS1hMjY3MjMyOTBiMWEiLCJ1c2VybmFtZSI6Ikdvb2dsZV8xMTI2MzEyMTcyODk2NjE2ODgzNDcifQ.GHCWGZ1U88W5h7ztPzUUIgYa19_v8SeSAxQ8BYFRt7MtxrIfei9pqgHZZKmpZH8p_JJWTMbsqBANsB7IRBKOqW4FIJ7VOH5iOyQ4dQC1lcjvx8zoP0EGMP26GZXWW1mWgN9p5OJPTrzrilD90aCTw4pBKAsvTFS9oZ6l1DFtsyKn9_xE1wS8lPjUDRXUfynVt5yfmhx3-qkTT4poixDWyJA1gs1Pyki5l7mFiC93Z1BL1DZREs4SurhVSghuzKPwwbHWQ-2utRmnYMZFyq_pADY7De7l60HcqCkqdtMk1iZPhmbXlLgnDChALH9ei9Kx3PEXN9Z2XmKXhcGai8iUcw";
	try {
		const decodedToken = await verifyJWT(idToken);
		console.log("Decoded Token:", decodedToken);
		await getToken(idToken);
	} catch (error) {
		console.error("Error:", error);
	}
};

exampleUsage();

hi @luca,

Please check this example: web3auth-core-kit-examples/single-factor-auth-node/sfa-node-quick-start/index.js at 4f5756aefaf6765a9c8db9cb984f3d29d9ad9a27 · Web3Auth/web3auth-core-kit-examples · GitHub

const provider = await web3auth.connect({
    verifier: "w3a-node-demo", // replace with your verifier name
    verifierId: sub, // replace with your verifier id's value, for example, sub value of JWT Token, or email address.
    idToken: token, 
  });
  const eth_private_key = await provider.request({ method: "eth_private_key" });

Hi @TomTom when I run this code, I get the error “Duplicate token found”.
I’ve used a fresh new user to test this, so I’m sure there is not more than 1 token for that user.
Any suggestion on how to fix this error?

Also, in the example code you provided, do I need to modify it to include information about AWS cognito?

Hi Luca,

I’ve shared this problem with the team so they can assist us in solving it.

thanks for your patience

Hey @luca,

I noticed that you are hardcoding the idToken. Could you try obtaining a fresh one using Cognito and testing it again? Sometimes, when we hardcode tokens, we might forget to use a new one, which often leads to errors.