Is there a way to import a private key to the web3auth nodes (using a custom verifier) so that it can be retrieved later on by the SFA SDK?
The use case is to seamlessly migrate users between verifiers. The idea is to have a dedicated “migration” web app where the user would first log in through the old (default) verifier, the app retrieves the private key. Subsequently, the user would log in through the new (custom) verifier and the app would initialize the account with the private key from the old verifier, ensuring the user would get the same private/key accounts they had when they logged in the “old” way.
The key initialization described in Using Web3Auth Core Kit tKey SDK in a React Application | Web3Auth seems to cover only the “1/2” flow, but for SFA I believe we would somehow need to initialize the key for a “1/1” flow for which I didn’t find any example so far
I dug deeper and it seems that the key can indeed be imported with the imporPrivateKey() call using solely web3auth SFA SDK, the catch is that the key will be correctly imported (i.e. same key returned) only on non-legacy networks/v2 users (not sure exactly why, but found branching related to legacy networks/v1 users so I guess it’s related to that):
import { TORUS_SAPPHIRE_NETWORK, Web3Auth } from "@web3auth/single-factor-auth";
const web3authSfa = new Web3Auth({
clientId, // Get your Client ID from Web3Auth Dashboard
web3AuthNetwork: TORUS_SAPPHIRE_NETWORK.SAPPHIRE_MAINNET,
});
const verifier = "w3a-google-demo";
const idToken = response.credential; // google OAuth token after logging into google
const { email } = parseToken(idToken);
const verifierDetails = {
verifier,
verifierId: email,
};
let finalVerifierParams = { verifier_id: email };
let finalIdToken = idToken!;
const newPrivateKey = "<IMPORTED PRIVATE KEY HEX>";
const { torusNodeEndpoints, torusNodePub, torusIndexes } = await web3authSfa.nodeDetailManagerInstance!.getNodeDetails(verifierDetails);
const res = await web3authSfa.authInstance?.importPrivateKey(
torusNodeEndpoints,
torusIndexes,
torusNodePub,
verifier,
finalVerifierParams,
finalIdToken,
newPrivateKey
);
// yay! it's the same as newPrivateKey
console.log("stored private key", res?.finalKeyData.privKey);
I think that’s the solution to my question, though I would welcome any advice/feedback on the security/usability (supposing we implement the usecase described in the question) of this solution and perhaps whether there isn’t some more straightforward way.
@rafael.korbas this use case is interesting. May I ask what happens to the old verifier? do you invalidate the key there so it cannot be used anymore? in that case, can you show how?
I don’t further touch the key in the old verifier, it just stays there. My intent is to just ensure the user gets the same private key on the new verifier as they did on the old one. The key is reconstructible anyway only for the user that would need to authenticate against this old verifier which sounds good to me.
Do you see any specific reason to “invalidate” the key in the old verifier? Bear in mind that the “old” verifier in my case is the default verifier and wiping the key (even if theoretically possible) would impact also any other projects relying on the default verifier, and I’d say that’s not desired.
In case of a shared verifier, like the default verifier, I agree, it’s not ok to touch the user key. I’m working in a different scenario, where we want to migrate an account from SFA, to MFA. So far, I’ve been able to import the key with MFA, but the verifierId in the SFA SDK continues to work. I’m looking for a way to invalidate it son only a multi-factor authentication can retrieve the key once migrated.