Open bmwolf opened 1 month ago
Hey @bmwolf, thank you for raising this one! As far as I see from this issue, it's also reproducible on Testnet. Would it be possible for you to send us Testnet Private Keys, which are not recovering properly so we can investigate further? I will attempt to reproduce this one in the meantime 👍
Hi @bmwolf and thank you for raising this. Can you please provide a step by step example or may a snippet how to reproduce this so we can start investigating?
@Petyo-Lukanov @agadzhalov Hey, sorry for the delayed response. I am trying to find a testnet account that has the issue but unfortunately most of them have been wiped from the quarterly purge. I am going through the account info that my coworkers have used for testing. As soon as I find one Ill post it here. I apologize I can't be of more help.
@Petyo-Lukanov @agadzhalov Sorry for the delay, it looks like if an account was previously created from a 12 word mnemonic phrase with toEd25519PrivateKey() that is what is causing an issue recovering. Here is the testnet account info.
Seed Phrase: flower camera awkward coil father lava hair course switch adult symptom evidence
Private Key: 302e020100300506032b6570042204208dd10cfec6fddfef379f2b6e34838d2e7aabe2ebc32e7dcadbba47d86da75e02
Hello @bmwolf I looked at your issue, reproduced it in a local environment using this snippet:
import {
AccountId,
PrivateKey,
Mnemonic,
} from "@hashgraph/sdk";
import * as dotenv from "dotenv";
dotenv.config();
async function htsContractFunction() {
const OPERATOR_ID = AccountId.fromString(process.env.OPERATOR_ID);
const OPERATOR_KEY = PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY);
const words = [
"flower",
"camera",
"awkward",
"coil",
"father",
"lava",
"hair",
"course",
"switch",
"adult",
"symptom",
"evidence",
];
const words2 = [
"finish",
"science",
"attend",
"acquire",
"until",
"derive",
"elephant",
"harsh",
"tool",
"bracket",
"move",
"shrimp",
];
const mnemonic = await Mnemonic.fromWords(words);
const privKey = await mnemonic.toStandardEd25519PrivateKey();
console.log("Private key from mnemonic", privKey.toStringDer());
const privKeyDirect = PrivateKey.fromStringED25519(
"302e020100300506032b6570042204208dd10cfec6fddfef379f2b6e34838d2e7aabe2ebc32e7dcadbba47d86da75e02"
);
console.log("Direct private key", privKeyDirect);
console.log("Direct public key", privKeyDirect.publicKey.toStringDer());
const privKeyNon = await mnemonic.toEd25519PrivateKey();
console.log("private key from mnemonic deprecated", privKeyNon.toStringDer());
}
void htsContractFunction();
I got the same result as you said -> didn't get the expected private key - 302e020100300506032b6570042204208dd10cfec6fddfef379f2b6e34838d2e7aabe2ebc32e7dcadbba47d86da75e02
but actually got 302e020100300506032b65700422042013b263718a331e955d7c2cda5c7c3c611ca4a5c99971ac2606600e102fae5c8f
.
I asked some colleagues that worked on the depreciation of .toEd25519PrivateKey
. So what they told me is this behaviour is expected. The problem is that the former implementation was wrong and it created a lot of issues. You can take a look at the issues we addressed by checking out this PR- https://github.com/hashgraph/hedera-sdk-js/pull/1550
The right way of getting the ED25519 private key from a mnemonic now is using toStandardEd25519PrivateKey
function.
If you really want to use this PrivateKey 302e020100300506032b6570042204208dd10cfec6fddfef379f2b6e34838d2e7aabe2ebc32e7dcadbba47d86da75e02
you can always use PrivateKey.fromStringED25519
. If you can tell me more about your problem I'd be glad to help. Any additional info that can help me with your issue would be appreciated! We can also book a call in a Google meeting if you think that would be faster way of resolving your issue.
So I did a little more research because I wanted to make sure that toStandardEd25519PrivateKey
behaves as expected.
I wrote this code snippet:
import {
Client,
AccountId,
PrivateKey,
Logger,
LogLevel,
Mnemonic,
} from "@hashgraph/sdk";
import * as dotenv from "dotenv";
dotenv.config();
async function htsContractFunction() {
const OPERATOR_ID = AccountId.fromString(process.env.OPERATOR_ID);
const OPERATOR_KEY = PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY);
const words = [
"flower",
"camera",
"awkward",
"coil",
"father",
"lava",
"hair",
"course",
"switch",
"adult",
"symptom",
"evidence",
];
const mnemonic = await Mnemonic.fromWords(words);
const ed25519PrivKey = await mnemonic.toStandardEd25519PrivateKey();
const privKeyCapitalCase = ed25519PrivKey.toStringRaw().toUpperCase();
console.log("Capital case of private key", privKeyCapitalCase);
console.log(
"Public key",
ed25519PrivKey.publicKey.toStringRaw().toUpperCase()
);
//const depricatedPrivatekey = await mnemonic.toEd25519PrivateKey();
//const privKey = await mnemonic.toStandardEd25519PrivateKey();
/*console.log("Private key from mnemonic", privKey.toStringDer());
console.log("Private key from mnemonic raw", privKey.toStringRaw());
console.log(privKey._key);
console.log("public key from mnemonic", privKey.publicKey.toStringRaw());
*/
/*
const privKeyDirect = PrivateKey.fromStringED25519(
"302e020100300506032b6570042204208dd10cfec6fddfef379f2b6e34838d2e7aabe2ebc32e7dcadbba47d86da75e02"
);
console.log("Direct private key", privKeyDirect);
console.log("Direct public key", privKeyDirect.publicKey.toStringDer());
const privKeyNon = await mnemonic.toEd25519PrivateKey();
console.log("private key from mnemonic deprecated", privKeyNon.toStringDer());
*/
}
void htsContractFunction();
It gives you a private key and a public key using the mnemonics. If you copy and paste the code snippet into this website:
https://cyphr.me/ed25519_tool/ed.html - You can confirm that the correct public key is derived from the private key.
And this is the output of the code snippet I gave you.
As you can see they are the same.
Description
Some Ed2551 encoded private keys seem like they can't be recovered using the
.toStandardEd2551PrivateKey()
method.I am able to recover using
.toEd25519PrivateKey()
but that function is now deprecated and can be removed at any time. I am assuming.toStandardEd2551PrivateKey
was supposed to fully replace.toEd25519PrivateKey()
and that is why I think there may be an issue.Steps to reproduce
Im not sure how to give steps to reproduce without giving account information
Additional context
None
Hedera network
mainnet, testnet
Version
v2.48.1
Operating system
macOS